diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml
index b3126be08..f7e591d81 100644
--- a/.github/workflows/ci-build.yml
+++ b/.github/workflows/ci-build.yml
@@ -110,6 +110,7 @@ jobs:
matrix:
native-image-project:
- :camel-k-quarkus-itests-core
+ - :camel-k-quarkus-itests-runtime
- :camel-k-quarkus-itests-cron
- :camel-k-quarkus-itests-master
- :camel-k-quarkus-itests-kamelet
diff --git a/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-cron/pom.xml b/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-cron/pom.xml
index 291f5a37a..032eb98c7 100644
--- a/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-cron/pom.xml
+++ b/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-cron/pom.xml
@@ -28,10 +28,22 @@
camel-k-quarkus-itests-cron
+
+ org.apache.camel.k
+ camel-k-runtime-quarkus
+
org.apache.camel.k
camel-k-quarkus-cron
+
+ org.apache.camel.k
+ camel-k-quarkus-loader-yaml
+
+
+ org.apache.camel.quarkus
+ camel-quarkus-timer
+
@@ -68,6 +80,13 @@
hamcrest-core
test
+
+
+ org.awaitility
+ awaitility
+ ${awaitility-version}
+
+
diff --git a/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-cron/src/main/java/org/apache/camel/k/quarkus/cron/deployment/Application.java b/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-cron/src/main/java/org/apache/camel/k/quarkus/cron/deployment/Application.java
index 3d8cb21ef..a70fd026f 100644
--- a/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-cron/src/main/java/org/apache/camel/k/quarkus/cron/deployment/Application.java
+++ b/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-cron/src/main/java/org/apache/camel/k/quarkus/cron/deployment/Application.java
@@ -16,22 +16,38 @@
*/
package org.apache.camel.k.quarkus.cron.deployment;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
+import javax.inject.Singleton;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
+import io.quarkus.arc.Unremovable;
import org.apache.camel.CamelContext;
import org.apache.camel.ExtendedCamelContext;
import org.apache.camel.k.Constants;
+import org.apache.camel.k.Runtime;
+import org.apache.camel.k.Source;
+import org.apache.camel.k.SourceLoader;
+import org.apache.camel.k.Sources;
+import org.apache.camel.k.cron.CronSourceLoaderInterceptor;
+import org.apache.camel.k.loader.yaml.YamlSourceLoader;
@Path("/test")
@ApplicationScoped
public class Application {
@Inject
CamelContext context;
+ @Inject
+ Runtime runtime;
+
+ private final AtomicBoolean stopped = new AtomicBoolean();
@GET
@Path("/find-cron-interceptor")
@@ -43,4 +59,54 @@ public String findCronInterceptor() {
.map(Class::getName)
.orElse("");
}
+
+ @GET
+ @Path("/load")
+ @Produces(MediaType.TEXT_PLAIN)
+ public String load() throws Exception {
+ final String code = ""
+ + "\n- from:"
+ + "\n uri: \"timer:tick?period=1&delay=60000\""
+ + "\n steps:"
+ + "\n - log: \"${body}\"";
+
+ final SourceLoader loader = new YamlSourceLoader();
+ final Source source = Sources.fromBytes("my-cron", "yaml", null, List.of("cron"), code.getBytes(StandardCharsets.UTF_8));
+
+ final CronSourceLoaderInterceptor interceptor = new CronSourceLoaderInterceptor();
+ interceptor.setRuntime(runtime);
+ interceptor.setOverridableComponents("timer");
+
+ SourceLoader.Result result = interceptor.afterLoad(
+ loader,
+ source,
+ loader.load(runtime, source));
+
+ result.builder().ifPresent(b -> {
+ try {
+ context.addRoutes(b);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ });
+
+ return "" + context.getRoutesSize();
+ }
+
+ @GET
+ @Path("/stopped")
+ @Produces(MediaType.TEXT_PLAIN)
+ public String stopped() {
+ return "" + stopped.get();
+ }
+
+ /*
+ * Override the default ShutdownTask for testing purpose.
+ */
+ @Unremovable
+ @Singleton
+ @javax.enterprise.inject.Produces
+ org.apache.camel.k.quarkus.Application.ShutdownTask shutdownTask() {
+ return () -> stopped.set(true);
+ }
}
diff --git a/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-cron/src/main/resources/application.properties b/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-cron/src/main/resources/application.properties
index 3f6864acc..1882d46d2 100644
--- a/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-cron/src/main/resources/application.properties
+++ b/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-cron/src/main/resources/application.properties
@@ -26,3 +26,5 @@ quarkus.banner.enabled = false
#
quarkus.camel.routes-discovery.enabled = false
+
+
diff --git a/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-cron/src/test/java/org/apache/camel/k/quarkus/cron/deployment/CronTest.java b/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-cron/src/test/java/org/apache/camel/k/quarkus/cron/deployment/CronTest.java
index ff38d6161..e0f945639 100644
--- a/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-cron/src/test/java/org/apache/camel/k/quarkus/cron/deployment/CronTest.java
+++ b/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-cron/src/test/java/org/apache/camel/k/quarkus/cron/deployment/CronTest.java
@@ -16,23 +16,43 @@
*/
package org.apache.camel.k.quarkus.cron.deployment;
-import java.io.IOException;
+import java.util.concurrent.TimeUnit;
import io.quarkus.test.junit.QuarkusTest;
import org.apache.camel.k.cron.CronSourceLoaderInterceptor;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.when;
+import static org.awaitility.Awaitility.await;
import static org.hamcrest.Matchers.is;
@QuarkusTest
public class CronTest {
@Test
- public void cronInterceptorIsRegistered() throws IOException {
+ public void cronInterceptorIsRegistered() {
when()
.get("/test/find-cron-interceptor")
.then()
.statusCode(200)
.body(is(CronSourceLoaderInterceptor.class.getName()));
}
+
+ @Test
+ public void cronInvokesShutdown() {
+ when()
+ .get("/test/load")
+ .then()
+ .statusCode(200)
+ .body(is("1"));
+
+ await().atMost(10, TimeUnit.SECONDS).until(() -> {
+ String result = when()
+ .get("/test/stopped")
+ .then()
+ .statusCode(200)
+ .extract().body().asString();
+
+ return "true".equals(result);
+ });
+ }
}
diff --git a/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-master/src/main/java/org/apache/camel/k/quarkus/master/Application.java b/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-master/src/main/java/org/apache/camel/k/quarkus/master/Application.java
index 3135739d6..d81ffd4eb 100644
--- a/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-master/src/main/java/org/apache/camel/k/quarkus/master/Application.java
+++ b/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-master/src/main/java/org/apache/camel/k/quarkus/master/Application.java
@@ -37,13 +37,12 @@ public class Application {
@GET
@Path("/inspect")
@Produces(MediaType.APPLICATION_JSON)
- public JsonObject findCronInterceptor() {
- KubernetesClusterService service = context.hasService(KubernetesClusterService.class);
+ public JsonObject inspect() {
+ var service = context.hasService(KubernetesClusterService.class);
return Json.createObjectBuilder()
.add("cluster-service", service != null ? service.getClass().getName() : "")
.add("cluster-service-cm", service != null ? service.getConfigMapName() : "")
-
.build();
}
}
diff --git a/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-master/src/main/resources/application.properties b/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-master/src/main/resources/application.properties
index 95370157d..e84134f0a 100644
--- a/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-master/src/main/resources/application.properties
+++ b/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-master/src/main/resources/application.properties
@@ -18,7 +18,7 @@
#
# Quarkus
#
-quarkus.log.console.enable = true
+quarkus.log.console.enable = false
quarkus.banner.enabled = false
#
diff --git a/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-runtime/pom.xml b/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-runtime/pom.xml
new file mode 100644
index 000000000..90f33260f
--- /dev/null
+++ b/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-runtime/pom.xml
@@ -0,0 +1,158 @@
+
+
+
+
+ org.apache.camel.k
+ camel-k-quarkus-itests
+ 1.5.1-SNAPSHOT
+
+ 4.0.0
+
+ camel-k-quarkus-itests-runtime
+
+
+
+ org.apache.camel.k
+ camel-k-runtime-quarkus
+
+
+
+ io.quarkus
+ quarkus-jsonb
+
+
+ io.quarkus
+ quarkus-resteasy
+
+
+ io.quarkus
+ quarkus-resteasy-jsonb
+
+
+
+
+ io.quarkus
+ quarkus-junit5
+ test
+
+
+ io.rest-assured
+ rest-assured
+ test
+
+
+ org.assertj
+ assertj-core
+ test
+
+
+
+
+
+
+
+ org.codehaus.mojo
+ build-helper-maven-plugin
+ ${build-helper-maven-plugin-version}
+
+
+ reserve-network-port
+
+ reserve-network-port
+
+ process-resources
+
+
+ test.http.port.jvm
+ test.http.port.native
+
+
+
+
+
+
+ io.quarkus
+ quarkus-maven-plugin
+ ${quarkus-version}
+
+
+
+ build
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ ${project.basedir}/src/test/resources/test.properties
+
+
+ ${test.http.port.jvm}
+ org.jboss.logmanager.LogManager
+ ${project.basedir}/src/test/resources/test.properties
+
+
+
+
+
+
+
+
+ native
+
+
+ native
+
+
+
+ native
+
+
+
+
+ org.apache.maven.plugins
+ maven-failsafe-plugin
+
+
+
+ integration-test
+ verify
+
+
+
+ ${project.basedir}/src/test/resources/test.properties
+
+
+ ${test.http.port.native}
+ ${project.build.directory}/${project.build.finalName}-runner
+
+
+
+
+
+
+
+
+
+
+
diff --git a/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-runtime/src/main/java/org/apache/camel/k/quarkus/it/Application.java b/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-runtime/src/main/java/org/apache/camel/k/quarkus/it/Application.java
new file mode 100644
index 000000000..f3112a83f
--- /dev/null
+++ b/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-runtime/src/main/java/org/apache/camel/k/quarkus/it/Application.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.k.quarkus.it;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import javax.json.Json;
+import javax.json.JsonObject;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.k.Runtime;
+import org.eclipse.microprofile.config.Config;
+
+import static org.apache.camel.k.quarkus.Application.instance;
+
+@Path("/test")
+@ApplicationScoped
+public class Application {
+ @Inject
+ Config config;
+
+ @GET
+ @Path("/inspect")
+ @Produces(MediaType.APPLICATION_JSON)
+ public JsonObject inspect() {
+ return Json.createObjectBuilder()
+ .add(
+ "camel-context",
+ instance(CamelContext.class)
+ .map(Object::getClass)
+ .map(Class::getName)
+ .orElse(""))
+ .add(
+ "camel-k-runtime",
+ instance(Runtime.class)
+ .map(Object::getClass)
+ .map(Class::getName)
+ .orElse(""))
+ .add(
+ "shutdown-task",
+ instance(org.apache.camel.k.quarkus.Application.ShutdownTask.class)
+ .map(Object::getClass)
+ .map(Class::getName)
+ .orElse(""))
+ .build();
+ }
+
+ @GET
+ @Path("/property/{name}")
+ @Produces(MediaType.TEXT_PLAIN)
+ public String property(@PathParam("name") String name) {
+ return config.getValue(name, String.class);
+ }
+}
diff --git a/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-runtime/src/main/resources/application.properties b/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-runtime/src/main/resources/application.properties
new file mode 100644
index 000000000..0d67e0636
--- /dev/null
+++ b/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-runtime/src/main/resources/application.properties
@@ -0,0 +1,22 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
+
+#
+# Quarkus
+#
+quarkus.log.console.enable = false
+quarkus.banner.enabled = false
diff --git a/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-runtime/src/test/java/org/apache/camel/k/quarkus/it/RuntimeIT.java b/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-runtime/src/test/java/org/apache/camel/k/quarkus/it/RuntimeIT.java
new file mode 100644
index 000000000..29f1c1745
--- /dev/null
+++ b/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-runtime/src/test/java/org/apache/camel/k/quarkus/it/RuntimeIT.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.k.quarkus.it;
+
+import io.quarkus.test.junit.NativeImageTest;
+
+@NativeImageTest
+public class RuntimeIT extends RuntimeTest {
+}
\ No newline at end of file
diff --git a/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-runtime/src/test/java/org/apache/camel/k/quarkus/it/RuntimeTest.java b/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-runtime/src/test/java/org/apache/camel/k/quarkus/it/RuntimeTest.java
new file mode 100644
index 000000000..5689b734c
--- /dev/null
+++ b/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-runtime/src/test/java/org/apache/camel/k/quarkus/it/RuntimeTest.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.k.quarkus.it;
+
+import javax.ws.rs.core.MediaType;
+
+import io.quarkus.test.junit.QuarkusTest;
+import io.restassured.RestAssured;
+import io.restassured.path.json.JsonPath;
+import org.apache.camel.k.quarkus.Application;
+import org.apache.camel.k.quarkus.ApplicationProducers;
+import org.apache.camel.quarkus.core.FastCamelContext;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@QuarkusTest
+public class RuntimeTest {
+ @Test
+ public void inspect() {
+ JsonPath p = RestAssured.given()
+ .accept(MediaType.APPLICATION_JSON)
+ .get("/test/inspect")
+ .then()
+ .statusCode(200)
+ .extract()
+ .body()
+ .jsonPath();
+
+ assertThat(p.getString("camel-context")).isEqualTo(FastCamelContext.class.getName());
+ assertThat(p.getString("camel-k-runtime")).isEqualTo(Application.Runtime.class.getName());
+ assertThat(p.getString("shutdown-task")).isEqualTo(ApplicationProducers.DefaultShutdownTask.class.getName());
+ }
+
+ @Test
+ public void configSourceProvider() {
+ String result = RestAssured.given()
+ .accept(MediaType.TEXT_PLAIN)
+ .get("/test/property/quarkus.my-property")
+ .then()
+ .statusCode(200)
+ .extract()
+ .body()
+ .asString();
+
+ assertThat(result).isEqualTo("my-test-value");
+ }
+}
\ No newline at end of file
diff --git a/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-runtime/src/test/resources/test.properties b/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-runtime/src/test/resources/test.properties
new file mode 100644
index 000000000..eb73887b5
--- /dev/null
+++ b/camel-k-quarkus/camel-k-quarkus-itests/camel-k-quarkus-itests-runtime/src/test/resources/test.properties
@@ -0,0 +1,18 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
+
+quarkus.my-property = my-test-value
\ No newline at end of file
diff --git a/camel-k-quarkus/camel-k-quarkus-itests/pom.xml b/camel-k-quarkus/camel-k-quarkus-itests/pom.xml
index bc5052555..dd4ddf147 100644
--- a/camel-k-quarkus/camel-k-quarkus-itests/pom.xml
+++ b/camel-k-quarkus/camel-k-quarkus-itests/pom.xml
@@ -30,6 +30,7 @@
camel-k-quarkus-itests-core
+ camel-k-quarkus-itests-runtime
camel-k-quarkus-itests-cron
camel-k-quarkus-itests-master
camel-k-quarkus-itests-kamelet
diff --git a/camel-k-quarkus/camel-k-runtime-quarkus/deployment/src/main/java/org/apache/camel/k/quarkus/deployment/DeploymentProcessor.java b/camel-k-quarkus/camel-k-runtime-quarkus/deployment/src/main/java/org/apache/camel/k/quarkus/deployment/DeploymentProcessor.java
index 076ca3cb1..f95949203 100644
--- a/camel-k-quarkus/camel-k-runtime-quarkus/deployment/src/main/java/org/apache/camel/k/quarkus/deployment/DeploymentProcessor.java
+++ b/camel-k-quarkus/camel-k-runtime-quarkus/deployment/src/main/java/org/apache/camel/k/quarkus/deployment/DeploymentProcessor.java
@@ -20,13 +20,20 @@
import java.util.List;
import java.util.ServiceLoader;
+import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
+import io.quarkus.arc.deployment.BeanContainerBuildItem;
+import io.quarkus.arc.deployment.SyntheticBeansRuntimeInitBuildItem;
import io.quarkus.deployment.annotations.BuildStep;
+import io.quarkus.deployment.annotations.Consume;
import io.quarkus.deployment.annotations.ExecutionTime;
import io.quarkus.deployment.annotations.Record;
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
import org.apache.camel.k.Runtime;
+import org.apache.camel.k.quarkus.ApplicationProducers;
import org.apache.camel.k.quarkus.ApplicationRecorder;
+import org.apache.camel.quarkus.core.deployment.spi.CamelRuntimeTaskBuildItem;
import org.apache.camel.quarkus.main.CamelMainApplication;
+import org.apache.camel.quarkus.main.deployment.spi.CamelMainBuildItem;
import org.apache.camel.quarkus.main.deployment.spi.CamelMainListenerBuildItem;
public class DeploymentProcessor {
@@ -43,4 +50,24 @@ CamelMainListenerBuildItem registerListener(ApplicationRecorder recorder) {
return new CamelMainListenerBuildItem(recorder.createMainListener(listeners));
}
+
+ @Record(ExecutionTime.RUNTIME_INIT)
+ @BuildStep
+ @Consume(SyntheticBeansRuntimeInitBuildItem.class)
+ CamelRuntimeTaskBuildItem registerRuntime(
+ ApplicationRecorder recorder,
+ CamelMainBuildItem camelMain,
+ BeanContainerBuildItem beanContainer) {
+
+ recorder.publishRuntime(camelMain.getInstance(), beanContainer.getValue());
+
+ return new CamelRuntimeTaskBuildItem("camel-k-runtime");
+ }
+
+ @BuildStep
+ List unremovableBeans() {
+ return List.of(
+ AdditionalBeanBuildItem.unremovableOf(ApplicationProducers.class)
+ );
+ }
}
diff --git a/camel-k-quarkus/camel-k-runtime-quarkus/runtime/src/main/java/org/apache/camel/k/quarkus/Application.java b/camel-k-quarkus/camel-k-runtime-quarkus/runtime/src/main/java/org/apache/camel/k/quarkus/Application.java
new file mode 100644
index 000000000..fb0392a1d
--- /dev/null
+++ b/camel-k-quarkus/camel-k-runtime-quarkus/runtime/src/main/java/org/apache/camel/k/quarkus/Application.java
@@ -0,0 +1,170 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.k.quarkus;
+
+import java.util.Comparator;
+import java.util.List;
+import java.util.Optional;
+import java.util.Properties;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import io.quarkus.arc.Arc;
+import io.quarkus.arc.ArcContainer;
+import io.quarkus.arc.InstanceHandle;
+import io.quarkus.runtime.Quarkus;
+import org.apache.camel.CamelContext;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.main.BaseMainSupport;
+import org.apache.camel.main.MainListener;
+
+public final class Application {
+ private Application() {
+ }
+
+ /**
+ * The camel-k runtime impl based on camel-quarkus
+ */
+ public static class Runtime implements org.apache.camel.k.Runtime {
+ private final BaseMainSupport main;
+ private final AtomicBoolean stopped;
+
+ public Runtime(BaseMainSupport main) {
+ this.main = main;
+ this.stopped = new AtomicBoolean();
+ }
+
+ @Override
+ public CamelContext getCamelContext() {
+ return main.getCamelContext();
+ }
+
+ @Override
+ public void addRoutes(RoutesBuilder builder) {
+ main.configure().addRoutesBuilder(builder);
+ }
+
+ @Override
+ public void addConfiguration(Object configuration) {
+ main.configure().addConfiguration(configuration);
+ }
+
+ @Override
+ public void setInitialProperties(Properties properties) {
+ main.setInitialProperties(properties);
+ }
+
+ @Override
+ public void setProperties(Properties properties) {
+ main.setOverrideProperties(properties);
+ }
+
+ @Override
+ public void stop() throws Exception {
+ if (!this.stopped.compareAndExchange(false, true)) {
+ instance(ShutdownTask.class).ifPresentOrElse(
+ ShutdownTask::run,
+ Quarkus::asyncExit);
+ }
+ }
+ }
+
+ /**
+ * Adapts main events to camel-k runtime lifecycle
+ */
+ public static class ListenerAdapter implements MainListener {
+ private final org.apache.camel.k.Runtime.Listener[] listeners;
+
+ public ListenerAdapter(List listeners) {
+ this.listeners = listeners.stream()
+ .sorted(Comparator.comparingInt(org.apache.camel.k.Runtime.Listener::getOrder))
+ .toArray(org.apache.camel.k.Runtime.Listener[]::new);
+ }
+
+ @Override
+ public void beforeInitialize(BaseMainSupport main) {
+ invokeListeners(org.apache.camel.k.Runtime.Phase.ConfigureProperties);
+ }
+
+ @Override
+ public void beforeConfigure(BaseMainSupport main) {
+ invokeListeners(org.apache.camel.k.Runtime.Phase.ConfigureRoutes);
+ }
+
+ @Override
+ public void afterConfigure(BaseMainSupport main) {
+ invokeListeners(org.apache.camel.k.Runtime.Phase.ConfigureContext);
+ }
+
+ @Override
+ public void configure(CamelContext context) {
+ // no-op
+ }
+
+ @Override
+ public void beforeStart(BaseMainSupport main) {
+ invokeListeners(org.apache.camel.k.Runtime.Phase.Starting);
+ }
+
+ @Override
+ public void afterStart(BaseMainSupport main) {
+ invokeListeners(org.apache.camel.k.Runtime.Phase.Started);
+ }
+
+ @Override
+ public void beforeStop(BaseMainSupport main) {
+ invokeListeners(org.apache.camel.k.Runtime.Phase.Stopping);
+ }
+
+ @Override
+ public void afterStop(BaseMainSupport main) {
+ invokeListeners(org.apache.camel.k.Runtime.Phase.Stopped);
+ }
+
+ private void invokeListeners(org.apache.camel.k.Runtime.Phase phase) {
+ org.apache.camel.k.Runtime runtime = instance(org.apache.camel.k.Runtime.class)
+ .orElseThrow(() -> new IllegalStateException("Unable to fine a Runtime instance"));
+
+ for (int i = 0; i < listeners.length; i ++) {
+ listeners[i].accept(phase, runtime);
+ }
+ }
+ }
+
+ /**
+ * Provide the task to be executed to shutdown the runtime
+ */
+ @FunctionalInterface
+ public interface ShutdownTask {
+ void run();
+ }
+
+ // *********************************
+ //
+ // Helpers
+ //
+ // *********************************
+
+ public static Optional container() {
+ return Optional.of(Arc.container());
+ }
+
+ public static Optional instance(Class type) {
+ return container()
+ .map(container -> container.instance(type))
+ .map(InstanceHandle::get);
+ }
+}
diff --git a/camel-k-quarkus/camel-k-runtime-quarkus/runtime/src/main/java/org/apache/camel/k/quarkus/ApplicationRuntimeConfigSourceProvider.java b/camel-k-quarkus/camel-k-runtime-quarkus/runtime/src/main/java/org/apache/camel/k/quarkus/ApplicationConfigSourceProvider.java
similarity index 95%
rename from camel-k-quarkus/camel-k-runtime-quarkus/runtime/src/main/java/org/apache/camel/k/quarkus/ApplicationRuntimeConfigSourceProvider.java
rename to camel-k-quarkus/camel-k-runtime-quarkus/runtime/src/main/java/org/apache/camel/k/quarkus/ApplicationConfigSourceProvider.java
index 302e0c805..cef2910a0 100644
--- a/camel-k-quarkus/camel-k-runtime-quarkus/runtime/src/main/java/org/apache/camel/k/quarkus/ApplicationRuntimeConfigSourceProvider.java
+++ b/camel-k-quarkus/camel-k-runtime-quarkus/runtime/src/main/java/org/apache/camel/k/quarkus/ApplicationConfigSourceProvider.java
@@ -24,7 +24,7 @@
import org.eclipse.microprofile.config.spi.ConfigSource;
import org.eclipse.microprofile.config.spi.ConfigSourceProvider;
-public class ApplicationRuntimeConfigSourceProvider implements ConfigSourceProvider {
+public class ApplicationConfigSourceProvider implements ConfigSourceProvider {
@Override
public Iterable getConfigSources(ClassLoader forClassLoader) {
final Properties applicationProperties = PropertiesSupport.loadProperties();
diff --git a/camel-k-quarkus/camel-k-runtime-quarkus/runtime/src/main/java/org/apache/camel/k/quarkus/ApplicationListenerAdapter.java b/camel-k-quarkus/camel-k-runtime-quarkus/runtime/src/main/java/org/apache/camel/k/quarkus/ApplicationListenerAdapter.java
deleted file mode 100644
index ccb01cca5..000000000
--- a/camel-k-quarkus/camel-k-runtime-quarkus/runtime/src/main/java/org/apache/camel/k/quarkus/ApplicationListenerAdapter.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.k.quarkus;
-
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Properties;
-
-import io.quarkus.runtime.Quarkus;
-import org.apache.camel.CamelContext;
-import org.apache.camel.RoutesBuilder;
-import org.apache.camel.k.Runtime;
-import org.apache.camel.main.BaseMainSupport;
-import org.apache.camel.main.MainListener;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ApplicationListenerAdapter implements MainListener {
- private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationListenerAdapter.class);
-
- private final List listeners;
-
- public ApplicationListenerAdapter() {
- this.listeners = new ArrayList<>();
- }
-
- public ApplicationListenerAdapter(List listeners) {
- this.listeners = new ArrayList<>(listeners);
- }
-
- public void setListeners(List listeners) {
- this.listeners.clear();
- this.listeners.addAll(listeners);
- }
-
- @Override
- public void beforeInitialize(BaseMainSupport main) {
- invokeListeners(listeners, on(main), Runtime.Phase.ConfigureProperties);
- }
-
- @Override
- public void beforeConfigure(BaseMainSupport main) {
- invokeListeners(listeners, on(main), Runtime.Phase.ConfigureRoutes);
- }
-
- @Override
- public void afterConfigure(BaseMainSupport main) {
- invokeListeners(listeners, on(main), Runtime.Phase.ConfigureContext);
- }
-
- @Override
- public void configure(CamelContext context) {
- // no-op
- }
-
- @Override
- public void beforeStart(BaseMainSupport main) {
- invokeListeners(listeners, on(main), Runtime.Phase.Starting);
- }
-
- @Override
- public void afterStart(BaseMainSupport main) {
- invokeListeners(listeners, on(main), Runtime.Phase.Started);
- }
-
- @Override
- public void beforeStop(BaseMainSupport main) {
- invokeListeners(listeners, on(main), Runtime.Phase.Stopping);
- }
-
- @Override
- public void afterStop(BaseMainSupport main) {
- invokeListeners(listeners, on(main), Runtime.Phase.Stopped);
- }
-
- // ************************
- //
- // Helpers
- //
- // ************************
-
- private static void invokeListeners(List listeners, Runtime runtime, Runtime.Phase phase) {
- listeners.stream()
- .sorted(Comparator.comparingInt(Runtime.Listener::getOrder))
- .forEach(l -> {
- if (l.accept(phase, runtime)) {
- LOGGER.debug("Listener {} executed in phase {}", l, phase);
- }
- });
- }
-
- private static Runtime on(BaseMainSupport main) {
- return new Runtime() {
- @Override
- public CamelContext getCamelContext() {
- return main.getCamelContext();
- }
-
- @Override
- public void addRoutes(RoutesBuilder builder) {
- main.configure().addRoutesBuilder(builder);
- }
-
- @Override
- public void addConfiguration(Object configuration) {
- main.configure().addConfiguration(configuration);
- }
-
- @Override
- public void setInitialProperties(Properties properties) {
- main.setInitialProperties(properties);
- }
-
- @Override
- public void setProperties(Properties properties) {
- main.setOverrideProperties(properties);
- }
-
- @Override
- public void stop() throws Exception {
- Quarkus.asyncExit();
- }
- };
- }
-}
diff --git a/camel-k-quarkus/camel-k-runtime-quarkus/runtime/src/main/java/org/apache/camel/k/quarkus/ApplicationProducers.java b/camel-k-quarkus/camel-k-runtime-quarkus/runtime/src/main/java/org/apache/camel/k/quarkus/ApplicationProducers.java
new file mode 100644
index 000000000..f44f3c9c8
--- /dev/null
+++ b/camel-k-quarkus/camel-k-runtime-quarkus/runtime/src/main/java/org/apache/camel/k/quarkus/ApplicationProducers.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.k.quarkus;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.Produces;
+import javax.inject.Singleton;
+
+import io.quarkus.arc.DefaultBean;
+import io.quarkus.arc.Unremovable;
+import io.quarkus.runtime.Quarkus;
+import org.apache.camel.k.Runtime;
+
+@ApplicationScoped
+public class ApplicationProducers {
+ private volatile Runtime runtime;
+
+ public void setRuntime(Runtime runtime) {
+ this.runtime = runtime;
+ }
+
+ @Unremovable
+ @Singleton
+ @Produces
+ Runtime runtime() {
+ return this.runtime;
+ }
+
+ @Unremovable
+ @DefaultBean
+ @Singleton
+ @Produces
+ Application.ShutdownTask shutdownTask() {
+ return new DefaultShutdownTask();
+ }
+
+ public static class DefaultShutdownTask implements Application.ShutdownTask {
+ @Override
+ public void run() {
+ Quarkus.asyncExit();
+ }
+ }
+}
diff --git a/camel-k-quarkus/camel-k-runtime-quarkus/runtime/src/main/java/org/apache/camel/k/quarkus/ApplicationRecorder.java b/camel-k-quarkus/camel-k-runtime-quarkus/runtime/src/main/java/org/apache/camel/k/quarkus/ApplicationRecorder.java
index 587dd9b1d..e4ed9a86e 100644
--- a/camel-k-quarkus/camel-k-runtime-quarkus/runtime/src/main/java/org/apache/camel/k/quarkus/ApplicationRecorder.java
+++ b/camel-k-quarkus/camel-k-runtime-quarkus/runtime/src/main/java/org/apache/camel/k/quarkus/ApplicationRecorder.java
@@ -18,14 +18,20 @@
import java.util.List;
+import io.quarkus.arc.runtime.BeanContainer;
import io.quarkus.runtime.RuntimeValue;
import io.quarkus.runtime.annotations.Recorder;
import org.apache.camel.k.Runtime;
import org.apache.camel.main.MainListener;
+import org.apache.camel.quarkus.main.CamelMain;
@Recorder
public class ApplicationRecorder {
public RuntimeValue createMainListener(List listeners) {
- return new RuntimeValue<>(new ApplicationListenerAdapter(listeners));
+ return new RuntimeValue<>(new Application.ListenerAdapter(listeners));
+ }
+
+ public void publishRuntime(RuntimeValue main, BeanContainer container) {
+ container.instance(ApplicationProducers.class).setRuntime(new Application.Runtime(main.getValue()));
}
}
diff --git a/camel-k-quarkus/camel-k-runtime-quarkus/runtime/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSourceProvider b/camel-k-quarkus/camel-k-runtime-quarkus/runtime/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSourceProvider
index 30fe91e1b..1079ba1eb 100644
--- a/camel-k-quarkus/camel-k-runtime-quarkus/runtime/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSourceProvider
+++ b/camel-k-quarkus/camel-k-runtime-quarkus/runtime/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSourceProvider
@@ -14,4 +14,4 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
-org.apache.camel.k.quarkus.ApplicationRuntimeConfigSourceProvider
\ No newline at end of file
+org.apache.camel.k.quarkus.ApplicationConfigSourceProvider
\ No newline at end of file
diff --git a/camel-k-runtime-cron/src/main/java/org/apache/camel/k/cron/CronSourceLoaderInterceptor.java b/camel-k-runtime-cron/src/main/java/org/apache/camel/k/cron/CronSourceLoaderInterceptor.java
index d3026d1a1..3c965ac0b 100644
--- a/camel-k-runtime-cron/src/main/java/org/apache/camel/k/cron/CronSourceLoaderInterceptor.java
+++ b/camel-k-runtime-cron/src/main/java/org/apache/camel/k/cron/CronSourceLoaderInterceptor.java
@@ -30,6 +30,7 @@
import org.apache.camel.spi.CamelEvent;
import org.apache.camel.spi.Configurer;
import org.apache.camel.support.EventNotifierSupport;
+import org.apache.camel.support.service.ServiceHelper;
import org.apache.camel.util.ObjectHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -100,7 +101,10 @@ public Optional builder() {
// Don't install the shutdown strategy more than once.
//
if (context.getManagementStrategy().getEventNotifiers().stream().noneMatch(CronShutdownStrategy.class::isInstance)) {
- context.getManagementStrategy().addEventNotifier(new CronShutdownStrategy(runtime));
+ CronShutdownStrategy strategy = new CronShutdownStrategy(runtime);
+ ServiceHelper.startService(strategy);
+
+ context.getManagementStrategy().addEventNotifier(strategy);
}
}
}
diff --git a/camel-k-runtime-knative/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.k.loader.knative.KnativeSourceLoaderInterceptor b/camel-k-runtime-knative/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.k.loader.knative.KnativeSourceLoaderInterceptor
deleted file mode 100644
index 50833dcf2..000000000
--- a/camel-k-runtime-knative/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.k.loader.knative.KnativeSourceLoaderInterceptor
+++ /dev/null
@@ -1,2 +0,0 @@
-# Generated by camel build tools - do NOT edit this file!
-class=org.apache.camel.k.loader.knative.KnativeSourceLoaderInterceptorConfigurer
diff --git a/examples/camel-k-runtime-example-quarkus-cron/data/application.properties b/examples/camel-k-runtime-example-quarkus-cron/data/application.properties
index 339b6c409..c32de635a 100644
--- a/examples/camel-k-runtime-example-quarkus-cron/data/application.properties
+++ b/examples/camel-k-runtime-example-quarkus-cron/data/application.properties
@@ -30,6 +30,6 @@ camel.main.stream-caching-spool-directory = ${java.io.tmpdir}/camel-q
#
# Camel K
#
-camel.k.loader.interceptor.cron.overridable-components = timer_
+camel.k.loader.interceptor.cron.overridable-components = timer
diff --git a/pom.xml b/pom.xml
index fb3c0fe62..a7febd7b6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -618,6 +618,12 @@
${rest-assured-version}
+
+ org.awaitility
+ awaitility
+ ${awaitility-version}
+
+
org.codehaus.groovy
groovy