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 cdf308d5bf..9a407c0dc2 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 @@ -21,6 +21,7 @@ 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.gizmo.ClassCreator; import io.quarkus.gizmo.ClassOutput; import io.quarkus.gizmo.MethodCreator; @@ -55,6 +56,12 @@ FeatureBuildItem feature() { return new FeatureBuildItem(FEATURE); } + @BuildStep + void indexSDKDependencies(BuildProducer indexDependency) { + indexDependency.produce( + new IndexDependencyBuildItem("io.javaoperatorsdk", "operator-framework-core")); + } + @BuildStep @Record(ExecutionTime.RUNTIME_INIT) void createConfigurationServiceAndOperator( @@ -132,6 +139,13 @@ private ControllerConfiguration createControllerConfiguration( // generate configuration final var controllerAnnotation = info.classAnnotation(CONTROLLER); + if (controllerAnnotation == null) { + throw new IllegalArgumentException( + resourceControllerClassName + + " is missing the " + + Controller.class.getCanonicalName() + + " annotation"); + } final var crdName = valueOrDefault( controllerAnnotation, "crdName", AnnotationValue::asString, EXCEPTION_SUPPLIER); diff --git a/operator-framework-quarkus-extension/pom.xml b/operator-framework-quarkus-extension/pom.xml index 623d2d1dff..b04cd947cb 100644 --- a/operator-framework-quarkus-extension/pom.xml +++ b/operator-framework-quarkus-extension/pom.xml @@ -27,6 +27,7 @@ deployment runtime + tests @@ -47,6 +48,10 @@ maven-compiler-plugin ${compiler-plugin.version} + + maven-surefire-plugin + ${maven.surefire.version} + diff --git a/operator-framework-quarkus-extension/runtime/pom.xml b/operator-framework-quarkus-extension/runtime/pom.xml index f8b30000bb..17ed9ac7bf 100644 --- a/operator-framework-quarkus-extension/runtime/pom.xml +++ b/operator-framework-quarkus-extension/runtime/pom.xml @@ -18,7 +18,6 @@ io.javaoperatorsdk operator-framework-core ${project.version} - compile io.quarkus @@ -78,16 +77,6 @@ - - maven-surefire-plugin - ${maven.surefire.version} - - - org.jboss.logmanager.LogManager - ${maven.home} - - - diff --git a/operator-framework-quarkus-extension/tests/pom.xml b/operator-framework-quarkus-extension/tests/pom.xml new file mode 100644 index 0000000000..5c5c183153 --- /dev/null +++ b/operator-framework-quarkus-extension/tests/pom.xml @@ -0,0 +1,83 @@ + + + + operator-framework-quarkus-extension-parent + io.javaoperatorsdk + 1.6.2-SNAPSHOT + + 4.0.0 + + operator-framework-quarkus-tests + Operator SDK - Quarkus Extension - Tests + + + + 11 + 11 + + + + + io.javaoperatorsdk + operator-framework-quarkus-extension + ${project.version} + + + io.quarkus + quarkus-resteasy-jackson + + + io.quarkus + quarkus-junit5-internal + test + + + io.rest-assured + rest-assured + test + + + org.assertj + assertj-core + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + true + + + + io.quarkus + quarkus-maven-plugin + ${quarkus.version} + + + + build + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + + org.jboss.logmanager.LogManager + + ${maven.home} + + + + + + \ No newline at end of file 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 new file mode 100644 index 0000000000..d29fc56d6e --- /dev/null +++ b/operator-framework-quarkus-extension/tests/src/main/java/io/javaoperatorsdk/quarkus/it/TestController.java @@ -0,0 +1,24 @@ +package io.javaoperatorsdk.quarkus.it; + +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; + +@Controller(crdName = TestController.CRD_NAME, 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) { + return null; + } + + @Override + public UpdateControl createOrUpdateResource( + TestResource resource, Context context) { + return null; + } +} 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 new file mode 100644 index 0000000000..ed6316ab0a --- /dev/null +++ b/operator-framework-quarkus-extension/tests/src/main/java/io/javaoperatorsdk/quarkus/it/TestOperatorApp.java @@ -0,0 +1,28 @@ +package io.javaoperatorsdk.quarkus.it; + +import io.javaoperatorsdk.operator.api.config.ConfigurationService; +import io.javaoperatorsdk.operator.api.config.ControllerConfiguration; +import javax.inject.Inject; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; + +@Path("/operator") +public class TestOperatorApp { + + @Inject TestController controller; + @Inject ConfigurationService configurationService; + + @GET + @Path("{name}") + // @Produces(MediaType.TEXT_PLAIN) + public boolean getController(@PathParam("name") String name) { + return name.equals(controller.getName()); + } + + @GET + @Path("{name}/config") + public ControllerConfiguration getConfig(@PathParam("name") String name) { + return getController(name) ? configurationService.getConfigurationFor(controller) : null; + } +} 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 new file mode 100644 index 0000000000..92a49075b5 --- /dev/null +++ b/operator-framework-quarkus-extension/tests/src/main/java/io/javaoperatorsdk/quarkus/it/TestResource.java @@ -0,0 +1,5 @@ +package io.javaoperatorsdk.quarkus.it; + +import io.fabric8.kubernetes.client.CustomResource; + +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 new file mode 100644 index 0000000000..8b3355c6a0 --- /dev/null +++ b/operator-framework-quarkus-extension/tests/src/test/java/io/javaoperatorsdk/quarkus/it/QuarkusExtensionProcessorTest.java @@ -0,0 +1,56 @@ +package io.javaoperatorsdk.quarkus.it; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; + +import io.quarkus.test.QuarkusProdModeTest; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +/** + * This tests creates and starts an application accessed over REST to assess that injected values + * are present and what we expect. + */ +public class QuarkusExtensionProcessorTest { + + @RegisterExtension + static final QuarkusProdModeTest config = + new QuarkusProdModeTest() + .setArchiveProducer( + () -> + ShrinkWrap.create(JavaArchive.class) + .addClasses(TestOperatorApp.class, TestController.class, TestResource.class)) + .setApplicationName("basic-app") + .setApplicationVersion("0.1-SNAPSHOT") + .setRun(true); + + @Test + void controllerShouldExist() { + // first check that we're not always returning true for any controller name :) + given().when().get("/operator/does_not_exist").then().statusCode(200).body(is("false")); + + // given the name of the TestController, the app should reply true meaning that it is indeed + // injected + given().when().get("/operator/" + TestController.NAME).then().statusCode(200).body(is("true")); + } + + @Test + void configurationForControllerShouldExist() { + // check that the config for the test controller can be retrieved and is conform to our + // expectations + final var resourceName = TestResource.class.getCanonicalName(); + given() + .when() + .get("/operator/" + TestController.NAME + "/config") + .then() + .statusCode(200) + .body( + "customResourceClass", equalTo(resourceName), + "doneableClass", equalTo(resourceName + "Doneable"), + "name", equalTo(TestController.NAME), + "crdName", equalTo(TestController.CRD_NAME)); + } +} diff --git a/operator-framework-spring-boot-starter-test/pom.xml b/operator-framework-spring-boot-starter-test/pom.xml index 775b2aefc6..11ad82657d 100644 --- a/operator-framework-spring-boot-starter-test/pom.xml +++ b/operator-framework-spring-boot-starter-test/pom.xml @@ -32,12 +32,6 @@ - - io.fabric8 - kubernetes-server-mock - 4.12.0 - - org.springframework.boot spring-boot-starter