diff --git a/README.md b/README.md index aaf0840f72..fbbc23eb68 100644 --- a/README.md +++ b/README.md @@ -15,9 +15,9 @@ Build Kubernetes Operators in Java without hassle. Inspired by [operator-sdk](ht #### Features * Framework for handling Kubernetes API events -* Registering Custom Resource watches +* Automatic registration of Custom Resource watches * Retry action on failure -* Smart event scheduling (only handle latest event for the same resource) +* Smart event scheduling (only handle the latest event for the same resource) Check out this [blog post](https://blog.container-solutions.com/a-deep-dive-into-the-java-operator-sdk) about the non-trivial yet common problems needed to be solved for every operator. @@ -44,6 +44,37 @@ about the non-trivial yet common problems needed to be solved for every operator You can (will) find detailed documentation [here](docs/DOCS.md). Note that these docs are currently in progress. +> :warning: 1.7.0 Upgrade +> The 1.7.0 upgrade comes with big changes due to the update to the 5.0.0 version of the fabric8 +> Kubernetes client. While this should improve the user experience quite nicely, there are a couple +> of things to be aware of when upgrading from a previous version as detailed below. + +##### Overview of the 1.7.0 changes + +- `Doneable` classes have been removed along with all the involved complexity +- `Controller` annotation has been simplified: the `crdName` field has been removed as that value is + computed from the associated custom resource implementation +- Custom Resource implementation classes now need to be annotated with `Group` and `Version` + annotations so that they can be identified properly. Optionally, they can also be annotated with + `Kind` (if the name of the implementation class doesn't match the desired kind) and `Plural` if + the plural version cannot be automatically computed (or the default computed version doesn't match + your expectations). +- The `CustomResource` class that needs to be extended is now parameterized with spec and status + types, so you can have an empty default implementation that does what you'd expect. If you don't + need a status, using `Void` for the associated type should work. +- Custom Resources that are namespace-scoped need to implement the `Namespaced` interface so that + the client can generate the proper URLs. This means, in particular, that `CustomResource` + implementations that do **not** implement `Namespaced` are considered cluster-scoped. As a + consequence, the `isClusterScoped` method/field has been removed from the appropriate + classes (`Controller` annotation, in particular) as this is now inferred from the `CustomResource` + type associated with your `Controller`. + +Many of these changes might not be immediately apparent but will result in `404` errors when +connecting to the cluster. Please check that the Custom Resource implementations are properly +annotated and that the value corresponds to your CRD manifest. If the namespace appear to be missing +in your request URL, don't forget that namespace-scoped Custom Resources need to implement +the `Namescaped` interface. + #### Usage We have several sample Operators under the [samples](samples) directory: @@ -52,6 +83,7 @@ Implemented with and without Spring Boot support. The two samples share the comm * *webserver*: More realistic example creating an nginx webserver from a Custom Resource containing html code. * *mysql-schema*: Operator managing schemas in a MySQL database * *spring-boot-plain/auto-config*: Samples showing integration with Spring Boot. +* *quarkus*: Minimal application showing automatic configuration / injection of Operator / Controllers. Add [dependency](https://search.maven.org/search?q=a:operator-framework) to your project with Maven: @@ -89,7 +121,7 @@ public class Runner { The Controller implements the business logic and describes all the classes needed to handle the CRD. ```java -@Controller(crdName = "webservers.sample.javaoperatorsdk") +@Controller public class WebServerController implements ResourceController { @Override @@ -110,28 +142,9 @@ public class WebServerController implements ResourceController { A sample custom resource POJO representation ```java -public class WebServer extends CustomResource { - - private WebServerSpec spec; - - private WebServerStatus status; - - public WebServerSpec getSpec() { - return spec; - } - - public void setSpec(WebServerSpec spec) { - this.spec = spec; - } - - public WebServerStatus getStatus() { - return status; - } - - public void setStatus(WebServerStatus status) { - this.status = status; - } -} +@Group("sample.javaoperatorsdk") +@Version("v1") +public class WebServer extends CustomResource implements Namespaced {} public class WebServerSpec { @@ -183,7 +196,6 @@ public class QuarkusOperator implements QuarkusApplication { public int run(String... args) throws Exception { final var config = configuration.getConfigurationFor(new CustomServiceController(client)); System.out.println("CR class: " + config.getCustomResourceClass()); - System.out.println("Doneable class = " + config.getDoneableClass()); Quarkus.waitForExit(); return 0; diff --git a/operator-framework-core/pom.xml b/operator-framework-core/pom.xml index 4ac1966006..f4f2664459 100644 --- a/operator-framework-core/pom.xml +++ b/operator-framework-core/pom.xml @@ -6,7 +6,7 @@ io.javaoperatorsdk java-operator-sdk - 1.6.4-SNAPSHOT + 1.7.0-SNAPSHOT ../pom.xml 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 ebec85bcda..b857ddb710 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 @@ -1,14 +1,8 @@ package io.javaoperatorsdk.operator; -import io.fabric8.kubernetes.api.model.apiextensions.v1beta1.CustomResourceDefinition; import io.fabric8.kubernetes.client.CustomResource; -import io.fabric8.kubernetes.client.CustomResourceDoneable; -import io.fabric8.kubernetes.client.CustomResourceList; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.dsl.MixedOperation; -import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext; -import io.fabric8.kubernetes.client.dsl.internal.CustomResourceOperationsImpl; -import io.fabric8.kubernetes.internal.KubernetesDeserializer; import io.javaoperatorsdk.operator.api.ResourceController; import io.javaoperatorsdk.operator.api.config.ConfigurationService; import io.javaoperatorsdk.operator.processing.CustomResourceCache; @@ -19,8 +13,6 @@ import io.javaoperatorsdk.operator.processing.retry.GenericRetry; import io.javaoperatorsdk.operator.processing.retry.Retry; import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,8 +22,6 @@ public class Operator { private static final Logger log = LoggerFactory.getLogger(Operator.class); private final KubernetesClient k8sClient; private final ConfigurationService configurationService; - private Map, CustomResourceOperationsImpl> customResourceClients = - new HashMap<>(); public Operator(KubernetesClient k8sClient, ConfigurationService configurationService) { this.k8sClient = k8sClient; @@ -41,9 +31,18 @@ public Operator(KubernetesClient k8sClient, ConfigurationService configurationSe public void register(ResourceController controller) throws OperatorException { final var configuration = configurationService.getConfigurationFor(controller); - final var retry = GenericRetry.fromConfiguration(configuration.getRetryConfiguration()); - final var targetNamespaces = configuration.getNamespaces().toArray(new String[] {}); - registerController(controller, configuration.watchAllNamespaces(), retry, targetNamespaces); + if (configuration == null) { + log.warn( + "Skipping registration of {} controller named {} because its configuration cannot be found.\n" + + "Known controllers are: {}", + controller.getClass().getCanonicalName(), + ControllerUtils.getNameFor(controller), + configurationService.getKnownControllerNames()); + } else { + final var retry = GenericRetry.fromConfiguration(configuration.getRetryConfiguration()); + final var targetNamespaces = configuration.getNamespaces().toArray(new String[] {}); + registerController(controller, configuration.watchAllNamespaces(), retry, targetNamespaces); + } } public void registerControllerForAllNamespaces( @@ -76,12 +75,8 @@ private void registerController( throws OperatorException { final var configuration = configurationService.getConfigurationFor(controller); Class resClass = configuration.getCustomResourceClass(); - CustomResourceDefinitionContext crd = getCustomResourceDefinitionForController(controller); - KubernetesDeserializer.registerCustomKind(crd.getVersion(), crd.getKind(), resClass); String finalizer = configuration.getFinalizer(); - MixedOperation client = - k8sClient.customResources( - crd, resClass, CustomResourceList.class, configuration.getDoneableClass()); + MixedOperation client = k8sClient.customResources(resClass); EventDispatcher eventDispatcher = new EventDispatcher( controller, finalizer, new EventDispatcher.CustomResourceFacade(client)); @@ -95,8 +90,6 @@ private void registerController( defaultEventHandler.setEventSourceManager(eventSourceManager); eventDispatcher.setEventSourceManager(eventSourceManager); - customResourceClients.put(resClass, (CustomResourceOperationsImpl) client); - controller.init(eventSourceManager); CustomResourceEventSource customResourceEventSource = createCustomResourceEventSource( @@ -137,30 +130,4 @@ private CustomResourceEventSource createCustomResourceEventSource( return customResourceEventSource; } - - private CustomResourceDefinitionContext getCustomResourceDefinitionForController( - ResourceController controller) { - final var crdName = configurationService.getConfigurationFor(controller).getCRDName(); - CustomResourceDefinition customResourceDefinition = - k8sClient.customResourceDefinitions().withName(crdName).get(); - if (customResourceDefinition == null) { - throw new OperatorException("Cannot find Custom Resource Definition with name: " + crdName); - } - CustomResourceDefinitionContext context = - CustomResourceDefinitionContext.fromCrd(customResourceDefinition); - return context; - } - - public Map, CustomResourceOperationsImpl> - getCustomResourceClients() { - return customResourceClients; - } - - public < - T extends CustomResource, - L extends CustomResourceList, - D extends CustomResourceDoneable> - CustomResourceOperationsImpl getCustomResourceClients(Class customResourceClass) { - return customResourceClients.get(customResourceClass); - } } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/Controller.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/Controller.java index 5f4f00a635..d3ca3dd05b 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/Controller.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/Controller.java @@ -11,8 +11,6 @@ String NULL = ""; - String crdName(); - String name() default NULL; /** @@ -28,7 +26,15 @@ */ boolean generationAwareEventProcessing() default true; - boolean isClusterScoped() default false; - + /** + * Specified which namespaces this Controller monitors for custom resources events. If no + * namespace is specified then the controller will monitor the namespace it is deployed in (or the + * namespace to which the Kubernetes client is connected to). To specify that the controller needs + * to monitor all namespaces, add {@link + * io.javaoperatorsdk.operator.api.config.ControllerConfiguration#WATCH_ALL_NAMESPACES_MARKER} to + * this field. + * + * @return the list of namespaces this controller monitors + */ String[] namespaces() default {}; } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AbstractConfigurationService.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AbstractConfigurationService.java index e3ad35188c..8d0ccb34e4 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AbstractConfigurationService.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/AbstractConfigurationService.java @@ -4,6 +4,7 @@ import io.javaoperatorsdk.operator.ControllerUtils; import io.javaoperatorsdk.operator.api.ResourceController; import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; public abstract class AbstractConfigurationService implements ConfigurationService { @@ -35,4 +36,9 @@ public ControllerConfiguration getConfigurationFor ResourceController controller) { return configurations.get(ControllerUtils.getNameFor(controller)); } + + @Override + public Set getKnownControllerNames() { + return configurations.keySet(); + } } 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 93b713e89e..952b1c1838 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 io.fabric8.kubernetes.client.Config; import io.fabric8.kubernetes.client.CustomResource; import io.javaoperatorsdk.operator.api.ResourceController; +import java.util.Set; public interface ConfigurationService { @@ -12,4 +13,6 @@ ControllerConfiguration getConfigurationFor( default Config getClientConfiguration() { return Config.autoConfigure(null); } + + Set getKnownControllerNames(); } 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 7960f2b212..f6bde0df82 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 @@ -1,7 +1,6 @@ package io.javaoperatorsdk.operator.api.config; import io.fabric8.kubernetes.client.CustomResource; -import io.fabric8.kubernetes.client.CustomResourceDoneable; import java.util.Collections; import java.util.Set; @@ -19,14 +18,8 @@ public interface ControllerConfiguration { Class getCustomResourceClass(); - Class> getDoneableClass(); - String getAssociatedControllerClassName(); - default boolean isClusterScoped() { - return false; - } - default Set getNamespaces() { return Collections.emptySet(); } 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 1193005769..9e951e26c2 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 @@ -191,10 +191,9 @@ private void addFinalizerIfNotPresent(CustomResource resource) { // created to support unit testing public static class CustomResourceFacade { - private final MixedOperation> resourceOperation; + private final MixedOperation> resourceOperation; - public CustomResourceFacade( - MixedOperation> resourceOperation) { + public CustomResourceFacade(MixedOperation> resourceOperation) { this.resourceOperation = resourceOperation; } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/internal/CustomResourceEventSource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/internal/CustomResourceEventSource.java index 503ff16972..c8d13a4d4b 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/internal/CustomResourceEventSource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/internal/CustomResourceEventSource.java @@ -3,11 +3,10 @@ import static io.javaoperatorsdk.operator.processing.KubernetesResourceUtils.getUID; import static io.javaoperatorsdk.operator.processing.KubernetesResourceUtils.getVersion; import static io.javaoperatorsdk.operator.processing.KubernetesResourceUtils.markedForDeletion; -import static java.net.HttpURLConnection.HTTP_GONE; import io.fabric8.kubernetes.client.CustomResource; -import io.fabric8.kubernetes.client.KubernetesClientException; import io.fabric8.kubernetes.client.Watcher; +import io.fabric8.kubernetes.client.WatcherException; import io.fabric8.kubernetes.client.dsl.MixedOperation; import io.fabric8.kubernetes.client.dsl.internal.CustomResourceOperationsImpl; import io.javaoperatorsdk.operator.ControllerUtils; @@ -151,11 +150,11 @@ public void eventSourceDeRegisteredForResource(String customResourceUid) { } @Override - public void onClose(KubernetesClientException e) { + public void onClose(WatcherException e) { if (e == null) { return; } - if (e.getCode() == HTTP_GONE) { + if (e.isHttpGone()) { log.warn("Received error for watch, will try to reconnect.", e); registerWatch(); } else { diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomResource.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomResource.java index dd6ed3ab86..2469c02c1e 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomResource.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomResource.java @@ -1,38 +1,10 @@ package io.javaoperatorsdk.operator.sample.simple; import io.fabric8.kubernetes.client.CustomResource; +import io.fabric8.kubernetes.model.annotation.Group; +import io.fabric8.kubernetes.model.annotation.Version; -public class TestCustomResource extends CustomResource { - - private TestCustomResourceSpec spec; - - private TestCustomResourceStatus status; - - public TestCustomResourceSpec getSpec() { - return spec; - } - - public void setSpec(TestCustomResourceSpec spec) { - this.spec = spec; - } - - public TestCustomResourceStatus getStatus() { - return status; - } - - public void setStatus(TestCustomResourceStatus status) { - this.status = status; - } - - @Override - public String toString() { - return "TestCustomResource{" - + "spec=" - + spec - + ", status=" - + status - + ", extendedFrom=" - + super.toString() - + '}'; - } -} +@Group("sample.javaoperatorsdk.io") +@Version("v1") +public class TestCustomResource + extends CustomResource {} diff --git a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomResourceController.java b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomResourceController.java index 857fc45b8e..ebcc8c7dd7 100644 --- a/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomResourceController.java +++ b/operator-framework-core/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomResourceController.java @@ -3,6 +3,7 @@ import io.fabric8.kubernetes.api.model.ConfigMap; import io.fabric8.kubernetes.api.model.ConfigMapBuilder; import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; +import io.fabric8.kubernetes.client.CustomResource; import io.fabric8.kubernetes.client.KubernetesClient; import io.javaoperatorsdk.operator.api.Context; import io.javaoperatorsdk.operator.api.Controller; @@ -14,12 +15,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@Controller(generationAwareEventProcessing = false, crdName = TestCustomResourceController.CRD_NAME) +@Controller(generationAwareEventProcessing = false) public class TestCustomResourceController implements ResourceController { private static final Logger log = LoggerFactory.getLogger(TestCustomResourceController.class); - public static final String CRD_NAME = "customservices.sample.javaoperatorsdk"; + public static final String CRD_NAME = CustomResource.getCRDName(TestCustomResource.class); public static final String FINALIZER_NAME = CRD_NAME + "/finalizer"; private final KubernetesClient kubernetesClient; diff --git a/operator-framework-quarkus-extension/deployment/pom.xml b/operator-framework-quarkus-extension/deployment/pom.xml index 25f7fda9b8..b7a6cdb232 100644 --- a/operator-framework-quarkus-extension/deployment/pom.xml +++ b/operator-framework-quarkus-extension/deployment/pom.xml @@ -6,7 +6,7 @@ io.javaoperatorsdk operator-framework-quarkus-extension-parent - 1.6.4-SNAPSHOT + 1.7.0-SNAPSHOT ../pom.xml diff --git a/operator-framework-quarkus-extension/deployment/src/main/java/io/javaoperatorsdk/quarkus/extension/deployment/QuarkusExtensionProcessor.java b/operator-framework-quarkus-extension/deployment/src/main/java/io/javaoperatorsdk/quarkus/extension/deployment/QuarkusExtensionProcessor.java index 094c0b8a90..02082de02e 100644 --- a/operator-framework-quarkus-extension/deployment/src/main/java/io/javaoperatorsdk/quarkus/extension/deployment/QuarkusExtensionProcessor.java +++ b/operator-framework-quarkus-extension/deployment/src/main/java/io/javaoperatorsdk/quarkus/extension/deployment/QuarkusExtensionProcessor.java @@ -1,7 +1,6 @@ package io.javaoperatorsdk.quarkus.extension.deployment; import io.fabric8.kubernetes.client.CustomResource; -import io.fabric8.kubernetes.client.CustomResourceDoneable; import io.javaoperatorsdk.operator.ControllerUtils; import io.javaoperatorsdk.operator.api.Controller; import io.javaoperatorsdk.operator.api.ResourceController; @@ -13,51 +12,48 @@ import io.javaoperatorsdk.quarkus.extension.QuarkusControllerConfiguration; import io.quarkus.arc.deployment.AdditionalBeanBuildItem; import io.quarkus.arc.deployment.SyntheticBeanBuildItem; -import io.quarkus.deployment.GeneratedClassGizmoAdaptor; import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.annotations.ExecutionTime; import io.quarkus.deployment.annotations.Record; import io.quarkus.deployment.builditem.CombinedIndexBuildItem; import io.quarkus.deployment.builditem.FeatureBuildItem; -import io.quarkus.deployment.builditem.GeneratedClassBuildItem; import io.quarkus.deployment.builditem.IndexDependencyBuildItem; import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; -import io.quarkus.gizmo.ClassCreator; -import io.quarkus.gizmo.ClassOutput; -import io.quarkus.gizmo.MethodCreator; -import io.quarkus.gizmo.MethodDescriptor; -import java.lang.reflect.Modifier; import java.util.List; import java.util.Optional; import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Collectors; +import javax.enterprise.context.ApplicationScoped; import javax.inject.Singleton; import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.AnnotationValue; import org.jboss.jandex.ClassInfo; import org.jboss.jandex.DotName; import org.jboss.jandex.Type; +import org.jboss.logging.Logger; class QuarkusExtensionProcessor { + private static final Logger log = Logger.getLogger(QuarkusExtensionProcessor.class.getName()); + private static final String FEATURE = "operator-sdk"; private static final DotName RESOURCE_CONTROLLER = DotName.createSimple(ResourceController.class.getName()); private static final DotName CONTROLLER = DotName.createSimple(Controller.class.getName()); + private static final DotName APPLICATION_SCOPED = + DotName.createSimple(ApplicationScoped.class.getName()); private static final Supplier EXCEPTION_SUPPLIER = () -> { throw new IllegalArgumentException(); }; @BuildStep - FeatureBuildItem feature() { - return new FeatureBuildItem(FEATURE); - } - - @BuildStep - void indexSDKDependencies(BuildProducer indexDependency) { + void indexSDKDependencies( + BuildProducer indexDependency, + BuildProducer features) { + features.produce(new FeatureBuildItem(FEATURE)); indexDependency.produce( new IndexDependencyBuildItem("io.javaoperatorsdk", "operator-framework-core")); } @@ -66,7 +62,6 @@ void indexSDKDependencies(BuildProducer indexDependenc @Record(ExecutionTime.STATIC_INIT) void createConfigurationServiceAndOperator( CombinedIndexBuildItem combinedIndexBuildItem, - BuildProducer generatedClass, BuildProducer syntheticBeanBuildItemBuildProducer, BuildProducer additionalBeans, BuildProducer reflectionClasses, @@ -74,13 +69,9 @@ void createConfigurationServiceAndOperator( final var index = combinedIndexBuildItem.getIndex(); final var resourceControllers = index.getAllKnownImplementors(RESOURCE_CONTROLLER); - final var classOutput = new GeneratedClassGizmoAdaptor(generatedClass, true); final List controllerConfigs = resourceControllers.stream() - .map( - ci -> - createControllerConfiguration( - ci, classOutput, additionalBeans, reflectionClasses)) + .map(ci -> createControllerConfiguration(ci, additionalBeans, reflectionClasses)) .collect(Collectors.toList()); final var supplier = recorder.configurationServiceSupplier(controllerConfigs); @@ -97,7 +88,6 @@ void createConfigurationServiceAndOperator( private ControllerConfiguration createControllerConfiguration( ClassInfo info, - ClassOutput classOutput, BuildProducer additionalBeans, BuildProducer reflectionClasses) { // first retrieve the custom resource class @@ -113,41 +103,19 @@ private ControllerConfiguration createControllerConfiguration( // create ResourceController bean final var resourceControllerClassName = info.name().toString(); - additionalBeans.produce(AdditionalBeanBuildItem.unremovableOf(resourceControllerClassName)); - - // generate associated Doneable class - final var doneableClassName = crType + "Doneable"; - final var crDoneableClassName = CustomResourceDoneable.class.getName(); - try (ClassCreator cc = - ClassCreator.builder() - .signature( - String.format( - "Lio/fabric8/kubernetes/client/CustomResourceDoneable;", - crType.replace('.', '/'))) - .classOutput(classOutput) - .className(doneableClassName) - .superClass(crDoneableClassName) - .build()) { - - final var functionName = io.fabric8.kubernetes.api.builder.Function.class.getName(); - MethodCreator ctor = - cc.getMethodCreator("", void.class.getName(), crType, functionName); - ctor.setModifiers(Modifier.PUBLIC); - ctor.invokeSpecialMethod( - MethodDescriptor.ofConstructor( - crDoneableClassName, CustomResource.class.getName(), functionName), - ctor.getThis(), - ctor.getMethodParam(0), - ctor.getMethodParam(1)); - ctor.returnValue(null); - } + additionalBeans.produce( + AdditionalBeanBuildItem.builder() + .addBeanClass(resourceControllerClassName) + .setUnremovable() + .setDefaultScope(APPLICATION_SCOPED) + .build()); // generate configuration final var controllerAnnotation = info.classAnnotation(CONTROLLER); if (controllerAnnotation == null) { throw new IllegalArgumentException( resourceControllerClassName - + " is missing the " + + " is missing the @" + Controller.class.getCanonicalName() + " annotation"); } @@ -155,23 +123,32 @@ private ControllerConfiguration createControllerConfiguration( // load CR class final Class crClass = (Class) loadClass(crType); + // Instantiate CR to check that it's properly annotated + final CustomResource cr; + try { + cr = crClass.getConstructor().newInstance(); + } catch (Exception e) { + throw new IllegalArgumentException(e.getCause()); + } + + // retrieve CRD name from CR type + final var crdName = CustomResource.getCRDName(crClass); + // register CR class for introspection reflectionClasses.produce(new ReflectiveClassBuildItem(true, true, crClass)); - final var crdName = + final var name = valueOrDefault( - controllerAnnotation, "crdName", AnnotationValue::asString, EXCEPTION_SUPPLIER); + controllerAnnotation, + "name", + AnnotationValue::asString, + () -> ControllerUtils.getDefaultResourceControllerName(resourceControllerClassName)); // create the configuration final var configuration = new QuarkusControllerConfiguration( resourceControllerClassName, - valueOrDefault( - controllerAnnotation, - "name", - AnnotationValue::asString, - () -> - ControllerUtils.getDefaultResourceControllerName(resourceControllerClassName)), + name, crdName, valueOrDefault( controllerAnnotation, @@ -183,8 +160,6 @@ private ControllerConfiguration createControllerConfiguration( "generationAwareEventProcessing", AnnotationValue::asBoolean, () -> true), - valueOrDefault( - controllerAnnotation, "isClusterScoped", AnnotationValue::asBoolean, () -> false), QuarkusControllerConfiguration.asSet( valueOrDefault( controllerAnnotation, @@ -192,10 +167,13 @@ private ControllerConfiguration createControllerConfiguration( AnnotationValue::asStringArray, () -> new String[] {})), crType, - doneableClassName, null // todo: fix-me ); + log.infov( + "Processed ''{0}'' controller named ''{1}'' for ''{2}'' CR (version ''{3}'')", + info.name().toString(), name, cr.getCRDName(), cr.getApiVersion()); + return configuration; } diff --git a/operator-framework-quarkus-extension/pom.xml b/operator-framework-quarkus-extension/pom.xml index b2e7e952f4..82fdda219a 100644 --- a/operator-framework-quarkus-extension/pom.xml +++ b/operator-framework-quarkus-extension/pom.xml @@ -5,7 +5,7 @@ io.javaoperatorsdk java-operator-sdk - 1.6.4-SNAPSHOT + 1.7.0-SNAPSHOT 4.0.0 @@ -19,7 +19,7 @@ UTF-8 UTF-8 true - 1.10.5.Final + 1.11.0.Final 3.8.1 3.0.0-M5 diff --git a/operator-framework-quarkus-extension/runtime/pom.xml b/operator-framework-quarkus-extension/runtime/pom.xml index df04049226..d43bde4ba3 100644 --- a/operator-framework-quarkus-extension/runtime/pom.xml +++ b/operator-framework-quarkus-extension/runtime/pom.xml @@ -6,7 +6,7 @@ io.javaoperatorsdk operator-framework-quarkus-extension-parent - 1.6.4-SNAPSHOT + 1.7.0-SNAPSHOT ../pom.xml diff --git a/operator-framework-quarkus-extension/runtime/src/main/java/io/javaoperatorsdk/quarkus/extension/QuarkusConfigurationService.java b/operator-framework-quarkus-extension/runtime/src/main/java/io/javaoperatorsdk/quarkus/extension/QuarkusConfigurationService.java index 996862356b..042502a9ee 100644 --- a/operator-framework-quarkus-extension/runtime/src/main/java/io/javaoperatorsdk/quarkus/extension/QuarkusConfigurationService.java +++ b/operator-framework-quarkus-extension/runtime/src/main/java/io/javaoperatorsdk/quarkus/extension/QuarkusConfigurationService.java @@ -1,14 +1,18 @@ package io.javaoperatorsdk.quarkus.extension; import io.fabric8.kubernetes.client.Config; +import io.fabric8.kubernetes.client.CustomResource; import io.fabric8.kubernetes.client.KubernetesClient; +import io.javaoperatorsdk.operator.api.ResourceController; import io.javaoperatorsdk.operator.api.config.AbstractConfigurationService; import io.javaoperatorsdk.operator.api.config.ControllerConfiguration; +import io.quarkus.arc.runtime.ClientProxyUnwrapper; import java.util.List; import javax.inject.Inject; public class QuarkusConfigurationService extends AbstractConfigurationService { @Inject KubernetesClient client; + private static final ClientProxyUnwrapper unwrapper = new ClientProxyUnwrapper(); public QuarkusConfigurationService(List configurations) { if (configurations != null && !configurations.isEmpty()) { @@ -20,4 +24,16 @@ public QuarkusConfigurationService(List configurations) public Config getClientConfiguration() { return client.getConfiguration(); } + + @Override + public ControllerConfiguration getConfigurationFor( + ResourceController controller) { + final var unwrapped = unwrap(controller); + return super.getConfigurationFor(unwrapped); + } + + private static ResourceController unwrap( + ResourceController controller) { + return (ResourceController) unwrapper.apply(controller); + } } diff --git a/operator-framework-quarkus-extension/runtime/src/main/java/io/javaoperatorsdk/quarkus/extension/QuarkusControllerConfiguration.java b/operator-framework-quarkus-extension/runtime/src/main/java/io/javaoperatorsdk/quarkus/extension/QuarkusControllerConfiguration.java index d9e1793ae5..0c0a90b6ca 100644 --- a/operator-framework-quarkus-extension/runtime/src/main/java/io/javaoperatorsdk/quarkus/extension/QuarkusControllerConfiguration.java +++ b/operator-framework-quarkus-extension/runtime/src/main/java/io/javaoperatorsdk/quarkus/extension/QuarkusControllerConfiguration.java @@ -1,7 +1,6 @@ package io.javaoperatorsdk.quarkus.extension; import io.fabric8.kubernetes.client.CustomResource; -import io.fabric8.kubernetes.client.CustomResourceDoneable; import io.javaoperatorsdk.operator.api.config.ControllerConfiguration; import io.javaoperatorsdk.operator.api.config.RetryConfiguration; import io.quarkus.runtime.annotations.RecordableConstructor; @@ -15,10 +14,8 @@ public class QuarkusControllerConfiguration private final String crdName; private final String finalizer; private final boolean generationAware; - private final boolean clusterScoped; private final Set namespaces; private final String crClass; - private final String doneableClassName; private final boolean watchAllNamespaces; private final RetryConfiguration retryConfiguration; @@ -29,20 +26,16 @@ public QuarkusControllerConfiguration( String crdName, String finalizer, boolean generationAware, - boolean clusterScoped, Set namespaces, String crClass, - String doneableClassName, RetryConfiguration retryConfiguration) { this.associatedControllerClassName = associatedControllerClassName; this.name = name; this.crdName = crdName; this.finalizer = finalizer; this.generationAware = generationAware; - this.clusterScoped = clusterScoped; this.namespaces = namespaces; this.crClass = crClass; - this.doneableClassName = doneableClassName; this.watchAllNamespaces = this.namespaces.contains(WATCH_ALL_NAMESPACES_MARKER); this.retryConfiguration = retryConfiguration == null @@ -66,11 +59,6 @@ public String getCrClass() { return crClass; } - // Needed for Quarkus to find the associated constructor parameter - public String getDoneableClassName() { - return doneableClassName; - } - @Override public String getName() { return name; @@ -96,11 +84,6 @@ public Class getCustomResourceClass() { return (Class) loadClass(crClass); } - @Override - public Class> getDoneableClass() { - return (Class>) loadClass(doneableClassName); - } - private Class loadClass(String className) { try { return Thread.currentThread().getContextClassLoader().loadClass(className); @@ -114,11 +97,6 @@ public String getAssociatedControllerClassName() { return associatedControllerClassName; } - @Override - public boolean isClusterScoped() { - return clusterScoped; - } - @Override public Set getNamespaces() { return namespaces; diff --git a/operator-framework-quarkus-extension/tests/pom.xml b/operator-framework-quarkus-extension/tests/pom.xml index a08aa4750f..ff36468ad4 100644 --- a/operator-framework-quarkus-extension/tests/pom.xml +++ b/operator-framework-quarkus-extension/tests/pom.xml @@ -5,7 +5,7 @@ operator-framework-quarkus-extension-parent io.javaoperatorsdk - 1.6.4-SNAPSHOT + 1.7.0-SNAPSHOT 4.0.0 diff --git a/operator-framework-quarkus-extension/tests/src/main/java/io/javaoperatorsdk/quarkus/it/TestController.java b/operator-framework-quarkus-extension/tests/src/main/java/io/javaoperatorsdk/quarkus/it/TestController.java index d29fc56d6e..a837bcfd61 100644 --- a/operator-framework-quarkus-extension/tests/src/main/java/io/javaoperatorsdk/quarkus/it/TestController.java +++ b/operator-framework-quarkus-extension/tests/src/main/java/io/javaoperatorsdk/quarkus/it/TestController.java @@ -6,10 +6,9 @@ import io.javaoperatorsdk.operator.api.ResourceController; import io.javaoperatorsdk.operator.api.UpdateControl; -@Controller(crdName = TestController.CRD_NAME, name = TestController.NAME) +@Controller(name = TestController.NAME) public class TestController implements ResourceController { public static final String NAME = "test"; - public static final String CRD_NAME = "test.example.com"; @Override public DeleteControl deleteResource(TestResource resource, Context context) { diff --git a/operator-framework-quarkus-extension/tests/src/main/java/io/javaoperatorsdk/quarkus/it/TestOperatorApp.java b/operator-framework-quarkus-extension/tests/src/main/java/io/javaoperatorsdk/quarkus/it/TestOperatorApp.java index 0ad0aa2636..9f5538ed32 100644 --- a/operator-framework-quarkus-extension/tests/src/main/java/io/javaoperatorsdk/quarkus/it/TestOperatorApp.java +++ b/operator-framework-quarkus-extension/tests/src/main/java/io/javaoperatorsdk/quarkus/it/TestOperatorApp.java @@ -65,14 +65,6 @@ public String getAssociatedControllerClassName() { return conf.getAssociatedControllerClassName(); } - public String getDoneableClass() { - return conf.getDoneableClass().getCanonicalName(); - } - - public boolean isClusterScoped() { - return conf.isClusterScoped(); - } - public Set getNamespaces() { return conf.getNamespaces(); } diff --git a/operator-framework-quarkus-extension/tests/src/main/java/io/javaoperatorsdk/quarkus/it/TestResource.java b/operator-framework-quarkus-extension/tests/src/main/java/io/javaoperatorsdk/quarkus/it/TestResource.java index 92a49075b5..0b70aed902 100644 --- a/operator-framework-quarkus-extension/tests/src/main/java/io/javaoperatorsdk/quarkus/it/TestResource.java +++ b/operator-framework-quarkus-extension/tests/src/main/java/io/javaoperatorsdk/quarkus/it/TestResource.java @@ -1,5 +1,9 @@ package io.javaoperatorsdk.quarkus.it; import io.fabric8.kubernetes.client.CustomResource; +import io.fabric8.kubernetes.model.annotation.Group; +import io.fabric8.kubernetes.model.annotation.Version; +@Group("example.com") +@Version("v1") public class TestResource extends CustomResource {} diff --git a/operator-framework-quarkus-extension/tests/src/test/java/io/javaoperatorsdk/quarkus/it/QuarkusExtensionProcessorTest.java b/operator-framework-quarkus-extension/tests/src/test/java/io/javaoperatorsdk/quarkus/it/QuarkusExtensionProcessorTest.java index 8b3355c6a0..f75706c829 100644 --- a/operator-framework-quarkus-extension/tests/src/test/java/io/javaoperatorsdk/quarkus/it/QuarkusExtensionProcessorTest.java +++ b/operator-framework-quarkus-extension/tests/src/test/java/io/javaoperatorsdk/quarkus/it/QuarkusExtensionProcessorTest.java @@ -49,8 +49,6 @@ void configurationForControllerShouldExist() { .statusCode(200) .body( "customResourceClass", equalTo(resourceName), - "doneableClass", equalTo(resourceName + "Doneable"), - "name", equalTo(TestController.NAME), - "crdName", equalTo(TestController.CRD_NAME)); + "name", equalTo(TestController.NAME)); } } diff --git a/operator-framework-spring-boot-starter-test/pom.xml b/operator-framework-spring-boot-starter-test/pom.xml index 5c713b2c27..a76edc8b81 100644 --- a/operator-framework-spring-boot-starter-test/pom.xml +++ b/operator-framework-spring-boot-starter-test/pom.xml @@ -4,13 +4,12 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - io.javaoperatorsdk operator-framework-spring-boot-starter-test io.javaoperatorsdk java-operator-sdk - 1.6.4-SNAPSHOT + 1.7.0-SNAPSHOT @@ -44,7 +43,7 @@ io.fabric8 kubernetes-server-mock - 4.12.0 + ${fabric8-client.version} io.javaoperatorsdk diff --git a/operator-framework-spring-boot-starter/pom.xml b/operator-framework-spring-boot-starter/pom.xml index d07f0f6fd0..1731892686 100644 --- a/operator-framework-spring-boot-starter/pom.xml +++ b/operator-framework-spring-boot-starter/pom.xml @@ -6,7 +6,7 @@ io.javaoperatorsdk java-operator-sdk - 1.6.4-SNAPSHOT + 1.7.0-SNAPSHOT operator-framework-spring-boot-starter diff --git a/operator-framework-spring-boot-starter/src/main/java/io/javaoperatorsdk/operator/springboot/starter/OperatorAutoConfiguration.java b/operator-framework-spring-boot-starter/src/main/java/io/javaoperatorsdk/operator/springboot/starter/OperatorAutoConfiguration.java index 314d8b93f3..4a8455b69a 100644 --- a/operator-framework-spring-boot-starter/src/main/java/io/javaoperatorsdk/operator/springboot/starter/OperatorAutoConfiguration.java +++ b/operator-framework-spring-boot-starter/src/main/java/io/javaoperatorsdk/operator/springboot/starter/OperatorAutoConfiguration.java @@ -100,11 +100,6 @@ public Class getCustomResourceClass() { return super.getCustomResourceClass(); } - @Override - public boolean isClusterScoped() { - return properties.map(ControllerProperties::isClusterScoped).orElse(super.isClusterScoped()); - } - @Override public Set getNamespaces() { return properties.map(ControllerProperties::getNamespaces).orElse(super.getNamespaces()); diff --git a/operator-framework-spring-boot-starter/src/test/java/io/javaoperatorsdk/operator/springboot/starter/TestController.java b/operator-framework-spring-boot-starter/src/test/java/io/javaoperatorsdk/operator/springboot/starter/TestController.java index 0c26fc2391..6f786c0f86 100644 --- a/operator-framework-spring-boot-starter/src/test/java/io/javaoperatorsdk/operator/springboot/starter/TestController.java +++ b/operator-framework-spring-boot-starter/src/test/java/io/javaoperatorsdk/operator/springboot/starter/TestController.java @@ -9,7 +9,7 @@ import org.springframework.stereotype.Component; @Component -@Controller(crdName = "name") +@Controller public class TestController implements ResourceController { @Override diff --git a/operator-framework-spring-boot-starter/src/test/java/io/javaoperatorsdk/operator/springboot/starter/model/TestResource.java b/operator-framework-spring-boot-starter/src/test/java/io/javaoperatorsdk/operator/springboot/starter/model/TestResource.java index 91d8b0c2aa..cd7792590a 100644 --- a/operator-framework-spring-boot-starter/src/test/java/io/javaoperatorsdk/operator/springboot/starter/model/TestResource.java +++ b/operator-framework-spring-boot-starter/src/test/java/io/javaoperatorsdk/operator/springboot/starter/model/TestResource.java @@ -1,5 +1,9 @@ package io.javaoperatorsdk.operator.springboot.starter.model; import io.fabric8.kubernetes.client.CustomResource; +import io.fabric8.kubernetes.model.annotation.Group; +import io.fabric8.kubernetes.model.annotation.Version; +@Group("sample.javaoperatorsdk") +@Version("v1") public class TestResource extends CustomResource {} diff --git a/operator-framework-spring-boot-starter/src/test/java/io/javaoperatorsdk/operator/springboot/starter/model/TestResourceDoneable.java b/operator-framework-spring-boot-starter/src/test/java/io/javaoperatorsdk/operator/springboot/starter/model/TestResourceDoneable.java deleted file mode 100644 index fcb5eeaa8d..0000000000 --- a/operator-framework-spring-boot-starter/src/test/java/io/javaoperatorsdk/operator/springboot/starter/model/TestResourceDoneable.java +++ /dev/null @@ -1,11 +0,0 @@ -package io.javaoperatorsdk.operator.springboot.starter.model; - -import io.fabric8.kubernetes.api.builder.Function; -import io.fabric8.kubernetes.client.CustomResourceDoneable; - -public class TestResourceDoneable extends CustomResourceDoneable { - public TestResourceDoneable( - TestResource resource, Function function) { - super(resource, function); - } -} diff --git a/operator-framework/pom.xml b/operator-framework/pom.xml index ae446b480b..bf6bcbf7cc 100644 --- a/operator-framework/pom.xml +++ b/operator-framework/pom.xml @@ -5,7 +5,7 @@ java-operator-sdk io.javaoperatorsdk - 1.6.4-SNAPSHOT + 1.7.0-SNAPSHOT 4.0.0 @@ -73,6 +73,12 @@ 0.19 test + + org.slf4j + slf4j-simple + ${slf4j.version} + test + \ No newline at end of file diff --git a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/AnnotationConfiguration.java b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/AnnotationConfiguration.java index 8a3e05760a..cce8ac1622 100644 --- a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/AnnotationConfiguration.java +++ b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/AnnotationConfiguration.java @@ -1,7 +1,6 @@ package io.javaoperatorsdk.operator.config.runtime; import io.fabric8.kubernetes.client.CustomResource; -import io.fabric8.kubernetes.client.CustomResourceDoneable; import io.javaoperatorsdk.operator.ControllerUtils; import io.javaoperatorsdk.operator.api.Controller; import io.javaoperatorsdk.operator.api.ResourceController; @@ -26,7 +25,7 @@ public String getName() { @Override public String getCRDName() { - return annotation.crdName(); + return CustomResource.getCRDName(getCustomResourceClass()); } @Override @@ -35,7 +34,7 @@ public String getFinalizer() { if (!Controller.NULL.equals(annotationFinalizerName)) { return annotationFinalizerName; } - return ControllerUtils.getDefaultFinalizerName(annotation.crdName()); + return ControllerUtils.getDefaultFinalizerName(getCRDName()); } @Override @@ -48,16 +47,6 @@ public Class getCustomResourceClass() { return RuntimeControllerMetadata.getCustomResourceClass(controller); } - @Override - public Class> getDoneableClass() { - return RuntimeControllerMetadata.getCustomResourceDoneableClass(controller); - } - - @Override - public boolean isClusterScoped() { - return annotation.isClusterScoped(); - } - @Override public Set getNamespaces() { return Set.of(annotation.namespaces()); diff --git a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/ControllerAnnotationProcessor.java b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/ControllerAnnotationProcessor.java index 6ef4126175..14b1307707 100644 --- a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/ControllerAnnotationProcessor.java +++ b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/ControllerAnnotationProcessor.java @@ -1,22 +1,11 @@ package io.javaoperatorsdk.operator.config.runtime; import static io.javaoperatorsdk.operator.config.runtime.RuntimeControllerMetadata.CONTROLLERS_RESOURCE_PATH; -import static io.javaoperatorsdk.operator.config.runtime.RuntimeControllerMetadata.DONEABLES_RESOURCE_PATH; import com.google.auto.service.AutoService; -import com.squareup.javapoet.AnnotationSpec; -import com.squareup.javapoet.ClassName; -import com.squareup.javapoet.JavaFile; -import com.squareup.javapoet.MethodSpec; -import com.squareup.javapoet.ParameterizedTypeName; import com.squareup.javapoet.TypeName; -import com.squareup.javapoet.TypeSpec; -import io.fabric8.kubernetes.api.builder.Function; import io.fabric8.kubernetes.client.CustomResource; -import io.fabric8.kubernetes.client.CustomResourceDoneable; import io.javaoperatorsdk.operator.api.ResourceController; -import java.io.PrintWriter; -import java.util.HashSet; import java.util.Set; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.ProcessingEnvironment; @@ -27,13 +16,9 @@ import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; -import javax.lang.model.element.Modifier; -import javax.lang.model.element.PackageElement; import javax.lang.model.element.TypeElement; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.TypeMirror; -import javax.tools.Diagnostic; -import javax.tools.JavaFileObject; @SupportedAnnotationTypes("io.javaoperatorsdk.operator.api.Controller") @SupportedSourceVersion(SourceVersion.RELEASE_11) @@ -41,10 +26,7 @@ public class ControllerAnnotationProcessor extends AbstractProcessor { private AccumulativeMappingWriter controllersResourceWriter; - private AccumulativeMappingWriter doneablesResourceWriter; private TypeParameterResolver typeParameterResolver; - private final Set generatedDoneableClassFiles = new HashSet<>(); - private DeclaredType fallbackCustomResourceType; @Override public synchronized void init(ProcessingEnvironment processingEnv) { @@ -52,21 +34,8 @@ public synchronized void init(ProcessingEnvironment processingEnv) { controllersResourceWriter = new AccumulativeMappingWriter(CONTROLLERS_RESOURCE_PATH, processingEnv) .loadExistingMappings(); - doneablesResourceWriter = - new AccumulativeMappingWriter(DONEABLES_RESOURCE_PATH, processingEnv) - .loadExistingMappings(); - - doneablesResourceWriter.add( - CustomResource.class.getCanonicalName(), CustomResourceDoneable.class.getCanonicalName()); typeParameterResolver = initializeResolver(processingEnv); - fallbackCustomResourceType = - processingEnv - .getTypeUtils() - .getDeclaredType( - processingEnv - .getElementUtils() - .getTypeElement(CustomResourceDoneable.class.getCanonicalName())); } @Override @@ -77,12 +46,11 @@ public boolean process(Set annotations, RoundEnvironment annotatedElements.stream() .filter(element -> element.getKind().equals(ElementKind.CLASS)) .map(e -> (TypeElement) e) - .forEach(e -> this.generateDoneableClass(e)); + .forEach(this::recordCRType); } } finally { if (roundEnv.processingOver()) { controllersResourceWriter.flush(); - doneablesResourceWriter.flush(); } } return true; @@ -100,7 +68,7 @@ private TypeParameterResolver initializeResolver(ProcessingEnvironment processin return new TypeParameterResolver(resourceControllerType, 0); } - private void generateDoneableClass(TypeElement controllerClassSymbol) { + private void recordCRType(TypeElement controllerClassSymbol) { try { final TypeMirror resourceType = findResourceType(controllerClassSymbol); if (resourceType == null) { @@ -113,63 +81,10 @@ private void generateDoneableClass(TypeElement controllerClassSymbol) { + "': ignoring!"); return; } - - TypeElement customerResourceTypeElement = - processingEnv.getElementUtils().getTypeElement(resourceType.toString()); - - final String doneableClassName = customerResourceTypeElement.getSimpleName() + "Doneable"; - final String destinationClassFileName = - customerResourceTypeElement.getQualifiedName() + "Doneable"; final TypeName customResourceType = TypeName.get(resourceType); + controllersResourceWriter.add( + controllerClassSymbol.getQualifiedName().toString(), customResourceType.toString()); - if (!generatedDoneableClassFiles.add(destinationClassFileName)) { - processingEnv - .getMessager() - .printMessage( - Diagnostic.Kind.NOTE, - String.format( - "%s already exists! adding the mapping to the %s", - destinationClassFileName, CONTROLLERS_RESOURCE_PATH)); - controllersResourceWriter.add( - controllerClassSymbol.getQualifiedName().toString(), customResourceType.toString()); - return; - } - JavaFileObject builderFile = - processingEnv.getFiler().createSourceFile(destinationClassFileName); - - try (PrintWriter out = new PrintWriter(builderFile.openWriter())) { - controllersResourceWriter.add( - controllerClassSymbol.getQualifiedName().toString(), customResourceType.toString()); - final MethodSpec constructor = - MethodSpec.constructorBuilder() - .addModifiers(Modifier.PUBLIC) - .addParameter(customResourceType, "resource") - .addParameter(Function.class, "function") - .addStatement("super(resource,function)") - .addAnnotation( - AnnotationSpec.builder(SuppressWarnings.class) - .addMember("value", "$S", "unchecked") - .build()) - .build(); - - final TypeSpec typeSpec = - TypeSpec.classBuilder(doneableClassName) - .superclass( - ParameterizedTypeName.get( - ClassName.get(CustomResourceDoneable.class), customResourceType)) - .addModifiers(Modifier.PUBLIC) - .addMethod(constructor) - .build(); - - final PackageElement packageElement = - processingEnv.getElementUtils().getPackageOf(customerResourceTypeElement); - final var packageQualifiedName = packageElement.getQualifiedName().toString(); - JavaFile file = JavaFile.builder(packageQualifiedName, typeSpec).build(); - file.writeTo(out); - doneablesResourceWriter.add( - customResourceType.toString(), - makeQualifiedClassName(packageQualifiedName, doneableClassName)); - } } catch (Exception ioException) { ioException.printStackTrace(); } @@ -185,11 +100,4 @@ private TypeMirror findResourceType(TypeElement controllerClassSymbol) { return null; } } - - private String makeQualifiedClassName(String packageName, String className) { - if (packageName.equals("")) { - return className; - } - return packageName + "." + className; - } } 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 55e3a4bdfb..8bbd8d05f4 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 @@ -1,7 +1,6 @@ package io.javaoperatorsdk.operator.config.runtime; import io.fabric8.kubernetes.client.CustomResource; -import io.fabric8.kubernetes.client.CustomResourceDoneable; import io.javaoperatorsdk.operator.api.ResourceController; import java.util.Map; @@ -11,16 +10,11 @@ public class RuntimeControllerMetadata { public static final String DONEABLES_RESOURCE_PATH = "javaoperatorsdk/doneables"; private static final Map, Class> controllerToCustomResourceMappings; - private static final Map, Class> - resourceToDoneableMappings; static { controllerToCustomResourceMappings = ClassMappingProvider.provide( CONTROLLERS_RESOURCE_PATH, ResourceController.class, CustomResource.class); - resourceToDoneableMappings = - ClassMappingProvider.provide( - DONEABLES_RESOURCE_PATH, CustomResource.class, CustomResourceDoneable.class); } static Class getCustomResourceClass( @@ -35,18 +29,4 @@ static Class getCustomResourceClass( } return (Class) customResourceClass; } - - public static - Class> getCustomResourceDoneableClass( - ResourceController controller) { - final Class customResourceClass = getCustomResourceClass(controller); - final Class> doneableClass = - (Class>) - resourceToDoneableMappings.get(customResourceClass); - if (doneableClass == null) { - throw new RuntimeException( - String.format("No matching Doneable class found for %s", customResourceClass)); - } - return doneableClass; - } } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/ConcurrencyIT.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/ConcurrencyIT.java index ede73107df..9d510ce017 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/ConcurrencyIT.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/ConcurrencyIT.java @@ -121,7 +121,8 @@ public void manyResourcesGetCreatedUpdatedAndDeleted() { List crs = integrationTest - .getCrOperations() + .getK8sClient() + .customResources(TestCustomResource.class) .inNamespace(IntegrationTestSupport.TEST_NAMESPACE) .list() .getItems(); 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 6f54d6aa80..128a332e91 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/IntegrationTestSupport.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/IntegrationTestSupport.java @@ -3,13 +3,12 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.awaitility.Awaitility.await; +import io.fabric8.kubernetes.api.model.KubernetesResourceList; import io.fabric8.kubernetes.api.model.Namespace; import io.fabric8.kubernetes.api.model.NamespaceBuilder; import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; import io.fabric8.kubernetes.api.model.apiextensions.v1beta1.CustomResourceDefinition; import io.fabric8.kubernetes.client.CustomResource; -import io.fabric8.kubernetes.client.CustomResourceDoneable; -import io.fabric8.kubernetes.client.CustomResourceList; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.dsl.MixedOperation; import io.fabric8.kubernetes.client.dsl.Resource; @@ -33,10 +32,7 @@ public class IntegrationTestSupport { private static final Logger log = LoggerFactory.getLogger(IntegrationTestSupport.class); private KubernetesClient k8sClient; private MixedOperation< - CustomResource, - CustomResourceList, - CustomResourceDoneable, - Resource> + CustomResource, KubernetesResourceList, Resource> crOperations; private Operator operator; private ResourceController controller; @@ -57,11 +53,8 @@ public void initialize( final var configurationService = DefaultConfigurationService.instance(); final var config = configurationService.getConfigurationFor(controller); - Class doneableClass = config.getDoneableClass(); - Class customResourceClass = config.getCustomResourceClass(); - crOperations = - k8sClient.customResources( - crdContext, customResourceClass, CustomResourceList.class, doneableClass); + final var customResourceClass = config.getCustomResourceClass(); + this.crOperations = k8sClient.customResources(customResourceClass); if (k8sClient.namespaces().withName(TEST_NAMESPACE).get() == null) { k8sClient @@ -177,10 +170,7 @@ public KubernetesClient getK8sClient() { } public MixedOperation< - CustomResource, - CustomResourceList, - CustomResourceDoneable, - Resource> + CustomResource, KubernetesResourceList, Resource> getCrOperations() { return crOperations; } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/runtime/ControllerAnnotationProcessorTest.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/runtime/ControllerAnnotationProcessorTest.java index 0227cae834..ea26b91b93 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/runtime/ControllerAnnotationProcessorTest.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/runtime/ControllerAnnotationProcessorTest.java @@ -3,9 +3,7 @@ import com.google.testing.compile.Compilation; import com.google.testing.compile.CompilationSubject; import com.google.testing.compile.Compiler; -import com.google.testing.compile.JavaFileObjectSubject; import com.google.testing.compile.JavaFileObjects; -import javax.tools.JavaFileObject; import org.junit.jupiter.api.Test; class ControllerAnnotationProcessorTest { @@ -19,12 +17,6 @@ public void generateCorrectDoneableClassIfInterfaceIsSecond() { JavaFileObjects.forResource( "compile-fixtures/ControllerImplemented2Interfaces.java")); CompilationSubject.assertThat(compilation).succeeded(); - - final JavaFileObject expectedResource = - JavaFileObjects.forResource( - "compile-fixtures/ControllerImplemented2InterfacesExpected.java"); - JavaFileObjectSubject.assertThat(compilation.generatedSourceFiles().get(0)) - .hasSourceEquivalentTo(expectedResource); } @Test @@ -37,12 +29,6 @@ public void generateCorrectDoneableClassIfThereIsAbstractBaseController() { JavaFileObjects.forResource( "compile-fixtures/ControllerImplementedIntermediateAbstractClass.java")); CompilationSubject.assertThat(compilation).succeeded(); - - final JavaFileObject expectedResource = - JavaFileObjects.forResource( - "compile-fixtures/ControllerImplementedIntermediateAbstractClassExpected.java"); - JavaFileObjectSubject.assertThat(compilation.generatedSourceFiles().get(0)) - .hasSourceEquivalentTo(expectedResource); } @Test @@ -55,10 +41,5 @@ public void generateDoneableClasswithMultilevelHierarchy() { JavaFileObjects.forResource("compile-fixtures/MultilevelAbstractController.java"), JavaFileObjects.forResource("compile-fixtures/MultilevelController.java")); CompilationSubject.assertThat(compilation).succeeded(); - - final JavaFileObject expectedResource = - JavaFileObjects.forResource("compile-fixtures/MultilevelControllerExpected.java"); - JavaFileObjectSubject.assertThat(compilation.generatedSourceFiles().get(0)) - .hasSourceEquivalentTo(expectedResource); } } diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/runtime/DefaultConfigurationServiceTest.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/runtime/DefaultConfigurationServiceTest.java index 6a3986a5df..c7c8b2a0d9 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/runtime/DefaultConfigurationServiceTest.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/runtime/DefaultConfigurationServiceTest.java @@ -3,10 +3,10 @@ import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; import io.fabric8.kubernetes.client.CustomResource; -import io.fabric8.kubernetes.client.CustomResourceDoneable; +import io.fabric8.kubernetes.model.annotation.Group; +import io.fabric8.kubernetes.model.annotation.Version; import io.javaoperatorsdk.operator.ControllerUtils; import io.javaoperatorsdk.operator.api.Context; import io.javaoperatorsdk.operator.api.Controller; @@ -24,13 +24,12 @@ public void returnsValuesFromControllerAnnotationFinalizer() { final var controller = new TestCustomResourceController(); final var configuration = DefaultConfigurationService.instance().getConfigurationFor(controller); - assertEquals(TestCustomResourceController.CRD_NAME, configuration.getCRDName()); + assertEquals(CustomResource.getCRDName(TestCustomResource.class), configuration.getCRDName()); assertEquals( ControllerUtils.getDefaultFinalizerName(configuration.getCRDName()), configuration.getFinalizer()); assertEquals(TestCustomResource.class, configuration.getCustomResourceClass()); assertFalse(configuration.isGenerationAware()); - assertTrue(CustomResourceDoneable.class.isAssignableFrom(configuration.getDoneableClass())); } @Test @@ -46,14 +45,18 @@ public void supportsInnerClassCustomResources() { final var controller = new TestCustomFinalizerController(); assertDoesNotThrow( () -> { - DefaultConfigurationService.instance().getConfigurationFor(controller).getDoneableClass(); + DefaultConfigurationService.instance() + .getConfigurationFor(controller) + .getAssociatedControllerClassName(); }); } - @Controller(crdName = "test.crd", finalizerName = CUSTOM_FINALIZER_NAME) + @Controller(finalizerName = CUSTOM_FINALIZER_NAME) static class TestCustomFinalizerController implements ResourceController { + @Group("test.crd") + @Version("v1") public class InnerCustomResource extends CustomResource {} @Override @@ -70,15 +73,8 @@ public UpdateControl createOr } } - @Controller( - generationAwareEventProcessing = false, - crdName = TestCustomResourceController.CRD_NAME, - name = "test") + @Controller(generationAwareEventProcessing = false, name = "test") static class TestCustomResourceController implements ResourceController { - - public static final String CRD_NAME = "customservices.sample.javaoperatorsdk"; - public static final String FINALIZER_NAME = CRD_NAME + "/finalizer"; - @Override public DeleteControl deleteResource( TestCustomResource resource, Context context) { diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/runtime/TestCustomResource.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/runtime/TestCustomResource.java index 79116a136b..44109bf43d 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/runtime/TestCustomResource.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/config/runtime/TestCustomResource.java @@ -1,5 +1,10 @@ package io.javaoperatorsdk.operator.config.runtime; +import io.fabric8.kubernetes.api.model.Namespaced; import io.fabric8.kubernetes.client.CustomResource; +import io.fabric8.kubernetes.model.annotation.Group; +import io.fabric8.kubernetes.model.annotation.Version; -class TestCustomResource extends CustomResource {} +@Group("sample.javaoperatorsdk") +@Version("v1") +class TestCustomResource extends CustomResource implements Namespaced {} diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/doubleupdate/DoubleUpdateTestCustomResource.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/doubleupdate/DoubleUpdateTestCustomResource.java index 064f3eb085..e76c63c52d 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/doubleupdate/DoubleUpdateTestCustomResource.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/doubleupdate/DoubleUpdateTestCustomResource.java @@ -1,38 +1,14 @@ package io.javaoperatorsdk.operator.sample.doubleupdate; +import io.fabric8.kubernetes.api.model.Namespaced; import io.fabric8.kubernetes.client.CustomResource; - -public class DoubleUpdateTestCustomResource extends CustomResource { - - private DoubleUpdateTestCustomResourceSpec spec; - - private DoubleUpdateTestCustomResourceStatus status; - - public DoubleUpdateTestCustomResourceSpec getSpec() { - return spec; - } - - public void setSpec(DoubleUpdateTestCustomResourceSpec spec) { - this.spec = spec; - } - - public DoubleUpdateTestCustomResourceStatus getStatus() { - return status; - } - - public void setStatus(DoubleUpdateTestCustomResourceStatus status) { - this.status = status; - } - - @Override - public String toString() { - return "DoubleUpdateTestCustomResource{" - + "spec=" - + spec - + ", status=" - + status - + ", extendedFrom=" - + super.toString() - + '}'; - } -} +import io.fabric8.kubernetes.model.annotation.Group; +import io.fabric8.kubernetes.model.annotation.Kind; +import io.fabric8.kubernetes.model.annotation.Version; + +@Group("sample.javaoperatorsdk") +@Version("v1") +@Kind("DoubleUpdateSample") +public class DoubleUpdateTestCustomResource + extends CustomResource + implements Namespaced {} diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/doubleupdate/DoubleUpdateTestCustomResourceController.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/doubleupdate/DoubleUpdateTestCustomResourceController.java index 0169ececd6..613a1eba79 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/doubleupdate/DoubleUpdateTestCustomResourceController.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/doubleupdate/DoubleUpdateTestCustomResourceController.java @@ -7,11 +7,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@Controller(crdName = DoubleUpdateTestCustomResourceController.CRD_NAME) +@Controller public class DoubleUpdateTestCustomResourceController implements ResourceController, TestExecutionInfoProvider { - public static final String CRD_NAME = "doubleupdatesamples.sample.javaoperatorsdk"; private static final Logger log = LoggerFactory.getLogger(DoubleUpdateTestCustomResourceController.class); public static final String TEST_ANNOTATION = "TestAnnotation"; diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/event/EventSourceTestCustomResource.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/event/EventSourceTestCustomResource.java index fcd968ab53..d38da3fa2d 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/event/EventSourceTestCustomResource.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/event/EventSourceTestCustomResource.java @@ -1,38 +1,14 @@ package io.javaoperatorsdk.operator.sample.event; +import io.fabric8.kubernetes.api.model.Namespaced; import io.fabric8.kubernetes.client.CustomResource; - -public class EventSourceTestCustomResource extends CustomResource { - - private EventSourceTestCustomResourceSpec spec; - - private EventSourceTestCustomResourceStatus status; - - public EventSourceTestCustomResourceSpec getSpec() { - return spec; - } - - public void setSpec(EventSourceTestCustomResourceSpec spec) { - this.spec = spec; - } - - public EventSourceTestCustomResourceStatus getStatus() { - return status; - } - - public void setStatus(EventSourceTestCustomResourceStatus status) { - this.status = status; - } - - @Override - public String toString() { - return "TestCustomResource{" - + "spec=" - + spec - + ", status=" - + status - + ", extendedFrom=" - + super.toString() - + '}'; - } -} +import io.fabric8.kubernetes.model.annotation.Group; +import io.fabric8.kubernetes.model.annotation.Kind; +import io.fabric8.kubernetes.model.annotation.Version; + +@Group("sample.javaoperatorsdk") +@Version("v1") +@Kind("Eventsourcesample") +public class EventSourceTestCustomResource + extends CustomResource + implements Namespaced {} diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/event/EventSourceTestCustomResourceController.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/event/EventSourceTestCustomResourceController.java index 6cfb0b2565..e77c7bdd14 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/event/EventSourceTestCustomResourceController.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/event/EventSourceTestCustomResourceController.java @@ -1,5 +1,7 @@ package io.javaoperatorsdk.operator.sample.event; +import io.fabric8.kubernetes.client.CustomResource; +import io.javaoperatorsdk.operator.ControllerUtils; import io.javaoperatorsdk.operator.TestExecutionInfoProvider; import io.javaoperatorsdk.operator.api.Context; import io.javaoperatorsdk.operator.api.Controller; @@ -12,12 +14,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@Controller(crdName = EventSourceTestCustomResourceController.CRD_NAME) +@Controller public class EventSourceTestCustomResourceController implements ResourceController, TestExecutionInfoProvider { - public static final String CRD_NAME = "eventsourcesamples.sample.javaoperatorsdk"; - public static final String FINALIZER_NAME = CRD_NAME + "/finalizer"; + public static final String FINALIZER_NAME = + ControllerUtils.getDefaultFinalizerName( + CustomResource.getCRDName(EventSourceTestCustomResource.class)); private static final Logger log = LoggerFactory.getLogger(EventSourceTestCustomResourceController.class); public static final int TIMER_DELAY = 300; diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/retry/RetryTestCustomResource.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/retry/RetryTestCustomResource.java index a351a78a33..c1e35d48df 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/retry/RetryTestCustomResource.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/retry/RetryTestCustomResource.java @@ -1,38 +1,14 @@ package io.javaoperatorsdk.operator.sample.retry; +import io.fabric8.kubernetes.api.model.Namespaced; import io.fabric8.kubernetes.client.CustomResource; - -public class RetryTestCustomResource extends CustomResource { - - private RetryTestCustomResourceSpec spec; - - private RetryTestCustomResourceStatus status; - - public RetryTestCustomResourceSpec getSpec() { - return spec; - } - - public void setSpec(RetryTestCustomResourceSpec spec) { - this.spec = spec; - } - - public RetryTestCustomResourceStatus getStatus() { - return status; - } - - public void setStatus(RetryTestCustomResourceStatus status) { - this.status = status; - } - - @Override - public String toString() { - return "TestCustomResource{" - + "spec=" - + spec - + ", status=" - + status - + ", extendedFrom=" - + super.toString() - + '}'; - } -} +import io.fabric8.kubernetes.model.annotation.Group; +import io.fabric8.kubernetes.model.annotation.Kind; +import io.fabric8.kubernetes.model.annotation.Version; + +@Group("sample.javaoperatorsdk") +@Version("v1") +@Kind("retrysample") +public class RetryTestCustomResource + extends CustomResource + implements Namespaced {} diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/retry/RetryTestCustomResourceController.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/retry/RetryTestCustomResourceController.java index e723caf118..0bc1e227cd 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/retry/RetryTestCustomResourceController.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/retry/RetryTestCustomResourceController.java @@ -1,5 +1,7 @@ package io.javaoperatorsdk.operator.sample.retry; +import io.fabric8.kubernetes.client.CustomResource; +import io.javaoperatorsdk.operator.ControllerUtils; import io.javaoperatorsdk.operator.TestExecutionInfoProvider; import io.javaoperatorsdk.operator.api.Context; import io.javaoperatorsdk.operator.api.Controller; @@ -10,14 +12,15 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@Controller(crdName = RetryTestCustomResourceController.CRD_NAME) +@Controller public class RetryTestCustomResourceController implements ResourceController, TestExecutionInfoProvider { public static final int NUMBER_FAILED_EXECUTIONS = 2; - public static final String CRD_NAME = "retrysamples.sample.javaoperatorsdk"; - public static final String FINALIZER_NAME = CRD_NAME + "/finalizer"; + public static final String FINALIZER_NAME = + ControllerUtils.getDefaultFinalizerName( + CustomResource.getCRDName(RetryTestCustomResource.class)); private static final Logger log = LoggerFactory.getLogger(RetryTestCustomResourceController.class); private final AtomicInteger numberOfExecutions = new AtomicInteger(0); diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomResource.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomResource.java index dd6ed3ab86..3fb144f332 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomResource.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomResource.java @@ -1,38 +1,14 @@ package io.javaoperatorsdk.operator.sample.simple; +import io.fabric8.kubernetes.api.model.Namespaced; import io.fabric8.kubernetes.client.CustomResource; - -public class TestCustomResource extends CustomResource { - - private TestCustomResourceSpec spec; - - private TestCustomResourceStatus status; - - public TestCustomResourceSpec getSpec() { - return spec; - } - - public void setSpec(TestCustomResourceSpec spec) { - this.spec = spec; - } - - public TestCustomResourceStatus getStatus() { - return status; - } - - public void setStatus(TestCustomResourceStatus status) { - this.status = status; - } - - @Override - public String toString() { - return "TestCustomResource{" - + "spec=" - + spec - + ", status=" - + status - + ", extendedFrom=" - + super.toString() - + '}'; - } -} +import io.fabric8.kubernetes.model.annotation.Group; +import io.fabric8.kubernetes.model.annotation.Kind; +import io.fabric8.kubernetes.model.annotation.Version; + +@Group("sample.javaoperatorsdk") +@Version("v1") +@Kind("CustomService") +public class TestCustomResource + extends CustomResource + implements Namespaced {} diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomResourceController.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomResourceController.java index 63f93f40ac..01b30f8f72 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomResourceController.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/simple/TestCustomResourceController.java @@ -3,7 +3,9 @@ import io.fabric8.kubernetes.api.model.ConfigMap; import io.fabric8.kubernetes.api.model.ConfigMapBuilder; import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; +import io.fabric8.kubernetes.client.CustomResource; import io.fabric8.kubernetes.client.KubernetesClient; +import io.javaoperatorsdk.operator.ControllerUtils; import io.javaoperatorsdk.operator.TestExecutionInfoProvider; import io.javaoperatorsdk.operator.api.Context; import io.javaoperatorsdk.operator.api.Controller; @@ -16,14 +18,14 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@Controller(generationAwareEventProcessing = false, crdName = TestCustomResourceController.CRD_NAME) +@Controller(generationAwareEventProcessing = false) public class TestCustomResourceController implements ResourceController, TestExecutionInfoProvider { private static final Logger log = LoggerFactory.getLogger(TestCustomResourceController.class); - public static final String CRD_NAME = "customservices.sample.javaoperatorsdk"; - public static final String FINALIZER_NAME = CRD_NAME + "/finalizer"; + public static final String FINALIZER_NAME = + ControllerUtils.getDefaultFinalizerName(CustomResource.getCRDName(TestCustomResource.class)); private final KubernetesClient kubernetesClient; private final boolean updateStatus; diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResource.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResource.java index 8c0beb1947..d1da028d9b 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResource.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResource.java @@ -1,38 +1,16 @@ package io.javaoperatorsdk.operator.sample.subresource; +import io.fabric8.kubernetes.api.model.Namespaced; import io.fabric8.kubernetes.client.CustomResource; - -public class SubResourceTestCustomResource extends CustomResource { - - private SubResourceTestCustomResourceSpec spec; - - private SubResourceTestCustomResourceStatus status; - - public SubResourceTestCustomResourceSpec getSpec() { - return spec; - } - - public void setSpec(SubResourceTestCustomResourceSpec spec) { - this.spec = spec; - } - - public SubResourceTestCustomResourceStatus getStatus() { - return status; - } - - public void setStatus(SubResourceTestCustomResourceStatus status) { - this.status = status; - } - - @Override - public String toString() { - return "TestCustomResource{" - + "spec=" - + spec - + ", status=" - + status - + ", extendedFrom=" - + super.toString() - + '}'; - } -} +import io.fabric8.kubernetes.model.annotation.Group; +import io.fabric8.kubernetes.model.annotation.Kind; +import io.fabric8.kubernetes.model.annotation.Plural; +import io.fabric8.kubernetes.model.annotation.Version; + +@Group("sample.javaoperatorsdk") +@Version("v1") +@Kind("SubresourceSample") +@Plural("subresourcesample") +public class SubResourceTestCustomResource + extends CustomResource + implements Namespaced {} diff --git a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResourceController.java b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResourceController.java index e0e0100225..0493f395b2 100644 --- a/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResourceController.java +++ b/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/subresource/SubResourceTestCustomResourceController.java @@ -1,5 +1,7 @@ package io.javaoperatorsdk.operator.sample.subresource; +import io.fabric8.kubernetes.client.CustomResource; +import io.javaoperatorsdk.operator.ControllerUtils; import io.javaoperatorsdk.operator.TestExecutionInfoProvider; import io.javaoperatorsdk.operator.api.Context; import io.javaoperatorsdk.operator.api.Controller; @@ -10,14 +12,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@Controller( - crdName = SubResourceTestCustomResourceController.CRD_NAME, - generationAwareEventProcessing = false) +@Controller(generationAwareEventProcessing = false) public class SubResourceTestCustomResourceController implements ResourceController, TestExecutionInfoProvider { - public static final String CRD_NAME = "subresourcesample.sample.javaoperatorsdk"; - public static final String FINALIZER_NAME = CRD_NAME + "/finalizer"; + public static final String FINALIZER_NAME = + ControllerUtils.getDefaultFinalizerName( + CustomResource.getCRDName(SubResourceTestCustomResource.class)); private static final Logger log = LoggerFactory.getLogger(SubResourceTestCustomResourceController.class); private final AtomicInteger numberOfExecutions = new AtomicInteger(0); diff --git a/operator-framework/src/test/resources/compile-fixtures/ControllerImplemented2Interfaces.java b/operator-framework/src/test/resources/compile-fixtures/ControllerImplemented2Interfaces.java index 9f12f17b75..406d314091 100644 --- a/operator-framework/src/test/resources/compile-fixtures/ControllerImplemented2Interfaces.java +++ b/operator-framework/src/test/resources/compile-fixtures/ControllerImplemented2Interfaces.java @@ -8,7 +8,7 @@ import io.javaoperatorsdk.operator.api.UpdateControl; import java.io.Serializable; -@Controller(crdName = "test.crd") +@Controller public class ControllerImplemented2Interfaces implements Serializable, ResourceController { public static class MyCustomResource extends CustomResource { diff --git a/operator-framework/src/test/resources/compile-fixtures/ControllerImplemented2InterfacesExpected.java b/operator-framework/src/test/resources/compile-fixtures/ControllerImplemented2InterfacesExpected.java deleted file mode 100644 index e1c466245b..0000000000 --- a/operator-framework/src/test/resources/compile-fixtures/ControllerImplemented2InterfacesExpected.java +++ /dev/null @@ -1,12 +0,0 @@ -package io; - -import io.fabric8.kubernetes.api.builder.Function; -import io.fabric8.kubernetes.client.CustomResourceDoneable; -import java.lang.SuppressWarnings; - -public class MyCustomResourceDoneable extends CustomResourceDoneable { - @SuppressWarnings("unchecked") - public MyCustomResourceDoneable(ControllerImplemented2Interfaces.MyCustomResource resource, Function function) { - super(resource, function); - } -} diff --git a/operator-framework/src/test/resources/compile-fixtures/ControllerImplementedIntermediateAbstractClass.java b/operator-framework/src/test/resources/compile-fixtures/ControllerImplementedIntermediateAbstractClass.java index 4f312b26ff..f048fb25f0 100644 --- a/operator-framework/src/test/resources/compile-fixtures/ControllerImplementedIntermediateAbstractClass.java +++ b/operator-framework/src/test/resources/compile-fixtures/ControllerImplementedIntermediateAbstractClass.java @@ -6,7 +6,7 @@ import io.javaoperatorsdk.operator.api.UpdateControl; import java.io.Serializable; -@Controller(crdName = "test.crd") +@Controller public class ControllerImplementedIntermediateAbstractClass extends AbstractController implements Serializable { diff --git a/operator-framework/src/test/resources/compile-fixtures/ControllerImplementedIntermediateAbstractClassExpected.java b/operator-framework/src/test/resources/compile-fixtures/ControllerImplementedIntermediateAbstractClassExpected.java deleted file mode 100644 index 7b313d6f92..0000000000 --- a/operator-framework/src/test/resources/compile-fixtures/ControllerImplementedIntermediateAbstractClassExpected.java +++ /dev/null @@ -1,12 +0,0 @@ -package io; - -import io.fabric8.kubernetes.api.builder.Function; -import io.fabric8.kubernetes.client.CustomResourceDoneable; -import java.lang.SuppressWarnings; - -public class MyCustomResourceDoneable extends CustomResourceDoneable { - @SuppressWarnings("unchecked") - public MyCustomResourceDoneable(AbstractController.MyCustomResource resource, Function function) { - super(resource, function); - } -} diff --git a/operator-framework/src/test/resources/compile-fixtures/MultilevelController.java b/operator-framework/src/test/resources/compile-fixtures/MultilevelController.java index c3759d2adf..8c1b6a7ffb 100644 --- a/operator-framework/src/test/resources/compile-fixtures/MultilevelController.java +++ b/operator-framework/src/test/resources/compile-fixtures/MultilevelController.java @@ -6,7 +6,7 @@ import io.javaoperatorsdk.operator.api.DeleteControl; import io.javaoperatorsdk.operator.api.UpdateControl; -@Controller(crdName = "test.crd") +@Controller public class MultilevelController extends MultilevelAbstractController { diff --git a/operator-framework/src/test/resources/compile-fixtures/MultilevelControllerExpected.java b/operator-framework/src/test/resources/compile-fixtures/MultilevelControllerExpected.java deleted file mode 100644 index 6a6be0068a..0000000000 --- a/operator-framework/src/test/resources/compile-fixtures/MultilevelControllerExpected.java +++ /dev/null @@ -1,12 +0,0 @@ -package io; - -import io.fabric8.kubernetes.api.builder.Function; -import io.fabric8.kubernetes.client.CustomResourceDoneable; -import java.lang.SuppressWarnings; - -public class MyCustomResourceDoneable extends CustomResourceDoneable { - @SuppressWarnings("unchecked") - public MyCustomResourceDoneable(MultilevelController.MyCustomResource resource, Function function) { - super(resource, function); - } -} diff --git a/pom.xml b/pom.xml index d260f4b424..653199165c 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.javaoperatorsdk java-operator-sdk - 1.6.4-SNAPSHOT + 1.7.0-SNAPSHOT Operator SDK for Java Java SDK for implementing Kubernetes operators pom @@ -38,6 +38,8 @@ 5.7.0 3.0.0-M5 UTF-8 + 5.0.0 + 1.7.30 @@ -55,12 +57,12 @@ io.fabric8 openshift-client - 4.12.0 + ${fabric8-client.version} org.slf4j slf4j-api - 1.7.30 + ${slf4j.version} org.junit.jupiter diff --git a/samples/common/pom.xml b/samples/common/pom.xml index 4f59a95d83..b5563cc129 100644 --- a/samples/common/pom.xml +++ b/samples/common/pom.xml @@ -6,7 +6,7 @@ io.javaoperatorsdk java-operator-sdk-samples - 1.6.4-SNAPSHOT + 1.7.0-SNAPSHOT operator-framework-samples-common diff --git a/samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomService.java b/samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomService.java index bfd16de585..c3106295c2 100644 --- a/samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomService.java +++ b/samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomService.java @@ -1,16 +1,10 @@ package io.javaoperatorsdk.operator.sample; +import io.fabric8.kubernetes.api.model.Namespaced; import io.fabric8.kubernetes.client.CustomResource; +import io.fabric8.kubernetes.model.annotation.Group; +import io.fabric8.kubernetes.model.annotation.Version; -public class CustomService extends CustomResource { - - private ServiceSpec spec; - - public ServiceSpec getSpec() { - return spec; - } - - public void setSpec(ServiceSpec spec) { - this.spec = spec; - } -} +@Group("sample.javaoperatorsdk") +@Version("v1") +public class CustomService extends CustomResource implements Namespaced {} diff --git a/samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomServiceController.java b/samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomServiceController.java index 8cf9fb592c..931f185acb 100644 --- a/samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomServiceController.java +++ b/samples/common/src/main/java/io/javaoperatorsdk/operator/sample/CustomServiceController.java @@ -1,5 +1,6 @@ package io.javaoperatorsdk.operator.sample; +import io.fabric8.kubernetes.api.model.ServiceBuilder; import io.fabric8.kubernetes.api.model.ServicePort; import io.fabric8.kubernetes.api.model.ServiceSpec; import io.fabric8.kubernetes.client.KubernetesClient; @@ -13,7 +14,7 @@ import org.slf4j.LoggerFactory; /** A very simple sample controller that creates a service with a label. */ -@Controller(crdName = "customservices.sample.javaoperatorsdk") +@Controller public class CustomServiceController implements ResourceController { public static final String KIND = "CustomService"; @@ -44,13 +45,14 @@ public UpdateControl createOrUpdateResource( kubernetesClient .services() .inNamespace(resource.getMetadata().getNamespace()) - .createOrReplaceWithNew() - .withNewMetadata() - .withName(resource.getSpec().getName()) - .addToLabels("testLabel", resource.getSpec().getLabel()) - .endMetadata() - .withSpec(serviceSpec) - .done(); + .createOrReplace( + new ServiceBuilder() + .withNewMetadata() + .withName(resource.getSpec().getName()) + .addToLabels("testLabel", resource.getSpec().getLabel()) + .endMetadata() + .withSpec(serviceSpec) + .build()); return UpdateControl.updateCustomResource(resource); } } diff --git a/samples/mysql-schema/pom.xml b/samples/mysql-schema/pom.xml index 75405e9614..4293caf131 100644 --- a/samples/mysql-schema/pom.xml +++ b/samples/mysql-schema/pom.xml @@ -6,7 +6,7 @@ io.javaoperatorsdk java-operator-sdk-samples - 1.6.4-SNAPSHOT + 1.7.0-SNAPSHOT mysql-schema-sample diff --git a/samples/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/Schema.java b/samples/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/Schema.java index 17bfe0c745..15e6a01205 100644 --- a/samples/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/Schema.java +++ b/samples/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/Schema.java @@ -1,26 +1,10 @@ package io.javaoperatorsdk.operator.sample; +import io.fabric8.kubernetes.api.model.Namespaced; import io.fabric8.kubernetes.client.CustomResource; +import io.fabric8.kubernetes.model.annotation.Group; +import io.fabric8.kubernetes.model.annotation.Version; -public class Schema extends CustomResource { - - private SchemaSpec spec; - - private SchemaStatus status; - - public SchemaSpec getSpec() { - return spec; - } - - public void setSpec(SchemaSpec spec) { - this.spec = spec; - } - - public SchemaStatus getStatus() { - return status; - } - - public void setStatus(SchemaStatus status) { - this.status = status; - } -} +@Group("mysql.sample.javaoperatorsdk") +@Version("v1") +public class Schema extends CustomResource implements Namespaced {} diff --git a/samples/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/SchemaController.java b/samples/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/SchemaController.java index d4bef70978..4367333ed4 100644 --- a/samples/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/SchemaController.java +++ b/samples/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/SchemaController.java @@ -21,7 +21,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@Controller(crdName = "schemas.mysql.sample.javaoperatorsdk") +@Controller public class SchemaController implements ResourceController { static final String USERNAME_FORMAT = "%s-user"; static final String SECRET_FORMAT = "%s-secret"; diff --git a/samples/pom.xml b/samples/pom.xml index f921263e16..4086823cca 100644 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -6,7 +6,7 @@ io.javaoperatorsdk java-operator-sdk - 1.6.4-SNAPSHOT + 1.7.0-SNAPSHOT java-operator-sdk-samples diff --git a/samples/pure-java/pom.xml b/samples/pure-java/pom.xml index 939c1e8063..21536b72a4 100644 --- a/samples/pure-java/pom.xml +++ b/samples/pure-java/pom.xml @@ -6,7 +6,7 @@ io.javaoperatorsdk java-operator-sdk-samples - 1.6.4-SNAPSHOT + 1.7.0-SNAPSHOT operator-framework-samples-pure-java diff --git a/samples/quarkus/pom.xml b/samples/quarkus/pom.xml index 9331849b7a..9d35749060 100644 --- a/samples/quarkus/pom.xml +++ b/samples/quarkus/pom.xml @@ -5,7 +5,7 @@ io.javaoperatorsdk java-operator-sdk-samples - 1.6.4-SNAPSHOT + 1.7.0-SNAPSHOT 4.0.0 @@ -17,7 +17,7 @@ 11 11 - 1.10.5.Final + 1.11.0.Final 3.8.1 true @@ -26,7 +26,7 @@ io.quarkus - quarkus-universe-bom + quarkus-bom ${quarkus.version} pom import diff --git a/samples/quarkus/src/main/java/io/javaoperatorsdk/operator/sample/QuarkusOperator.java b/samples/quarkus/src/main/java/io/javaoperatorsdk/operator/sample/QuarkusOperator.java index 794de984a7..1c0f01953b 100644 --- a/samples/quarkus/src/main/java/io/javaoperatorsdk/operator/sample/QuarkusOperator.java +++ b/samples/quarkus/src/main/java/io/javaoperatorsdk/operator/sample/QuarkusOperator.java @@ -27,7 +27,6 @@ public static void main(String... args) { public int run(String... args) throws Exception { final var config = configuration.getConfigurationFor(controller); System.out.println("CR class: " + config.getCustomResourceClass()); - System.out.println("Doneable class = " + config.getDoneableClass()); Quarkus.waitForExit(); return 0; } diff --git a/samples/spring-boot-auto-config/pom.xml b/samples/spring-boot-auto-config/pom.xml index 6210f42180..558ea40dda 100644 --- a/samples/spring-boot-auto-config/pom.xml +++ b/samples/spring-boot-auto-config/pom.xml @@ -8,7 +8,7 @@ io.javaoperatorsdk java-operator-sdk-samples - 1.6.4-SNAPSHOT + 1.7.0-SNAPSHOT operator-framework-samples-spring-boot-auto-configuration diff --git a/samples/spring-boot-plain/pom.xml b/samples/spring-boot-plain/pom.xml index 83bc0ed249..1c2ba1c952 100644 --- a/samples/spring-boot-plain/pom.xml +++ b/samples/spring-boot-plain/pom.xml @@ -6,7 +6,7 @@ io.javaoperatorsdk java-operator-sdk-samples - 1.6.4-SNAPSHOT + 1.7.0-SNAPSHOT operator-framework-samples-spring-boot-plain diff --git a/samples/tomcat/pom.xml b/samples/tomcat/pom.xml index 647d956473..e8cb52fa17 100644 --- a/samples/tomcat/pom.xml +++ b/samples/tomcat/pom.xml @@ -7,7 +7,7 @@ io.javaoperatorsdk java-operator-sdk-samples - 1.6.4-SNAPSHOT + 1.7.0-SNAPSHOT tomcat-sample diff --git a/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/DeploymentEventSource.java b/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/DeploymentEventSource.java index 93a6e49e5d..85654ad73a 100644 --- a/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/DeploymentEventSource.java +++ b/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/DeploymentEventSource.java @@ -2,12 +2,11 @@ import static io.javaoperatorsdk.operator.processing.KubernetesResourceUtils.getUID; import static io.javaoperatorsdk.operator.processing.KubernetesResourceUtils.getVersion; -import static java.net.HttpURLConnection.HTTP_GONE; import io.fabric8.kubernetes.api.model.apps.Deployment; import io.fabric8.kubernetes.client.KubernetesClient; -import io.fabric8.kubernetes.client.KubernetesClientException; import io.fabric8.kubernetes.client.Watcher; +import io.fabric8.kubernetes.client.WatcherException; import io.javaoperatorsdk.operator.processing.event.AbstractEventSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -57,11 +56,11 @@ public void eventReceived(Action action, Deployment deployment) { } @Override - public void onClose(KubernetesClientException e) { + public void onClose(WatcherException e) { if (e == null) { return; } - if (e.getCode() == HTTP_GONE) { + if (e.isHttpGone()) { log.warn("Received error for watch, will try to reconnect.", e); registerWatch(); } else { diff --git a/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/Tomcat.java b/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/Tomcat.java index 6c192ab846..2792781009 100644 --- a/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/Tomcat.java +++ b/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/Tomcat.java @@ -1,32 +1,10 @@ package io.javaoperatorsdk.operator.sample; +import io.fabric8.kubernetes.api.model.Namespaced; import io.fabric8.kubernetes.client.CustomResource; +import io.fabric8.kubernetes.model.annotation.Group; +import io.fabric8.kubernetes.model.annotation.Version; -public class Tomcat extends CustomResource { - - private TomcatSpec spec; - - private TomcatStatus status; - - public TomcatSpec getSpec() { - if (spec == null) { - spec = new TomcatSpec(); - } - return spec; - } - - public void setSpec(TomcatSpec spec) { - this.spec = spec; - } - - public TomcatStatus getStatus() { - if (status == null) { - status = new TomcatStatus(); - } - return status; - } - - public void setStatus(TomcatStatus status) { - this.status = status; - } -} +@Group("tomcatoperator.io") +@Version("v1") +public class Tomcat extends CustomResource implements Namespaced {} diff --git a/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/TomcatController.java b/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/TomcatController.java index 3943d41557..c2326e0b53 100644 --- a/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/TomcatController.java +++ b/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/TomcatController.java @@ -1,21 +1,18 @@ package io.javaoperatorsdk.operator.sample; -import io.fabric8.kubernetes.api.model.DoneableService; import io.fabric8.kubernetes.api.model.HasMetadata; import io.fabric8.kubernetes.api.model.OwnerReference; import io.fabric8.kubernetes.api.model.Service; import io.fabric8.kubernetes.api.model.apps.Deployment; import io.fabric8.kubernetes.api.model.apps.DeploymentStatus; -import io.fabric8.kubernetes.api.model.apps.DoneableDeployment; -import io.fabric8.kubernetes.client.CustomResourceDoneable; -import io.fabric8.kubernetes.client.CustomResourceList; import io.fabric8.kubernetes.client.KubernetesClient; -import io.fabric8.kubernetes.client.dsl.MixedOperation; -import io.fabric8.kubernetes.client.dsl.Resource; import io.fabric8.kubernetes.client.dsl.RollableScalableResource; import io.fabric8.kubernetes.client.dsl.ServiceResource; import io.fabric8.kubernetes.client.utils.Serialization; -import io.javaoperatorsdk.operator.api.*; +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.processing.event.EventSourceManager; import io.javaoperatorsdk.operator.processing.event.internal.CustomResourceEvent; import java.io.IOException; @@ -26,20 +23,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@Controller(crdName = "tomcats.tomcatoperator.io") public class TomcatController implements ResourceController { private final Logger log = LoggerFactory.getLogger(getClass()); private final KubernetesClient kubernetesClient; - private MixedOperation< - Tomcat, - CustomResourceList, - CustomResourceDoneable, - Resource>> - tomcatOperations; - private DeploymentEventSource deploymentEventSource; public TomcatController(KubernetesClient client) { @@ -153,7 +142,7 @@ private void createOrUpdateDeployment(Tomcat tomcat) { private void deleteDeployment(Tomcat tomcat) { log.info("Deleting Deployment {}", tomcat.getMetadata().getName()); - RollableScalableResource deployment = + RollableScalableResource deployment = kubernetesClient .apps() .deployments() @@ -176,7 +165,7 @@ private void createOrUpdateService(Tomcat tomcat) { private void deleteService(Tomcat tomcat) { log.info("Deleting Service {}", tomcat.getMetadata().getName()); - ServiceResource service = + ServiceResource service = kubernetesClient .services() .inNamespace(tomcat.getMetadata().getNamespace()) @@ -194,17 +183,8 @@ private T loadYaml(Class clazz, String yaml) { } } - public void setTomcatOperations( - MixedOperation< - Tomcat, - CustomResourceList, - CustomResourceDoneable, - Resource>> - tomcatOperations) { - this.tomcatOperations = tomcatOperations; - } - private static class WatchedResource { + private final String type; private final String name; @@ -219,9 +199,13 @@ public static WatchedResource fromResource(HasMetadata resource) { @Override public boolean equals(Object o) { - if (this == o) return true; + if (this == o) { + return true; + } - if (o == null || getClass() != o.getClass()) return false; + if (o == null || getClass() != o.getClass()) { + return false; + } WatchedResource that = (WatchedResource) o; diff --git a/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/TomcatOperator.java b/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/TomcatOperator.java index 579c7fed7e..e2bfff6d54 100644 --- a/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/TomcatOperator.java +++ b/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/TomcatOperator.java @@ -26,7 +26,6 @@ public static void main(String[] args) throws IOException { TomcatController tomcatController = new TomcatController(client); operator.registerControllerForAllNamespaces(tomcatController); - tomcatController.setTomcatOperations(operator.getCustomResourceClients(Tomcat.class)); operator.registerControllerForAllNamespaces(new WebappController(client)); diff --git a/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/Webapp.java b/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/Webapp.java index 5c3efa7a40..b496a05378 100644 --- a/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/Webapp.java +++ b/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/Webapp.java @@ -1,29 +1,9 @@ package io.javaoperatorsdk.operator.sample; import io.fabric8.kubernetes.client.CustomResource; +import io.fabric8.kubernetes.model.annotation.Group; +import io.fabric8.kubernetes.model.annotation.Version; -public class Webapp extends CustomResource { - - private WebappSpec spec; - - private WebappStatus status; - - public WebappSpec getSpec() { - return spec; - } - - public void setSpec(WebappSpec spec) { - this.spec = spec; - } - - public WebappStatus getStatus() { - if (status == null) { - status = new WebappStatus(); - } - return status; - } - - public void setStatus(WebappStatus status) { - this.status = status; - } -} +@Group("tomcatoperator.io") +@Version("v1") +public class Webapp extends CustomResource {} diff --git a/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/WebappController.java b/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/WebappController.java index 32c3c2cd2f..80c6a647ce 100644 --- a/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/WebappController.java +++ b/samples/tomcat/src/main/java/io/javaoperatorsdk/operator/sample/WebappController.java @@ -12,7 +12,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@Controller(crdName = "webapps.tomcatoperator.io") +@Controller public class WebappController implements ResourceController { private KubernetesClient kubernetesClient; diff --git a/samples/webserver/pom.xml b/samples/webserver/pom.xml index 222461c084..a4064d54f0 100644 --- a/samples/webserver/pom.xml +++ b/samples/webserver/pom.xml @@ -6,7 +6,7 @@ io.javaoperatorsdk java-operator-sdk-samples - 1.6.4-SNAPSHOT + 1.7.0-SNAPSHOT webserver-sample diff --git a/samples/webserver/src/main/java/io/javaoperatorsdk/operator/sample/WebServer.java b/samples/webserver/src/main/java/io/javaoperatorsdk/operator/sample/WebServer.java index cbef68eb80..9554fd3f12 100644 --- a/samples/webserver/src/main/java/io/javaoperatorsdk/operator/sample/WebServer.java +++ b/samples/webserver/src/main/java/io/javaoperatorsdk/operator/sample/WebServer.java @@ -1,26 +1,11 @@ package io.javaoperatorsdk.operator.sample; +import io.fabric8.kubernetes.api.model.Namespaced; import io.fabric8.kubernetes.client.CustomResource; +import io.fabric8.kubernetes.model.annotation.Group; +import io.fabric8.kubernetes.model.annotation.Version; -public class WebServer extends CustomResource { - - private WebServerSpec spec; - - private WebServerStatus status; - - public WebServerSpec getSpec() { - return spec; - } - - public void setSpec(WebServerSpec spec) { - this.spec = spec; - } - - public WebServerStatus getStatus() { - return status; - } - - public void setStatus(WebServerStatus status) { - this.status = status; - } -} +@Group("sample.javaoperatorsdk") +@Version("v1") +public class WebServer extends CustomResource + implements Namespaced {} diff --git a/samples/webserver/src/main/java/io/javaoperatorsdk/operator/sample/WebServerController.java b/samples/webserver/src/main/java/io/javaoperatorsdk/operator/sample/WebServerController.java index fb1f87da51..be5bbe4495 100644 --- a/samples/webserver/src/main/java/io/javaoperatorsdk/operator/sample/WebServerController.java +++ b/samples/webserver/src/main/java/io/javaoperatorsdk/operator/sample/WebServerController.java @@ -3,19 +3,15 @@ import io.fabric8.kubernetes.api.model.ConfigMap; import io.fabric8.kubernetes.api.model.ConfigMapBuilder; import io.fabric8.kubernetes.api.model.ConfigMapVolumeSourceBuilder; -import io.fabric8.kubernetes.api.model.DoneableConfigMap; -import io.fabric8.kubernetes.api.model.DoneableService; import io.fabric8.kubernetes.api.model.ObjectMetaBuilder; import io.fabric8.kubernetes.api.model.Service; import io.fabric8.kubernetes.api.model.apps.Deployment; -import io.fabric8.kubernetes.api.model.apps.DoneableDeployment; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.kubernetes.client.dsl.Resource; import io.fabric8.kubernetes.client.dsl.RollableScalableResource; import io.fabric8.kubernetes.client.dsl.ServiceResource; import io.fabric8.kubernetes.client.utils.Serialization; import io.javaoperatorsdk.operator.api.Context; -import io.javaoperatorsdk.operator.api.Controller; import io.javaoperatorsdk.operator.api.DeleteControl; import io.javaoperatorsdk.operator.api.ResourceController; import io.javaoperatorsdk.operator.api.UpdateControl; @@ -27,7 +23,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@Controller(crdName = "webservers.sample.javaoperatorsdk") public class WebServerController implements ResourceController { private final Logger log = LoggerFactory.getLogger(getClass()); @@ -129,7 +124,7 @@ public DeleteControl deleteResource( log.info("Execution deleteResource for: {}", nginx.getMetadata().getName()); log.info("Deleting ConfigMap {}", configMapName(nginx)); - Resource configMap = + Resource configMap = kubernetesClient .configMaps() .inNamespace(nginx.getMetadata().getNamespace()) @@ -139,7 +134,7 @@ public DeleteControl deleteResource( } log.info("Deleting Deployment {}", deploymentName(nginx)); - RollableScalableResource deployment = + RollableScalableResource deployment = kubernetesClient .apps() .deployments() @@ -150,7 +145,7 @@ public DeleteControl deleteResource( } log.info("Deleting Service {}", serviceName(nginx)); - ServiceResource service = + ServiceResource service = kubernetesClient .services() .inNamespace(nginx.getMetadata().getNamespace())