You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by pp...@apache.org on 2023/08/30 13:47:16 UTC
[camel-quarkus] branch main updated: Onboard Camel K Runtime
This is an automated email from the ASF dual-hosted git repository.
ppalaga pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
The following commit(s) were added to refs/heads/main by this push:
new 93d6053c7e Onboard Camel K Runtime
93d6053c7e is described below
commit 93d6053c7ea043ab1af7004ab0307726dc54a440
Author: Claudio Miranda <cl...@claudius.com.br>
AuthorDate: Mon Jul 24 13:24:42 2023 -0300
Onboard Camel K Runtime
https://github.com/apache/camel-quarkus/issues/4283
---
catalog/pom.xml | 14 +
extensions/camel-k/deployment/pom.xml | 154 +++++++
.../camel/quarkus/k/deployment/RuntimeFeature.java | 29 ++
.../quarkus/k/deployment/RuntimeProcessor.java | 144 ++++++
.../deployment/devmode/HotDeploymentProcessor.java | 115 +++++
.../k/deployment/support/DeploymentSupport.java | 61 +++
.../camel/quarkus/k/deployment/LoaderTest.java | 335 ++++++++++++++
.../deployment/src/test/resources/MyRoutes.java | 26 ++
.../deployment/src/test/resources/routes.groovy | 20 +
.../deployment/src/test/resources/routes.js | 19 +
.../deployment/src/test/resources/routes.jsh | 21 +
.../deployment/src/test/resources/routes.kts | 20 +
.../deployment/src/test/resources/routes.xml | 34 ++
.../deployment/src/test/resources/routes.yaml | 25 +
{tooling => extensions/camel-k}/pom.xml | 30 +-
extensions/camel-k/runtime/pom.xml | 214 +++++++++
.../quarkus/k/core/SourceDefinitionConfigurer.java | 114 +++++
.../k/listener/SourcesConfigurerConfigurer.java | 49 ++
...rg.apache.camel.quarkus.k.core.SourceDefinition | 2 +
...ache.camel.quarkus.k.listener.SourcesConfigurer | 2 +
.../org/apache/camel/quarkus/k/core/Runtime.java | 156 +++++++
.../apache/camel/quarkus/k/core/RuntimeAware.java | 24 +
.../org/apache/camel/quarkus/k/core/Source.java | 54 +++
.../camel/quarkus/k/core/SourceDefinition.java | 184 ++++++++
.../apache/camel/quarkus/k/core/SourceType.java | 24 +
.../quarkus/k/listener/AbstractPhaseListener.java | 39 ++
.../quarkus/k/listener/ContextConfigurer.java | 38 ++
.../quarkus/k/listener/SourcesConfigurer.java | 109 +++++
.../camel/quarkus/k/runtime/Application.java | 175 +++++++
.../k/runtime/ApplicationConfigSourceProvider.java | 45 ++
.../quarkus/k/runtime/ApplicationProducers.java | 39 ++
.../quarkus/k/runtime/ApplicationRecorder.java | 48 ++
.../apache/camel/quarkus/k/support/Constants.java | 63 +++
.../camel/quarkus/k/support/DelegatingRuntime.java | 80 ++++
.../camel/quarkus/k/support/PropertiesSupport.java | 93 ++++
.../camel/quarkus/k/support/RouteBuilders.java | 73 +++
.../camel/quarkus/k/support/RuntimeSupport.java | 341 ++++++++++++++
.../apache/camel/quarkus/k/support/Sources.java | 243 ++++++++++
.../camel/quarkus/k/support/SourcesSupport.java | 187 ++++++++
.../camel/quarkus/k/support/StringSupport.java | 75 +++
.../main/resources/META-INF/quarkus-extension.yaml | 33 ++
...rg.apache.camel.quarkus.k.core.Runtime$Listener | 19 +
...se.microprofile.config.spi.ConfigSourceProvider | 17 +
.../org/apache/camel/quarkus/k/SourceTest.java | 54 +++
.../PropertiesFunctionsConfigurerTest.java | 55 +++
.../quarkus/k/listener/SourceConfigurerTest.java | 143 ++++++
.../camel/quarkus/k/support/NameCustomizer.java | 45 ++
.../quarkus/k/support/PropertiesSupportTest.java | 94 ++++
.../quarkus/k/support/RuntimeSupportTest.java | 194 ++++++++
.../org.apache.camel.quarkus.k/customizer/name | 18 +
.../configmaps/my-binary-cm/my-property.zip | Bin 0 -> 186 bytes
.../test/resources/configmaps/my-cm/my-property | 1 +
.../runtime/src/test/resources/my-cp-resource.txt | 1 +
.../src/test/resources/my-file-resource.txt | 1 +
.../test/resources/secrets/my-secret/my-property | 1 +
extensions/pom.xml | 1 +
integration-tests/camel-k-runtime/pom.xml | 187 ++++++++
.../org/apache/camel/quarkus/k/it/Application.java | 108 +++++
.../camel/quarkus/k/it/RuntimeInspector.java | 111 +++++
.../camel/quarkus/k/it/yaml/BeanProducers.java | 36 ++
.../org/apache/camel/quarkus/k/it/yaml/MyBean.java | 46 ++
.../camel/quarkus/k/it/yaml/MyProcessor.java | 28 ++
.../src/main/resources/application.properties | 21 +
.../quarkus/k/it/RuntimeCustomizerFallbackIT.java | 23 +
.../k/it/RuntimeCustomizerFallbackTest.java | 58 +++
.../camel/quarkus/k/it/RuntimeCustomizerIT.java | 23 +
.../camel/quarkus/k/it/RuntimeCustomizerTest.java | 58 +++
.../org/apache/camel/quarkus/k/it/RuntimeIT.java | 23 +
.../org/apache/camel/quarkus/k/it/RuntimeTest.java | 60 +++
.../camel/quarkus/k/it/RuntimeWithXmlIT.java | 23 +
.../camel/quarkus/k/it/RuntimeWithXmlTest.java | 74 +++
.../camel/quarkus/k/it/RuntimeWithYamlIT.java | 23 +
.../camel/quarkus/k/it/RuntimeWithYamlTest.java | 77 ++++
.../apache/camel/quarkus/k/it/TestCustomizer.java | 50 ++
.../org.apache.camel.quarkus.k/customizer/test | 18 +
.../src/test/resources/conf.d/001/conf.properties | 17 +
.../src/test/resources/conf.d/002/conf.properties | 18 +
.../src/test/resources/conf.d/003/flat-property | 1 +
.../src/test/resources/conf.properties | 21 +
.../camel-k-runtime/src/test/resources/rests.xml | 27 ++
.../src/test/resources/routes-with-beans.yaml | 31 ++
.../src/test/resources/routes-with-expression.xml | 28 ++
.../camel-k-runtime/src/test/resources/routes.xml | 25 +
integration-tests/pom.xml | 1 +
pom.xml | 4 +
poms/bom-test/pom.xml | 10 +
poms/bom/pom.xml | 54 ++-
poms/bom/src/main/generated/flattened-full-pom.xml | 79 ++--
.../src/main/generated/flattened-reduced-pom.xml | 24 +-
.../generated/flattened-reduced-verbose-pom.xml | 24 +-
tooling/camel-k-catalog-model/pom.xml | 96 ++++
.../camel/quarkus/k/catalog/model/Artifact.java | 59 +++
.../quarkus/k/catalog/model/CamelArtifact.java | 82 ++++
.../quarkus/k/catalog/model/CamelCapability.java | 47 ++
.../camel/quarkus/k/catalog/model/CamelLoader.java | 62 +++
.../camel/quarkus/k/catalog/model/CamelScheme.java | 66 +++
.../k/catalog/model/CamelScopedArtifact.java | 50 ++
.../catalog/model/CatalogComponentDefinition.java | 80 ++++
.../catalog/model/CatalogDataFormatDefinition.java | 58 +++
.../quarkus/k/catalog/model/CatalogDefinition.java | 47 ++
.../k/catalog/model/CatalogLanguageDefinition.java | 58 +++
.../k/catalog/model/CatalogOtherDefinition.java | 49 ++
.../quarkus/k/catalog/model/CatalogSupport.java | 51 ++
.../quarkus/k/catalog/model/k8s/ObjectMeta.java | 38 ++
.../quarkus/k/catalog/model/k8s/TypeMeta.java | 37 ++
.../k/catalog/model/k8s/crd/CamelCatalog.java | 44 ++
.../k/catalog/model/k8s/crd/CamelCatalogSpec.java | 56 +++
.../k/catalog/model/k8s/crd/RuntimeSpec.java | 63 +++
tooling/camel-k-maven-plugin/pom.xml | 266 +++++++++++
.../it/generate-catalog-with-exclusions/pom.xml | 110 +++++
.../generate-catalog-with-exclusions/verify.groovy | 40 ++
.../src/it/generate-catalog/pom.xml | 104 +++++
.../src/it/generate-catalog/verify.groovy | 121 +++++
.../src/it/generate-dependencies/pom.xml | 107 +++++
.../src/it/generate-dependencies/verify.groovy | 46 ++
.../src/it/generate-rest-dsl-from-v2/document.json | 46 ++
.../src/it/generate-rest-dsl-from-v2/pom.xml | 102 ++++
.../src/it/generate-rest-dsl-from-v2/verify.groovy | 27 ++
.../src/it/generate-rest-dsl-from-v3/document.yaml | 128 ++++++
.../src/it/generate-rest-dsl-from-v3/pom.xml | 102 ++++
.../src/it/generate-rest-dsl-from-v3/verify.groovy | 29 ++
.../k/tooling/maven/GenerateCatalogMojo.java | 512 +++++++++++++++++++++
.../tooling/maven/GenerateDependencyListMojo.java | 132 ++++++
.../quarkus/k/tooling/maven/GenerateRestXML.java | 102 ++++
.../quarkus/k/tooling/maven/GenerateSupport.java | 38 ++
.../k/tooling/maven/support/MavenSupport.java | 120 +++++
.../src/main/resources/app.properties | 18 +
.../src/main/resources/catalog-license.txt | 17 +
tooling/pom.xml | 2 +
tooling/scripts/test-categories.yaml | 1 +
130 files changed, 8752 insertions(+), 67 deletions(-)
diff --git a/catalog/pom.xml b/catalog/pom.xml
index 412865d5db..aeff08564c 100644
--- a/catalog/pom.xml
+++ b/catalog/pom.xml
@@ -695,6 +695,19 @@
</exclusion>
</exclusions>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-camel-k</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-cassandraql</artifactId>
@@ -4313,6 +4326,7 @@
<configuration>
<skipArtifactIdBases>
<skipArtifactIdBase>http-common</skipArtifactIdBase>
+ <skipArtifactIdBase>camel-k</skipArtifactIdBase>
<skipArtifactIdBase>support-.*</skipArtifactIdBase>
<skipArtifactIdBase>integration-tests?-support-.*</skipArtifactIdBase>
</skipArtifactIdBases>
diff --git a/extensions/camel-k/deployment/pom.xml b/extensions/camel-k/deployment/pom.xml
new file mode 100644
index 0000000000..3aabc908b1
--- /dev/null
+++ b/extensions/camel-k/deployment/pom.xml
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-camel-k-parent</artifactId>
+ <version>3.3.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>camel-quarkus-camel-k-deployment</artifactId>
+ <name>Camel Quarkus :: Camel K :: Deployment</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-core-deployment</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-camel-k</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-kubernetes-deployment</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-bean-deployment</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-junit5-internal</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>io.rest-assured</groupId>
+ <artifactId>rest-assured</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-resteasy</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-groovy-dsl</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-java-joor-dsl</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-js-dsl</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-jsh-dsl</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-kotlin-dsl</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-yaml-dsl</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-xml-io-dsl</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-direct</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-jackson</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-log</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-jsonb</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-resteasy-jsonb</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <annotationProcessorPaths>
+ <path>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-extension-processor</artifactId>
+ <version>${quarkus.version}</version>
+ </path>
+ </annotationProcessorPaths>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/extensions/camel-k/deployment/src/main/java/org/apache/camel/quarkus/k/deployment/RuntimeFeature.java b/extensions/camel-k/deployment/src/main/java/org/apache/camel/quarkus/k/deployment/RuntimeFeature.java
new file mode 100644
index 0000000000..be92d4ebf4
--- /dev/null
+++ b/extensions/camel-k/deployment/src/main/java/org/apache/camel/quarkus/k/deployment/RuntimeFeature.java
@@ -0,0 +1,29 @@
+/*
+ * 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.quarkus.k.deployment;
+
+import io.quarkus.deployment.annotations.BuildStep;
+import io.quarkus.deployment.builditem.FeatureBuildItem;
+
+public class RuntimeFeature {
+ private static final String FEATURE = "camel-k-runtime";
+
+ @BuildStep
+ FeatureBuildItem feature() {
+ return new FeatureBuildItem(FEATURE);
+ }
+}
diff --git a/extensions/camel-k/deployment/src/main/java/org/apache/camel/quarkus/k/deployment/RuntimeProcessor.java b/extensions/camel-k/deployment/src/main/java/org/apache/camel/quarkus/k/deployment/RuntimeProcessor.java
new file mode 100644
index 0000000000..02c674f4ef
--- /dev/null
+++ b/extensions/camel-k/deployment/src/main/java/org/apache/camel/quarkus/k/deployment/RuntimeProcessor.java
@@ -0,0 +1,144 @@
+/*
+ * 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.quarkus.k.deployment;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ServiceLoader;
+import java.util.stream.Collectors;
+
+import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
+import io.quarkus.arc.deployment.BeanContainerBuildItem;
+import io.quarkus.arc.deployment.SyntheticBeansRuntimeInitBuildItem;
+import io.quarkus.deployment.annotations.BuildProducer;
+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.CombinedIndexBuildItem;
+import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
+import io.quarkus.deployment.builditem.nativeimage.ServiceProviderBuildItem;
+import org.apache.camel.builder.RouteBuilderLifecycleStrategy;
+import org.apache.camel.quarkus.core.deployment.main.spi.CamelMainBuildItem;
+import org.apache.camel.quarkus.core.deployment.main.spi.CamelMainListenerBuildItem;
+import org.apache.camel.quarkus.core.deployment.main.spi.CamelRoutesCollectorBuildItem;
+import org.apache.camel.quarkus.core.deployment.spi.CamelRuntimeTaskBuildItem;
+import org.apache.camel.quarkus.core.deployment.spi.CamelServiceDestination;
+import org.apache.camel.quarkus.core.deployment.spi.CamelServicePatternBuildItem;
+import org.apache.camel.quarkus.k.core.Runtime;
+import org.apache.camel.quarkus.k.core.SourceDefinition;
+import org.apache.camel.quarkus.k.runtime.ApplicationProducers;
+import org.apache.camel.quarkus.k.runtime.ApplicationRecorder;
+import org.apache.camel.quarkus.k.support.Constants;
+import org.apache.camel.quarkus.k.support.RuntimeSupport;
+import org.apache.camel.spi.CamelContextCustomizer;
+import org.apache.camel.spi.StreamCachingStrategy;
+import org.jboss.jandex.IndexView;
+
+import static org.apache.camel.quarkus.k.deployment.support.DeploymentSupport.getAllKnownImplementors;
+import static org.apache.camel.quarkus.k.deployment.support.DeploymentSupport.reflectiveClassBuildItem;
+import static org.apache.camel.quarkus.k.deployment.support.DeploymentSupport.stream;
+
+public class RuntimeProcessor {
+
+ @Record(ExecutionTime.STATIC_INIT)
+ @BuildStep
+ CamelMainListenerBuildItem mainListener(ApplicationRecorder recorder) {
+ List<Runtime.Listener> listeners = new ArrayList<>();
+ ServiceLoader.load(Runtime.Listener.class).forEach(listeners::add);
+
+ return new CamelMainListenerBuildItem(recorder.createMainListener(listeners));
+ }
+
+ @Record(ExecutionTime.STATIC_INIT)
+ @BuildStep
+ CamelRoutesCollectorBuildItem routesCollector(ApplicationRecorder recorder) {
+ return new CamelRoutesCollectorBuildItem(recorder.createRoutesCollector());
+ }
+
+ @Record(ExecutionTime.RUNTIME_INIT)
+ @BuildStep
+ @Consume(SyntheticBeansRuntimeInitBuildItem.class)
+ CamelRuntimeTaskBuildItem registerRuntime(
+ ApplicationRecorder recorder,
+ CamelMainBuildItem camelMain,
+ BeanContainerBuildItem beanContainer) {
+
+ recorder.publishRuntime(camelMain.getInstance(), beanContainer.getValue());
+ recorder.version(RuntimeSupport.getRuntimeVersion());
+
+ return new CamelRuntimeTaskBuildItem("camel-k-runtime");
+ }
+
+ @BuildStep
+ List<AdditionalBeanBuildItem> unremovableBeans() {
+ return List.of(
+ AdditionalBeanBuildItem.unremovableOf(ApplicationProducers.class));
+ }
+
+ @BuildStep
+ List<CamelServicePatternBuildItem> servicePatterns() {
+ return List.of(
+ new CamelServicePatternBuildItem(
+ CamelServiceDestination.REGISTRY,
+ true,
+ Constants.CONTEXT_CUSTOMIZER_RESOURCE_PATH + "/*"),
+ new CamelServicePatternBuildItem(
+ CamelServiceDestination.DISCOVERY,
+ true,
+ Constants.SOURCE_LOADER_INTERCEPTOR_RESOURCE_PATH + "/*"));
+ }
+
+ @BuildStep
+ List<ReflectiveClassBuildItem> registerClasses(CombinedIndexBuildItem index) {
+ return List.of(
+ ReflectiveClassBuildItem.builder(SourceDefinition.class).methods().fields(false).build(),
+ reflectiveClassBuildItem(getAllKnownImplementors(index.getIndex(), CamelContextCustomizer.class)),
+ reflectiveClassBuildItem(getAllKnownImplementors(index.getIndex(), RouteBuilderLifecycleStrategy.class)));
+ }
+
+ @BuildStep
+ List<ServiceProviderBuildItem> registerServices(CombinedIndexBuildItem combinedIndexBuildItem) {
+ final IndexView view = combinedIndexBuildItem.getIndex();
+ final String serviceType = "org.apache.camel.quarkus.k.core.Runtime$Listener";
+ return stream(getAllKnownImplementors(view, serviceType))
+ .map(i -> new ServiceProviderBuildItem(serviceType, i.name().toString()))
+ .collect(Collectors.toList());
+ }
+
+ @BuildStep
+ void registerStreamCachingClasses(BuildProducer<ReflectiveClassBuildItem> reflectiveClass,
+ CombinedIndexBuildItem combinedIndex) {
+
+ final IndexView view = combinedIndex.getIndex();
+
+ getAllKnownImplementors(view, StreamCachingStrategy.class)
+ .forEach(i -> reflectiveClass.produce(reflectiveClassBuildItem(i)));
+
+ getAllKnownImplementors(view, StreamCachingStrategy.Statistics.class)
+ .forEach(i -> reflectiveClass.produce(reflectiveClassBuildItem(i)));
+
+ getAllKnownImplementors(view, StreamCachingStrategy.SpoolRule.class)
+ .forEach(i -> reflectiveClass.produce(reflectiveClassBuildItem(i)));
+
+ reflectiveClass.produce(
+ ReflectiveClassBuildItem.builder("StreamCachingStrategy.SpoolRule.class")
+ .methods()
+ .fields()
+ .build());
+ }
+}
diff --git a/extensions/camel-k/deployment/src/main/java/org/apache/camel/quarkus/k/deployment/devmode/HotDeploymentProcessor.java b/extensions/camel-k/deployment/src/main/java/org/apache/camel/quarkus/k/deployment/devmode/HotDeploymentProcessor.java
new file mode 100644
index 0000000000..8777938ca5
--- /dev/null
+++ b/extensions/camel-k/deployment/src/main/java/org/apache/camel/quarkus/k/deployment/devmode/HotDeploymentProcessor.java
@@ -0,0 +1,115 @@
+/*
+ * 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.quarkus.k.deployment.devmode;
+
+import java.io.IOException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.FileVisitor;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+
+import io.quarkus.deployment.annotations.BuildStep;
+import io.quarkus.deployment.builditem.HotDeploymentWatchedFileBuildItem;
+import org.apache.camel.quarkus.k.support.Constants;
+import org.apache.camel.util.StringHelper;
+import org.apache.commons.io.FilenameUtils;
+import org.eclipse.microprofile.config.Config;
+import org.eclipse.microprofile.config.ConfigProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class HotDeploymentProcessor {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(HotDeploymentProcessor.class);
+
+ @BuildStep
+ List<HotDeploymentWatchedFileBuildItem> routes() {
+ final Config config = ConfigProvider.getConfig();
+ final Optional<String> value = config.getOptionalValue(Constants.PROPERTY_CAMEL_K_ROUTES, String.class);
+
+ List<HotDeploymentWatchedFileBuildItem> items = new ArrayList<>();
+
+ if (value.isPresent()) {
+ for (String source : value.get().split(",", -1)) {
+ String path = StringHelper.after(source, ":");
+ if (path == null) {
+ path = source;
+ }
+
+ Path p = Paths.get(path);
+ if (Files.exists(p)) {
+ LOGGER.info("Register source for hot deployment: {}", p.toAbsolutePath());
+ items.add(new HotDeploymentWatchedFileBuildItem(p.toAbsolutePath().toString()));
+ }
+ }
+ }
+
+ return items;
+ }
+
+ @BuildStep
+ List<HotDeploymentWatchedFileBuildItem> conf() {
+ final Config config = ConfigProvider.getConfig();
+ final Optional<String> conf = config.getOptionalValue(Constants.PROPERTY_CAMEL_K_CONF, String.class);
+ final Optional<String> confd = config.getOptionalValue(Constants.PROPERTY_CAMEL_K_CONF_D, String.class);
+
+ List<HotDeploymentWatchedFileBuildItem> items = new ArrayList<>();
+
+ if (conf.isPresent()) {
+ LOGGER.info("Register conf for hot deployment: {}", conf.get());
+ items.add(new HotDeploymentWatchedFileBuildItem(conf.get()));
+ }
+
+ if (confd.isPresent()) {
+ FileVisitor<Path> visitor = new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+ Objects.requireNonNull(file);
+ Objects.requireNonNull(attrs);
+
+ String path = file.toFile().getAbsolutePath();
+ String ext = FilenameUtils.getExtension(path);
+
+ if (Objects.equals("properties", ext)) {
+ LOGGER.info("Register conf for hot deployment: {}", path);
+ items.add(new HotDeploymentWatchedFileBuildItem(path));
+ }
+
+ return FileVisitResult.CONTINUE;
+ }
+ };
+
+ Path root = Paths.get(confd.get());
+ if (Files.exists(root)) {
+ try {
+ Files.walkFileTree(root, visitor);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ return items;
+ }
+}
diff --git a/extensions/camel-k/deployment/src/main/java/org/apache/camel/quarkus/k/deployment/support/DeploymentSupport.java b/extensions/camel-k/deployment/src/main/java/org/apache/camel/quarkus/k/deployment/support/DeploymentSupport.java
new file mode 100644
index 0000000000..9f9e744fdb
--- /dev/null
+++ b/extensions/camel-k/deployment/src/main/java/org/apache/camel/quarkus/k/deployment/support/DeploymentSupport.java
@@ -0,0 +1,61 @@
+/*
+ * 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.quarkus.k.deployment.support;
+
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
+import org.jboss.jandex.ClassInfo;
+import org.jboss.jandex.DotName;
+import org.jboss.jandex.IndexView;
+
+public final class DeploymentSupport {
+
+ private DeploymentSupport() {
+ }
+
+ public static Iterable<ClassInfo> getAllKnownImplementors(IndexView view, String name) {
+ return view.getAllKnownImplementors(DotName.createSimple(name));
+ }
+
+ public static Iterable<ClassInfo> getAllKnownImplementors(IndexView view, Class<?> type) {
+ return getAllKnownImplementors(view, type.getName());
+ }
+
+ public static ReflectiveClassBuildItem reflectiveClassBuildItem(ClassInfo... classInfos) {
+ return classInfos.length == 1
+ ? ReflectiveClassBuildItem.builder(classInfos[0].name().toString()).methods().fields(false).build()
+ : ReflectiveClassBuildItem.builder(Stream.of(classInfos)
+ .map(ClassInfo::name)
+ .map(DotName::toString)
+ .toArray(String[]::new))
+ .methods().fields(false).build();
+ }
+
+ public static ReflectiveClassBuildItem reflectiveClassBuildItem(Iterable<ClassInfo> classInfos) {
+ return ReflectiveClassBuildItem.builder(stream(classInfos)
+ .map(ClassInfo::name)
+ .map(DotName::toString)
+ .toArray(String[]::new))
+ .methods().fields(false).build();
+ }
+
+ public static <T> Stream<T> stream(Iterable<T> iterable) {
+ return StreamSupport.stream(iterable.spliterator(), false);
+ }
+}
diff --git a/extensions/camel-k/deployment/src/test/java/org/apache/camel/quarkus/k/deployment/LoaderTest.java b/extensions/camel-k/deployment/src/test/java/org/apache/camel/quarkus/k/deployment/LoaderTest.java
new file mode 100644
index 0000000000..5d398f4f54
--- /dev/null
+++ b/extensions/camel-k/deployment/src/test/java/org/apache/camel/quarkus/k/deployment/LoaderTest.java
@@ -0,0 +1,335 @@
+/*
+ * 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.quarkus.k.deployment;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Collection;
+import java.util.ServiceLoader;
+
+import io.quarkus.test.QuarkusUnitTest;
+import io.restassured.RestAssured;
+import io.restassured.path.json.JsonPath;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
+import jakarta.json.Json;
+import jakarta.json.JsonArrayBuilder;
+import jakarta.json.JsonObject;
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.core.MediaType;
+import org.apache.camel.CamelContext;
+import org.apache.camel.ExtendedCamelContext;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.quarkus.k.core.Runtime;
+import org.apache.camel.quarkus.k.listener.ContextConfigurer;
+import org.apache.camel.quarkus.k.listener.SourcesConfigurer;
+import org.apache.camel.spi.RoutesLoader;
+import org.apache.camel.support.PluginHelper;
+import org.apache.camel.support.ResourceHelper;
+import org.apache.camel.util.IOHelper;
+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;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class LoaderTest {
+ @RegisterExtension
+ public static final QuarkusUnitTest test = new QuarkusUnitTest()
+ .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
+ .addClasses(Application.class, LoaderSupport.class)
+ .addAsResource("MyRoutes.java")
+ .addAsResource("routes.groovy")
+ .addAsResource("routes.js")
+ .addAsResource("routes.jsh")
+ .addAsResource("routes.kts")
+ .addAsResource("routes.xml")
+ .addAsResource("routes.yaml"))
+ .overrideConfigKey("quarkus.camel.routes-discovery.enabled", "false");
+
+ @Test
+ public void testServices() {
+ JsonPath p = RestAssured.given()
+ .accept(MediaType.APPLICATION_JSON)
+ .get("/camel-k/loader/services")
+ .then()
+ .statusCode(200)
+ .extract()
+ .body()
+ .jsonPath();
+
+ assertThat(p.getList("services", String.class)).contains(
+ ContextConfigurer.class.getName(),
+ SourcesConfigurer.class.getName());
+ }
+
+ @Test
+ public void testLoadGroovyRoutes() throws IOException {
+ String code;
+ try (InputStream is = LoaderTest.class.getResourceAsStream("/routes.groovy")) {
+ code = IOHelper.loadText(is);
+ }
+
+ JsonPath p = RestAssured.given()
+ .contentType(MediaType.TEXT_PLAIN)
+ .accept(MediaType.APPLICATION_JSON)
+ .body(code)
+ .post("/camel-k/loader/load-routes/groovy/MyRoute")
+ .then()
+ .statusCode(200)
+ .extract()
+ .body()
+ .jsonPath();
+
+ assertThat(p.getList("components", String.class)).contains("direct", "log");
+ assertThat(p.getList("routes", String.class)).contains("groovy");
+ assertThat(p.getList("endpoints", String.class)).contains("direct://groovy", "log://groovy");
+ }
+
+ @Test
+ public void testLoadJavaRoutes() throws IOException {
+ String code;
+
+ try (InputStream is = LoaderTest.class.getResourceAsStream("/MyRoutes.java")) {
+ code = IOHelper.loadText(is);
+ }
+
+ JsonPath p = RestAssured.given()
+ .contentType(MediaType.TEXT_PLAIN)
+ .accept(MediaType.APPLICATION_JSON)
+ .body(code)
+ .post("/camel-k/loader/load-routes/java/MyRoutes")
+ .then()
+ .statusCode(200)
+ .extract()
+ .body()
+ .jsonPath();
+
+ assertThat(p.getList("components", String.class)).contains("direct", "log");
+ assertThat(p.getList("routes", String.class)).contains("java");
+ assertThat(p.getList("endpoints", String.class)).contains("direct://java", "log://java");
+ }
+
+ @Test
+ public void testLoadJavascriptRoutes() throws IOException {
+ String code;
+
+ try (InputStream is = LoaderTest.class.getResourceAsStream("/routes.js")) {
+ code = IOHelper.loadText(is);
+ }
+
+ JsonPath p = RestAssured.given()
+ .contentType(MediaType.TEXT_PLAIN)
+ .accept(MediaType.APPLICATION_JSON)
+ .body(code)
+ .post("/camel-k/loader/load-routes/js/MyRoute")
+ .then()
+ .statusCode(200)
+ .extract()
+ .body()
+ .jsonPath();
+
+ assertThat(p.getList("components", String.class)).contains("direct", "log");
+ assertThat(p.getList("routes", String.class)).contains("js");
+ assertThat(p.getList("endpoints", String.class)).contains("direct://js", "log://js");
+ }
+
+ @Test
+ public void testLoadJshRoutes() throws IOException {
+ String code;
+
+ try (InputStream is = LoaderTest.class.getResourceAsStream("/routes.jsh")) {
+ code = IOHelper.loadText(is);
+ }
+
+ JsonPath p = RestAssured.given()
+ .contentType(MediaType.TEXT_PLAIN)
+ .accept(MediaType.APPLICATION_JSON)
+ .body(code)
+ .post("/camel-k/loader/load-routes/jsh/routes")
+ .then()
+ .statusCode(200)
+ .extract()
+ .body()
+ .jsonPath();
+
+ assertThat(p.getList("components", String.class)).contains("direct", "log");
+ assertThat(p.getList("routes", String.class)).contains("jsh");
+ assertThat(p.getList("endpoints", String.class)).contains("direct://jsh", "log://jsh");
+ }
+
+ @Test
+ public void testLoadKotlinRoutes() throws IOException {
+
+ String code;
+
+ try (InputStream is = LoaderTest.class.getResourceAsStream("/routes.kts")) {
+ code = IOHelper.loadText(is);
+ }
+
+ JsonPath p = RestAssured.given()
+ .contentType(MediaType.TEXT_PLAIN)
+ .accept(MediaType.APPLICATION_JSON)
+ .body(code)
+ .post("/camel-k/loader/load-routes/kts/MyRoute")
+ .then()
+ .statusCode(200)
+ .extract()
+ .body()
+ .jsonPath();
+
+ assertThat(p.getList("components", String.class)).contains("direct", "log");
+ assertThat(p.getList("routes", String.class)).contains("kotlin");
+ assertThat(p.getList("endpoints", String.class)).contains("direct://kotlin", "log://kotlin");
+ }
+
+ @Test
+ public void testLoadXmlRoutes() throws IOException {
+ String code;
+
+ try (InputStream is = LoaderTest.class.getResourceAsStream("/routes.xml")) {
+ code = IOHelper.loadText(is);
+ }
+
+ JsonPath p = RestAssured.given()
+ .contentType(MediaType.TEXT_PLAIN)
+ .accept(MediaType.APPLICATION_JSON)
+ .body(code)
+ .post("/camel-k/loader/load-routes/xml/MyRoute")
+ .then()
+ .statusCode(200)
+ .extract()
+ .body()
+ .jsonPath();
+
+ assertThat(p.getList("components", String.class)).contains("direct", "log");
+ assertThat(p.getList("routes", String.class)).contains("xml");
+ assertThat(p.getList("endpoints", String.class)).contains("direct://xml", "log://xml");
+ }
+
+ @Test
+ public void testLoadYamlRoutes() throws IOException {
+ String code;
+
+ try (InputStream is = LoaderTest.class.getResourceAsStream("/routes.yaml")) {
+ code = IOHelper.loadText(is);
+ }
+
+ JsonPath p = RestAssured.given()
+ .contentType(MediaType.TEXT_PLAIN)
+ .accept(MediaType.APPLICATION_JSON)
+ .body(code)
+ .post("/camel-k/loader/load-routes/yaml/MyRoute")
+ .then()
+ .statusCode(200)
+ .extract()
+ .body()
+ .jsonPath();
+
+ assertThat(p.getList("components", String.class)).contains("direct", "log");
+ assertThat(p.getList("routes", String.class)).contains("yaml");
+ assertThat(p.getList("endpoints", String.class)).contains("direct://yaml", "log://yaml");
+ }
+
+ @Path("/camel-k/loader")
+ @ApplicationScoped
+ public static class Application {
+
+ @Inject
+ CamelContext context;
+
+ // k-core
+ @GET
+ @Path("/services")
+ @Produces(MediaType.APPLICATION_JSON)
+ public JsonObject getServices() {
+ JsonArrayBuilder builder = Json.createArrayBuilder();
+
+ ServiceLoader.load(Runtime.Listener.class).forEach(listener -> {
+ builder.add(listener.getClass().getName());
+ });
+
+ return Json.createObjectBuilder()
+ .add("services", builder)
+ .build();
+ }
+
+ @POST
+ @Path("/load-routes/{loaderName}/{name}")
+ @Consumes(MediaType.TEXT_PLAIN)
+ @Produces(MediaType.APPLICATION_JSON)
+ public JsonObject loadRoutes(@PathParam("loaderName") String loaderName, @PathParam("name") String name, byte[] code)
+ throws Exception {
+ return LoaderSupport.inspectSource(context, name + "." + loaderName, code);
+ }
+ }
+
+ static final class LoaderSupport {
+ private LoaderSupport() {
+ }
+
+ public static JsonObject inspectSource(CamelContext context, String location, byte[] code) throws Exception {
+ final Runtime runtime = Runtime.on(context);
+ final ExtendedCamelContext ecc = runtime.getExtendedCamelContext();
+ final RoutesLoader loader = PluginHelper.getRoutesLoader(ecc);
+ final Collection<RoutesBuilder> builders = loader.findRoutesBuilders(ResourceHelper.fromBytes(location, code));
+
+ for (RoutesBuilder builder : builders) {
+ runtime.addRoutes(builder);
+ }
+
+ return Json.createObjectBuilder()
+ .add("components", extractComponents(context))
+ .add("routes", extractRoutes(context))
+ .add("endpoints", extractEndpoints(context))
+ .build();
+ }
+
+ public static JsonObject inspectSource(CamelContext context, String location, String code) throws Exception {
+ return inspectSource(context, location, code.getBytes(StandardCharsets.UTF_8));
+ }
+
+ public static JsonArrayBuilder extractComponents(CamelContext context) {
+ JsonArrayBuilder answer = Json.createArrayBuilder();
+ context.getComponentNames().forEach(answer::add);
+
+ return answer;
+ }
+
+ public static JsonArrayBuilder extractRoutes(CamelContext context) {
+ JsonArrayBuilder answer = Json.createArrayBuilder();
+ context.getRoutes().forEach(r -> answer.add(r.getId()));
+
+ return answer;
+ }
+
+ public static JsonArrayBuilder extractEndpoints(CamelContext context) {
+ JsonArrayBuilder answer = Json.createArrayBuilder();
+ context.getEndpoints().forEach(e -> answer.add(e.getEndpointUri()));
+
+ return answer;
+ }
+ }
+
+}
diff --git a/extensions/camel-k/deployment/src/test/resources/MyRoutes.java b/extensions/camel-k/deployment/src/test/resources/MyRoutes.java
new file mode 100644
index 0000000000..d305e3e2d5
--- /dev/null
+++ b/extensions/camel-k/deployment/src/test/resources/MyRoutes.java
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+import org.apache.camel.builder.RouteBuilder;
+
+public class MyRoutes extends RouteBuilder {
+ @Override
+ public void configure() throws Exception {
+ from("direct:java")
+ .routeId("java")
+ .to("log:java");
+ }
+}
\ No newline at end of file
diff --git a/extensions/camel-k/deployment/src/test/resources/routes.groovy b/extensions/camel-k/deployment/src/test/resources/routes.groovy
new file mode 100644
index 0000000000..a96deb2378
--- /dev/null
+++ b/extensions/camel-k/deployment/src/test/resources/routes.groovy
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+from('direct:groovy')
+ .routeId('groovy')
+ .to('log:groovy')
\ No newline at end of file
diff --git a/extensions/camel-k/deployment/src/test/resources/routes.js b/extensions/camel-k/deployment/src/test/resources/routes.js
new file mode 100644
index 0000000000..414fe0a798
--- /dev/null
+++ b/extensions/camel-k/deployment/src/test/resources/routes.js
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+from('direct:js')
+ .routeId('js')
+ .to('log:js')
\ No newline at end of file
diff --git a/extensions/camel-k/deployment/src/test/resources/routes.jsh b/extensions/camel-k/deployment/src/test/resources/routes.jsh
new file mode 100644
index 0000000000..c47a78f30f
--- /dev/null
+++ b/extensions/camel-k/deployment/src/test/resources/routes.jsh
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+
+builder.from("direct:jsh")
+ .routeId("jsh")
+ .to("log:jsh");
diff --git a/extensions/camel-k/deployment/src/test/resources/routes.kts b/extensions/camel-k/deployment/src/test/resources/routes.kts
new file mode 100644
index 0000000000..fba70eee0b
--- /dev/null
+++ b/extensions/camel-k/deployment/src/test/resources/routes.kts
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+from("direct:kotlin")
+ .routeId("kotlin")
+ .to("log:kotlin")
\ No newline at end of file
diff --git a/extensions/camel-k/deployment/src/test/resources/routes.xml b/extensions/camel-k/deployment/src/test/resources/routes.xml
new file mode 100644
index 0000000000..2bb35d9d4d
--- /dev/null
+++ b/extensions/camel-k/deployment/src/test/resources/routes.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://camel.apache.org/schema/spring"
+ xsi:schemaLocation="
+ http://camel.apache.org/schema/spring
+ http://camel.apache.org/schema/spring/camel-spring.xsd">
+
+ <route id="xml">
+ <from uri="direct:xml"/>
+ <marshal>
+ <json/>
+ </marshal>
+ <to uri="log:xml"/>
+ </route>
+
+</routes>
\ No newline at end of file
diff --git a/extensions/camel-k/deployment/src/test/resources/routes.yaml b/extensions/camel-k/deployment/src/test/resources/routes.yaml
new file mode 100644
index 0000000000..be866f3300
--- /dev/null
+++ b/extensions/camel-k/deployment/src/test/resources/routes.yaml
@@ -0,0 +1,25 @@
+#
+# 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.
+#
+
+- route:
+ id: yaml
+ from:
+ uri: 'direct:yaml'
+ steps:
+ - marshal:
+ json: {}
+ - to: 'log:yaml'
diff --git a/tooling/pom.xml b/extensions/camel-k/pom.xml
similarity index 60%
copy from tooling/pom.xml
copy to extensions/camel-k/pom.xml
index 748afb2770..ac3fcb2213 100644
--- a/tooling/pom.xml
+++ b/extensions/camel-k/pom.xml
@@ -19,37 +19,19 @@
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
-
<parent>
<groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus</artifactId>
+ <artifactId>camel-quarkus-extensions</artifactId>
<version>3.3.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
</parent>
- <artifactId>camel-quarkus-tooling</artifactId>
+ <artifactId>camel-quarkus-camel-k-parent</artifactId>
+ <name>Camel Quarkus :: Camel K</name>
<packaging>pom</packaging>
- <name>Camel Quarkus :: Tooling</name>
- <description>Camel Quarkus Tooling Parent POM</description>
-
<modules>
- <module>maven-plugin</module>
- <module>perf-regression</module>
- <module>test-list</module>
+ <module>deployment</module>
+ <module>runtime</module>
</modules>
-
- <dependencyManagement>
- <dependencies>
- <dependency>
- <groupId>com.google.code.gson</groupId>
- <artifactId>gson</artifactId>
- <version>${gson.version}</version>
- </dependency>
- <dependency>
- <groupId>org.freemarker</groupId>
- <artifactId>freemarker</artifactId>
- <version>${freemarker.version}</version>
- </dependency>
- </dependencies>
- </dependencyManagement>
</project>
diff --git a/extensions/camel-k/runtime/pom.xml b/extensions/camel-k/runtime/pom.xml
new file mode 100644
index 0000000000..06c5018bd8
--- /dev/null
+++ b/extensions/camel-k/runtime/pom.xml
@@ -0,0 +1,214 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-camel-k-parent</artifactId>
+ <version>3.3.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>camel-quarkus-camel-k</artifactId>
+ <name>Camel Quarkus :: Camel K :: Runtime</name>
+ <description>Camel runtime specialization for Camel K</description>
+
+ <properties>
+ <camel.quarkus.jvmSince>3.3.0</camel.quarkus.jvmSince>
+ <camel.quarkus.nativeSince>3.3.0</camel.quarkus.nativeSince>
+ <quarkus.metadata.unlisted>true</quarkus.metadata.unlisted>
+ <camel-quarkus.update-extension-doc-page.skip>true</camel-quarkus.update-extension-doc-page.skip>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-arc</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-bean</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-core-engine</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-core-languages</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-endpointdsl</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-util</artifactId>
+ </dependency>
+ <!-- The camel-quarkus-kubernetes is required for the kubernetes property resolver -->
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-kubernetes</artifactId>
+ </dependency>
+
+
+ <!-- Tests -->
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-junit5-internal</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-base-engine</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.jboss.jandex</groupId>
+ <artifactId>jandex-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>make-index</id>
+ <goals>
+ <goal>jandex</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-package-maven-plugin</artifactId>
+ <version>${camel.version}</version>
+ <executions>
+ <execution>
+ <id>generate-configurer</id>
+ <phase>process-classes</phase>
+ <goals>
+ <goal>generate-configurer</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>add-source</goal>
+ <goal>add-resource</goal>
+ </goals>
+ <configuration>
+ <sources>
+ <source>src/generated/java</source>
+ </sources>
+ <resources>
+ <resource>
+ <directory>src/generated/resources</directory>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-extension-maven-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <annotationProcessorPaths>
+ <path>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-extension-processor</artifactId>
+ <version>${quarkus.version}</version>
+ </path>
+ </annotationProcessorPaths>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <environmentVariables>
+ <CAMEL_K_RESOURCE_001>my env content</CAMEL_K_RESOURCE_001>
+ <MY_ENV_RESOURCE_TXT>env:CAMEL_K_RESOURCE_001</MY_ENV_RESOURCE_TXT>
+ <CAMEL_K_RESOURCE_002>H4sIAFlah1wAA8utVEjOzy0oSi0uTk1RSM0rA3LzSlLzSrgAUbkzGRoAAAA=</CAMEL_K_RESOURCE_002>
+ <MY_COMPRESSED_ENV_RESOURCE_TXT>env:CAMEL_K_RESOURCE_002?compression=true</MY_COMPRESSED_ENV_RESOURCE_TXT>
+ </environmentVariables>
+ <systemPropertyVariables>
+ <root>${project.basedir}</root>
+ <camel.k.mount-path.configmaps>${project.basedir}/src/test/resources/configmaps</camel.k.mount-path.configmaps>
+ <camel.k.mount-path.secrets>${project.basedir}/src/test/resources/secrets</camel.k.mount-path.secrets>
+ <camel.kubernetes-config.client-enabled>false</camel.kubernetes-config.client-enabled>
+ </systemPropertyVariables>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>full</id>
+ <activation>
+ <property>
+ <name>!quickly</name>
+ </property>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>update-extension-doc-page</id>
+ <goals>
+ <goal>update-extension-doc-page</goal>
+ </goals>
+ <phase>process-classes</phase>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
diff --git a/extensions/camel-k/runtime/src/generated/java/org/apache/camel/quarkus/k/core/SourceDefinitionConfigurer.java b/extensions/camel-k/runtime/src/generated/java/org/apache/camel/quarkus/k/core/SourceDefinitionConfigurer.java
new file mode 100644
index 0000000000..be4f0d7a7f
--- /dev/null
+++ b/extensions/camel-k/runtime/src/generated/java/org/apache/camel/quarkus/k/core/SourceDefinitionConfigurer.java
@@ -0,0 +1,114 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.quarkus.k.core;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.quarkus.k.core.SourceDefinition;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class SourceDefinitionConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+ @Override
+ public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+ org.apache.camel.quarkus.k.core.SourceDefinition target = (org.apache.camel.quarkus.k.core.SourceDefinition) obj;
+ switch (ignoreCase ? name.toLowerCase() : name) {
+ case "compressed":
+ case "Compressed": target.setCompressed(property(camelContext, boolean.class, value)); return true;
+ case "content":
+ case "Content": target.setContent(property(camelContext, byte[].class, value)); return true;
+ case "id":
+ case "Id": target.setId(property(camelContext, java.lang.String.class, value)); return true;
+ case "interceptors":
+ case "Interceptors": target.setInterceptors(property(camelContext, java.util.List.class, value)); return true;
+ case "language":
+ case "Language": target.setLanguage(property(camelContext, java.lang.String.class, value)); return true;
+ case "loader":
+ case "Loader": target.setLoader(property(camelContext, java.lang.String.class, value)); return true;
+ case "location":
+ case "Location": target.setLocation(property(camelContext, java.lang.String.class, value)); return true;
+ case "name":
+ case "Name": target.setName(property(camelContext, java.lang.String.class, value)); return true;
+ case "propertynames":
+ case "PropertyNames": target.setPropertyNames(property(camelContext, java.util.List.class, value)); return true;
+ case "type":
+ case "Type": target.setType(property(camelContext, org.apache.camel.quarkus.k.core.SourceType.class, value)); return true;
+ default: return false;
+ }
+ }
+
+ @Override
+ public Class<?> getOptionType(String name, boolean ignoreCase) {
+ switch (ignoreCase ? name.toLowerCase() : name) {
+ case "compressed":
+ case "Compressed": return boolean.class;
+ case "content":
+ case "Content": return byte[].class;
+ case "id":
+ case "Id": return java.lang.String.class;
+ case "interceptors":
+ case "Interceptors": return java.util.List.class;
+ case "language":
+ case "Language": return java.lang.String.class;
+ case "loader":
+ case "Loader": return java.lang.String.class;
+ case "location":
+ case "Location": return java.lang.String.class;
+ case "name":
+ case "Name": return java.lang.String.class;
+ case "propertynames":
+ case "PropertyNames": return java.util.List.class;
+ case "type":
+ case "Type": return org.apache.camel.quarkus.k.core.SourceType.class;
+ default: return null;
+ }
+ }
+
+ @Override
+ public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+ org.apache.camel.quarkus.k.core.SourceDefinition target = (org.apache.camel.quarkus.k.core.SourceDefinition) obj;
+ switch (ignoreCase ? name.toLowerCase() : name) {
+ case "compressed":
+ case "Compressed": return target.isCompressed();
+ case "content":
+ case "Content": return target.getContent();
+ case "id":
+ case "Id": return target.getId();
+ case "interceptors":
+ case "Interceptors": return target.getInterceptors();
+ case "language":
+ case "Language": return target.getLanguage();
+ case "loader":
+ case "Loader": return target.getLoader();
+ case "location":
+ case "Location": return target.getLocation();
+ case "name":
+ case "Name": return target.getName();
+ case "propertynames":
+ case "PropertyNames": return target.getPropertyNames();
+ case "type":
+ case "Type": return target.getType();
+ default: return null;
+ }
+ }
+
+ @Override
+ public Object getCollectionValueType(Object target, String name, boolean ignoreCase) {
+ switch (ignoreCase ? name.toLowerCase() : name) {
+ case "interceptors":
+ case "Interceptors": return java.lang.String.class;
+ case "propertynames":
+ case "PropertyNames": return java.lang.String.class;
+ default: return null;
+ }
+ }
+}
+
diff --git a/extensions/camel-k/runtime/src/generated/java/org/apache/camel/quarkus/k/listener/SourcesConfigurerConfigurer.java b/extensions/camel-k/runtime/src/generated/java/org/apache/camel/quarkus/k/listener/SourcesConfigurerConfigurer.java
new file mode 100644
index 0000000000..d0586e63f8
--- /dev/null
+++ b/extensions/camel-k/runtime/src/generated/java/org/apache/camel/quarkus/k/listener/SourcesConfigurerConfigurer.java
@@ -0,0 +1,49 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.quarkus.k.listener;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.quarkus.k.listener.SourcesConfigurer;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class SourcesConfigurerConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+ @Override
+ public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+ org.apache.camel.quarkus.k.listener.SourcesConfigurer target = (org.apache.camel.quarkus.k.listener.SourcesConfigurer) obj;
+ switch (ignoreCase ? name.toLowerCase() : name) {
+ case "sources":
+ case "Sources": target.setSources(property(camelContext, org.apache.camel.quarkus.k.core.SourceDefinition[].class, value)); return true;
+ default: return false;
+ }
+ }
+
+ @Override
+ public Class<?> getOptionType(String name, boolean ignoreCase) {
+ switch (ignoreCase ? name.toLowerCase() : name) {
+ case "sources":
+ case "Sources": return org.apache.camel.quarkus.k.core.SourceDefinition[].class;
+ default: return null;
+ }
+ }
+
+ @Override
+ public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+ org.apache.camel.quarkus.k.listener.SourcesConfigurer target = (org.apache.camel.quarkus.k.listener.SourcesConfigurer) obj;
+ switch (ignoreCase ? name.toLowerCase() : name) {
+ case "sources":
+ case "Sources": return target.getSources();
+ default: return null;
+ }
+ }
+}
+
diff --git a/extensions/camel-k/runtime/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.quarkus.k.core.SourceDefinition b/extensions/camel-k/runtime/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.quarkus.k.core.SourceDefinition
new file mode 100644
index 0000000000..92383b0230
--- /dev/null
+++ b/extensions/camel-k/runtime/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.quarkus.k.core.SourceDefinition
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.quarkus.k.core.SourceDefinitionConfigurer
diff --git a/extensions/camel-k/runtime/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.quarkus.k.listener.SourcesConfigurer b/extensions/camel-k/runtime/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.quarkus.k.listener.SourcesConfigurer
new file mode 100644
index 0000000000..6a1ffed062
--- /dev/null
+++ b/extensions/camel-k/runtime/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.quarkus.k.listener.SourcesConfigurer
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.quarkus.k.listener.SourcesConfigurerConfigurer
diff --git a/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/core/Runtime.java b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/core/Runtime.java
new file mode 100644
index 0000000000..f67b227753
--- /dev/null
+++ b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/core/Runtime.java
@@ -0,0 +1,156 @@
+/*
+ * 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.quarkus.k.core;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.ExtendedCamelContext;
+import org.apache.camel.Ordered;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.spi.HasCamelContext;
+import org.apache.camel.spi.Registry;
+
+import static org.apache.camel.util.CollectionHelper.mapOf;
+
+public interface Runtime extends HasCamelContext, AutoCloseable {
+ /**
+ * Returns the camel context adapting it to the specialized type.
+ *
+ * @see HasCamelContext#getCamelContext()
+ *
+ * @return the extended camel context.
+ */
+ default ExtendedCamelContext getExtendedCamelContext() {
+ return getCamelContext().getCamelContextExtension();
+ }
+
+ /**
+ * Returns the registry associated to this runtime.
+ */
+ default Registry getRegistry() {
+ return getCamelContext().getRegistry();
+ }
+
+ /**
+ * Sets a special list of properties that take precedence and will use first, if a property exist.
+ *
+ * @see org.apache.camel.spi.PropertiesComponent#setOverrideProperties(Properties)
+ * @param properties the properties to set
+ */
+ default void setProperties(Properties properties) {
+ getCamelContext().getPropertiesComponent().setOverrideProperties(properties);
+ }
+
+ /**
+ * Sets a special list of properties that take precedence and will use first, if a property exist.
+ *
+ * @see org.apache.camel.spi.PropertiesComponent#setOverrideProperties(Properties)
+ * @param properties the properties to set
+ */
+ default void setProperties(Map<String, String> properties) {
+ Properties p = new Properties();
+ p.putAll(properties);
+
+ setProperties(p);
+ }
+
+ /**
+ * Sets a special list of properties that take precedence and will use first, if a property exist.
+ *
+ * @see org.apache.camel.spi.PropertiesComponent#setOverrideProperties(Properties)
+ * @param key the mapping's key
+ * @param value the mapping's value
+ * @param entries containing the keys and values from which the map is populated
+ *
+ */
+ default void setProperties(String key, String value, String... entries) {
+ setProperties(
+ mapOf(HashMap::new, key, value, entries));
+ }
+
+ /**
+ * Sets a special list of properties that take precedence and will use first, if a property exist.
+ *
+ * @see org.apache.camel.spi.PropertiesComponent#setOverrideProperties(Properties)
+ * @param builder the builder which will create the routes
+ */
+ default void addRoutes(RoutesBuilder builder) {
+ try {
+ getCamelContext().addRoutes(builder);
+ } catch (Exception e) {
+ throw RuntimeCamelException.wrapRuntimeCamelException(e);
+ }
+ }
+
+ /**
+ * Lifecycle method used to stops the entire integration.
+ */
+ default void stop() throws Exception {
+ // Stopping the Camel context in default config is enough to tear down the integration
+ getCamelContext().stop();
+ }
+
+ @Override
+ default void close() throws Exception {
+ stop();
+ }
+
+ enum Phase {
+ Initializing,
+ ConfigureProperties,
+ ConfigureContext,
+ ConfigureRoutes,
+ Starting,
+ Started,
+ Stopping,
+ Stopped
+ }
+
+ @FunctionalInterface
+ interface Listener extends Ordered {
+ boolean accept(Phase phase, Runtime runtime);
+
+ @Override
+ default int getOrder() {
+ return Ordered.LOWEST;
+ }
+ }
+
+ /**
+ * Helper to create a simple runtime from a given Camel Context.
+ *
+ * @param camelContext the camel context
+ * @return the runtime
+ */
+ static Runtime on(CamelContext camelContext) {
+ return () -> camelContext;
+ }
+
+ /**
+ * Helper to create a simple runtime from a given Camel Context provider.
+ *
+ * @param provider the camel context provider
+ * @return the runtime
+ */
+ static Runtime on(HasCamelContext provider) {
+ return provider::getCamelContext;
+ }
+}
diff --git a/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/core/RuntimeAware.java b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/core/RuntimeAware.java
new file mode 100644
index 0000000000..a6df6d2d4e
--- /dev/null
+++ b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/core/RuntimeAware.java
@@ -0,0 +1,24 @@
+/*
+ * 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.quarkus.k.core;
+
+public interface RuntimeAware {
+
+ void setRuntime(Runtime runtime);
+
+ Runtime getRuntime();
+}
diff --git a/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/core/Source.java b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/core/Source.java
new file mode 100644
index 0000000000..afbe41235b
--- /dev/null
+++ b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/core/Source.java
@@ -0,0 +1,54 @@
+/*
+ * 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.quarkus.k.core;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+import java.util.Optional;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.HasId;
+
+public interface Source extends HasId {
+ String getLocation();
+
+ String getName();
+
+ String getLanguage();
+
+ SourceType getType();
+
+ Optional<String> getLoader();
+
+ List<String> getInterceptors();
+
+ List<String> getPropertyNames();
+
+ InputStream resolveAsInputStream(CamelContext ctx);
+
+ default Reader resolveAsReader(CamelContext ctx) {
+ return resolveAsReader(ctx, StandardCharsets.UTF_8);
+ }
+
+ default Reader resolveAsReader(CamelContext ctx, Charset charset) {
+ return new InputStreamReader(resolveAsInputStream(ctx), charset);
+ }
+}
diff --git a/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/core/SourceDefinition.java b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/core/SourceDefinition.java
new file mode 100644
index 0000000000..45ba6cef9c
--- /dev/null
+++ b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/core/SourceDefinition.java
@@ -0,0 +1,184 @@
+/*
+ * 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.quarkus.k.core;
+
+import java.util.List;
+
+import org.apache.camel.spi.Configurer;
+import org.apache.camel.spi.IdAware;
+
+@Configurer
+public class SourceDefinition implements IdAware {
+ private String id;
+ private String name;
+ private String language;
+ private String loader;
+ private List<String> interceptors;
+ // Default as source type
+ private SourceType type = SourceType.source;
+ private List<String> propertyNames;
+ private String location;
+ private byte[] content;
+ private boolean compressed;
+
+ @Override
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * Sets the id
+ */
+ @Override
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * The name of the source.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getLanguage() {
+ return language;
+ }
+
+ /**
+ * The language use to define the source.
+ */
+ public void setLanguage(String language) {
+ this.language = language;
+ }
+
+ public String getLoader() {
+ return loader;
+ }
+
+ /**
+ * The {@link SourceLoader} that should be used to load the content of the source.
+ */
+ public void setLoader(String loader) {
+ this.loader = loader;
+ }
+
+ public List<String> getInterceptors() {
+ return interceptors;
+ }
+
+ /**
+ * The {@link org.apache.camel.quarkus.SourceLoader.Interceptor} that should be applied.
+ */
+ public void setInterceptors(List<String> interceptors) {
+ this.interceptors = interceptors;
+ }
+
+ public SourceType getType() {
+ return type;
+ }
+
+ /**
+ * The {@link SourceType} of the source.
+ */
+ public void setType(SourceType type) {
+ this.type = type;
+ }
+
+ public List<String> getPropertyNames() {
+ return propertyNames;
+ }
+
+ /**
+ * The list of properties names the source requires (used only for templates).
+ */
+ public void setPropertyNames(List<String> propertyNames) {
+ this.propertyNames = propertyNames;
+ }
+
+ public String getLocation() {
+ return location;
+ }
+
+ /**
+ * The location of the source.
+ */
+ public void setLocation(String location) {
+ this.location = location;
+ }
+
+ public byte[] getContent() {
+ return content;
+ }
+
+ /**
+ * The content of the source.
+ */
+ public void setContent(byte[] content) {
+ this.content = content;
+ }
+
+ public boolean isCompressed() {
+ return compressed;
+ }
+
+ /**
+ * If the content of the source is compressed.
+ */
+ public void setCompressed(boolean compressed) {
+ this.compressed = compressed;
+ }
+
+ @Override
+ public String toString() {
+ String answer = "";
+
+ if (name != null) {
+ answer += "name='" + name + "', ";
+ }
+ if (language != null) {
+ answer += "language='" + language + "', ";
+ }
+ if (loader != null) {
+ answer += "loader='" + loader + "', ";
+ }
+ if (interceptors != null) {
+ answer += "interceptors='" + interceptors + "', ";
+ }
+ if (type != null) {
+ answer += "type='" + type + "', ";
+ }
+ if (propertyNames != null) {
+ answer += "propertyNames='" + propertyNames + "', ";
+ }
+ if (location != null) {
+ answer += "location='" + location + "', ";
+ }
+ if (compressed) {
+ answer += "compressed='true', ";
+ }
+ if (content != null) {
+ answer += "<...>";
+ }
+
+ return "SourceDefinition{" + answer + '}';
+ }
+}
diff --git a/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/core/SourceType.java b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/core/SourceType.java
new file mode 100644
index 0000000000..da4e053ad4
--- /dev/null
+++ b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/core/SourceType.java
@@ -0,0 +1,24 @@
+/*
+ * 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.quarkus.k.core;
+
+public enum SourceType {
+ // Order matters. We want the sources to be loaded following this enum order.
+ errorHandler,
+ template,
+ source
+}
diff --git a/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/listener/AbstractPhaseListener.java b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/listener/AbstractPhaseListener.java
new file mode 100644
index 0000000000..f303ba3aad
--- /dev/null
+++ b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/listener/AbstractPhaseListener.java
@@ -0,0 +1,39 @@
+/*
+ * 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.quarkus.k.listener;
+
+import org.apache.camel.quarkus.k.core.Runtime;
+
+public abstract class AbstractPhaseListener implements Runtime.Listener {
+ private final Runtime.Phase phase;
+
+ protected AbstractPhaseListener(Runtime.Phase phase) {
+ this.phase = phase;
+ }
+
+ @Override
+ public boolean accept(Runtime.Phase phase, Runtime runtime) {
+ boolean run = this.phase == phase;
+ if (run) {
+ accept(runtime);
+ }
+
+ return run;
+ }
+
+ protected abstract void accept(Runtime runtime);
+}
diff --git a/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/listener/ContextConfigurer.java b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/listener/ContextConfigurer.java
new file mode 100644
index 0000000000..7c1f965c48
--- /dev/null
+++ b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/listener/ContextConfigurer.java
@@ -0,0 +1,38 @@
+/*
+ * 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.quarkus.k.listener;
+
+import org.apache.camel.quarkus.k.core.Runtime;
+import org.apache.camel.quarkus.k.support.RuntimeSupport;
+
+public class ContextConfigurer extends AbstractPhaseListener {
+
+ public ContextConfigurer() {
+ super(Runtime.Phase.ConfigureContext);
+ }
+
+ @Override
+ protected void accept(Runtime runtime) {
+ //
+ // Programmatically configure the camel context.
+ //
+ // This is useful to configure services such as the ClusterService,
+ // RouteController, etc
+ //
+ RuntimeSupport.configureContextCustomizers(runtime.getCamelContext());
+ }
+}
diff --git a/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/listener/SourcesConfigurer.java b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/listener/SourcesConfigurer.java
new file mode 100644
index 0000000000..dd221e1451
--- /dev/null
+++ b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/listener/SourcesConfigurer.java
@@ -0,0 +1,109 @@
+/*
+ * 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.quarkus.k.listener;
+
+import java.util.Arrays;
+import java.util.Comparator;
+
+import org.apache.camel.quarkus.k.core.Runtime;
+import org.apache.camel.quarkus.k.core.SourceDefinition;
+import org.apache.camel.quarkus.k.core.SourceType;
+import org.apache.camel.quarkus.k.support.Constants;
+import org.apache.camel.quarkus.k.support.PropertiesSupport;
+import org.apache.camel.quarkus.k.support.SourcesSupport;
+import org.apache.camel.spi.Configurer;
+import org.apache.camel.util.ObjectHelper;
+
+@Configurer
+public class SourcesConfigurer extends AbstractPhaseListener {
+
+ public static final String CAMEL_K_PREFIX = "camel.k.";
+ public static final String CAMEL_K_SOURCES_PREFIX = "camel.k.sources[";
+
+ private SourceDefinition[] sources;
+
+ public SourcesConfigurer() {
+ super(Runtime.Phase.ConfigureRoutes);
+ }
+
+ public SourceDefinition[] getSources() {
+ return sources;
+ }
+
+ public void setSources(SourceDefinition[] sources) {
+ this.sources = sources;
+ }
+
+ @Override
+ protected void accept(Runtime runtime) {
+ //
+ // load routes from env var for backward compatibility
+ //
+ String routes = System.getProperty(Constants.PROPERTY_CAMEL_K_ROUTES);
+ if (ObjectHelper.isEmpty(routes)) {
+ routes = System.getenv(Constants.ENV_CAMEL_K_ROUTES);
+ }
+
+ if (ObjectHelper.isNotEmpty(routes)) {
+ SourcesSupport.loadSources(runtime, routes.split(","));
+ }
+
+ //
+ // load routes from properties
+ //
+ // In order not to load any unwanted property, the filer remove any
+ // property that can't be bound to this configurer.
+ //
+ PropertiesSupport.bindProperties(
+ runtime.getCamelContext(),
+ this,
+ k -> k.startsWith(CAMEL_K_SOURCES_PREFIX),
+ CAMEL_K_PREFIX);
+
+ checkUniqueErrorHandler();
+ sortSources();
+
+ if (ObjectHelper.isNotEmpty(this.getSources())) {
+ SourcesSupport.loadSources(runtime, this.getSources());
+ }
+ }
+
+ private void checkUniqueErrorHandler() {
+ checkUniqueErrorHandler(this.sources);
+ }
+
+ static void checkUniqueErrorHandler(SourceDefinition[] sources) {
+ long errorHandlers = sources == null ? 0
+ : Arrays.stream(sources).filter(s -> s.getType() == SourceType.errorHandler).count();
+ if (errorHandlers > 1) {
+ throw new IllegalArgumentException("Expected only one error handler source type, got " + errorHandlers);
+ }
+ }
+
+ private void sortSources() {
+ sortSources(this.getSources());
+ }
+
+ static void sortSources(SourceDefinition[] sources) {
+ if (sources == null) {
+ return;
+ }
+ // We must ensure the source order as defined in SourceType enum
+ Arrays.sort(sources, Comparator.comparingInt(a -> a.getType().ordinal()));
+ }
+
+}
diff --git a/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/runtime/Application.java b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/runtime/Application.java
new file mode 100644
index 0000000000..95bcf6636c
--- /dev/null
+++ b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/runtime/Application.java
@@ -0,0 +1,175 @@
+/*
+ * 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.quarkus.k.runtime;
+
+import java.util.Collection;
+import java.util.Collections;
+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;
+import org.apache.camel.main.RoutesCollector;
+import org.apache.camel.spi.Resource;
+
+public final class Application {
+
+ private Application() {
+ }
+
+ /**
+ * The camel-k runtime impl based on camel-quarkus
+ */
+ public static class Runtime implements org.apache.camel.quarkus.k.core.Runtime {
+ private final BaseMainSupport main;
+ private final AtomicBoolean stopped;
+
+ public Runtime(BaseMainSupport main) {
+ this.main = main;
+ this.main.configure().setAutoConfigurationLogSummary(false);
+ this.stopped = new AtomicBoolean();
+ }
+
+ @Override
+ public CamelContext getCamelContext() {
+ return main.getCamelContext();
+ }
+
+ @Override
+ public void addRoutes(RoutesBuilder builder) {
+ main.configure().addRoutesBuilder(builder);
+ }
+
+ @Override
+ public void setProperties(Properties properties) {
+ main.setOverrideProperties(properties);
+ }
+
+ @Override
+ public void stop() throws Exception {
+ if (!this.stopped.compareAndExchange(false, true)) {
+ Quarkus.asyncExit();
+ }
+ }
+ }
+
+ /**
+ * Adapts main events to camel-k runtime lifecycle
+ */
+ public static class ListenerAdapter implements MainListener {
+ private final org.apache.camel.quarkus.k.core.Runtime.Listener[] listeners;
+
+ public ListenerAdapter(List<org.apache.camel.quarkus.k.core.Runtime.Listener> listeners) {
+ this.listeners = listeners.stream()
+ .sorted(Comparator.comparingInt(org.apache.camel.quarkus.k.core.Runtime.Listener::getOrder))
+ .toArray(org.apache.camel.quarkus.k.core.Runtime.Listener[]::new);
+ }
+
+ @Override
+ public void beforeInitialize(BaseMainSupport main) {
+ invokeListeners(org.apache.camel.quarkus.k.core.Runtime.Phase.Initializing);
+ invokeListeners(org.apache.camel.quarkus.k.core.Runtime.Phase.ConfigureProperties);
+ }
+
+ @Override
+ public void beforeConfigure(BaseMainSupport main) {
+ invokeListeners(org.apache.camel.quarkus.k.core.Runtime.Phase.ConfigureRoutes);
+ }
+
+ @Override
+ public void afterConfigure(BaseMainSupport main) {
+ invokeListeners(org.apache.camel.quarkus.k.core.Runtime.Phase.ConfigureContext);
+ }
+
+ @Override
+ public void beforeStart(BaseMainSupport main) {
+ invokeListeners(org.apache.camel.quarkus.k.core.Runtime.Phase.Starting);
+ }
+
+ @Override
+ public void afterStart(BaseMainSupport main) {
+ invokeListeners(org.apache.camel.quarkus.k.core.Runtime.Phase.Started);
+ }
+
+ @Override
+ public void beforeStop(BaseMainSupport main) {
+ invokeListeners(org.apache.camel.quarkus.k.core.Runtime.Phase.Stopping);
+ }
+
+ @Override
+ public void afterStop(BaseMainSupport main) {
+ invokeListeners(org.apache.camel.quarkus.k.core.Runtime.Phase.Stopped);
+ }
+
+ private void invokeListeners(org.apache.camel.quarkus.k.core.Runtime.Phase phase) {
+ org.apache.camel.quarkus.k.core.Runtime runtime = instance(org.apache.camel.quarkus.k.core.Runtime.class)
+ .orElseThrow(() -> new IllegalStateException("Unable to fine a Runtime instance"));
+
+ for (int i = 0; i < listeners.length; i++) {
+ listeners[i].accept(phase, runtime);
+ }
+ }
+ }
+
+ /**
+ * Since routes are programmatically loaded, create a no-hop collector
+ */
+ public static class NoRoutesCollector implements RoutesCollector {
+ @Override
+ public Collection<RoutesBuilder> collectRoutesFromDirectory(CamelContext camelContext, String excludePattern,
+ String includePattern) {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public Collection<Resource> findRouteResourcesFromDirectory(CamelContext camelContext, String excludePattern,
+ String includePattern) {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public List<RoutesBuilder> collectRoutesFromRegistry(CamelContext camelContext, String excludePattern,
+ String includePattern) {
+ return Collections.emptyList();
+ }
+ }
+
+ // *********************************
+ //
+ // Helpers
+ //
+ // *********************************
+
+ public static Optional<ArcContainer> container() {
+ return Optional.of(Arc.container());
+ }
+
+ public static <T> Optional<T> instance(Class<T> type) {
+ return container()
+ .map(container -> container.instance(type))
+ .map(InstanceHandle::get);
+ }
+}
diff --git a/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/runtime/ApplicationConfigSourceProvider.java b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/runtime/ApplicationConfigSourceProvider.java
new file mode 100644
index 0000000000..f0fb7f90f6
--- /dev/null
+++ b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/runtime/ApplicationConfigSourceProvider.java
@@ -0,0 +1,45 @@
+/*
+ * 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.quarkus.k.runtime;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import io.smallrye.config.PropertiesConfigSource;
+import org.apache.camel.component.kubernetes.properties.ConfigMapPropertiesFunction;
+import org.apache.camel.quarkus.k.support.RuntimeSupport;
+import org.eclipse.microprofile.config.spi.ConfigSource;
+import org.eclipse.microprofile.config.spi.ConfigSourceProvider;
+
+public class ApplicationConfigSourceProvider implements ConfigSourceProvider {
+
+ @Override
+ public Iterable<ConfigSource> getConfigSources(ClassLoader forClassLoader) {
+ final Map<String, String> sysProperties = new HashMap<>();
+ // explicit disable looking up configmap and secret using the KubernetesClient
+ sysProperties.put(ConfigMapPropertiesFunction.CLIENT_ENABLED, "false");
+
+ final Map<String, String> appProperties = RuntimeSupport.loadApplicationProperties();
+ final Map<String, String> usrProperties = RuntimeSupport.loadUserProperties();
+
+ return List.of(
+ new PropertiesConfigSource(sysProperties, "camel-k-sys", ConfigSource.DEFAULT_ORDINAL + 1000),
+ new PropertiesConfigSource(appProperties, "camel-k-app", ConfigSource.DEFAULT_ORDINAL),
+ new PropertiesConfigSource(usrProperties, "camel-k-usr", ConfigSource.DEFAULT_ORDINAL + 1));
+ }
+}
diff --git a/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/runtime/ApplicationProducers.java b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/runtime/ApplicationProducers.java
new file mode 100644
index 0000000000..9e0509d550
--- /dev/null
+++ b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/runtime/ApplicationProducers.java
@@ -0,0 +1,39 @@
+/*
+ * 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.quarkus.k.runtime;
+
+import io.quarkus.arc.Unremovable;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.inject.Produces;
+import jakarta.inject.Singleton;
+import org.apache.camel.quarkus.k.core.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;
+ }
+}
diff --git a/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/runtime/ApplicationRecorder.java b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/runtime/ApplicationRecorder.java
new file mode 100644
index 0000000000..5e06ec9bd6
--- /dev/null
+++ b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/runtime/ApplicationRecorder.java
@@ -0,0 +1,48 @@
+/*
+ * 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.quarkus.k.runtime;
+
+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.main.MainListener;
+import org.apache.camel.main.RoutesCollector;
+import org.apache.camel.quarkus.k.core.Runtime;
+import org.apache.camel.quarkus.main.CamelMain;
+import org.slf4j.LoggerFactory;
+
+@Recorder
+public class ApplicationRecorder {
+
+ public void version(String version) {
+ LoggerFactory.getLogger(Runtime.class).info("Apache Camel K Runtime {}", version);
+ }
+
+ public RuntimeValue<MainListener> createMainListener(List<Runtime.Listener> listeners) {
+ return new RuntimeValue<>(new Application.ListenerAdapter(listeners));
+ }
+
+ public void publishRuntime(RuntimeValue<CamelMain> main, BeanContainer container) {
+ container.beanInstance(ApplicationProducers.class).setRuntime(new Application.Runtime(main.getValue()));
+ }
+
+ public RuntimeValue<RoutesCollector> createRoutesCollector() {
+ return new RuntimeValue<>(new Application.NoRoutesCollector());
+ }
+}
diff --git a/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/support/Constants.java b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/support/Constants.java
new file mode 100644
index 0000000000..3979ba7af6
--- /dev/null
+++ b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/support/Constants.java
@@ -0,0 +1,63 @@
+/*
+ * 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.quarkus.k.support;
+
+public final class Constants {
+ public static final String ENV_CAMEL_K_ROUTES = "CAMEL_K_ROUTES";
+ public static final String PROPERTY_CAMEL_K_ROUTES = "camel.k.routes";
+
+ public static final String ENV_CAMEL_K_CONF = "CAMEL_K_CONF";
+ public static final String PROPERTY_CAMEL_K_CONF = "camel.k.conf";
+
+ public static final String ENV_CAMEL_K_CONF_D = "CAMEL_K_CONF_D";
+ public static final String PROPERTY_CAMEL_K_CONF_D = "camel.k.conf.d";
+
+ public static final String ENV_CAMEL_K_CUSTOMIZERS = "CAMEL_K_CUSTOMIZERS";
+ public static final String PROPERTY_CAMEL_K_CUSTOMIZER = "camel.k.customizer";
+
+ public static final String ENV_CAMEL_K_MOUNT_PATH_CONFIGMAPS = "CAMEL_K_MOUNT_PATH_CONFIGMAPS";
+ public static final String PROPERTY_CAMEL_K_MOUNT_PATH_CONFIGMAPS = "camel.k.mount-path.configmaps";
+
+ public static final String ENV_CAMEL_K_MOUNT_PATH_SECRETS = "CAMEL_K_MOUNT_PATH_SECRETS";
+ public static final String PROPERTY_CAMEL_K_MOUNT_PATH_SECRETS = "camel.k.mount-path.secrets";
+
+ public static final String SCHEME_REF = "ref";
+ public static final String SCHEME_PREFIX_REF = SCHEME_REF + ":";
+ public static final String SCHEME_CLASS = "class";
+ public static final String SCHEME_PREFIX_CLASS = SCHEME_CLASS + ":";
+ public static final String SCHEME_CLASSPATH = "classpath";
+ public static final String SCHEME_PREFIX_CLASSPATH = SCHEME_CLASSPATH + ":";
+ public static final String SCHEME_FILE = "file";
+ public static final String SCHEME_PREFIX_FILE = SCHEME_FILE + ":";
+
+ public static final String LOGGING_LEVEL_PREFIX = "logging.level.";
+ public static final String SOURCE_LOADER_INTERCEPTOR_RESOURCE_PATH = "META-INF/services/org.apache.camel.quarkus.k/loader/interceptor/";
+ public static final String CONTEXT_CUSTOMIZER_RESOURCE_PATH = "META-INF/services/org.apache.camel.quarkus.k/customizer/";
+
+ public static final String ENABLE_CUSTOMIZER_PATTERN = "(camel\\.k\\.)?customizer\\.([\\w][\\w-]*)\\.enabled";
+
+ public static final String PROPERTY_PREFIX_REST_COMPONENT_PROPERTY = "camel.rest.componentProperty.";
+ public static final String PROPERTY_PREFIX_REST_ENDPOINT_PROPERTY = "camel.rest.endpointProperty.";
+
+ public static final String CUSTOMIZER_PREFIX = "camel.k.customizer.";
+ public static final String CUSTOMIZER_PREFIX_FALLBACK = "customizer.";
+ public static final String LOADER_INTERCEPTOR_PREFIX = "camel.k.loader.interceptor.";
+ public static final String LOADER_INTERCEPTOR_PREFIX_FALLBACK = "loader.interceptor.";
+
+ private Constants() {
+ }
+}
diff --git a/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/support/DelegatingRuntime.java b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/support/DelegatingRuntime.java
new file mode 100644
index 0000000000..2cc6221758
--- /dev/null
+++ b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/support/DelegatingRuntime.java
@@ -0,0 +1,80 @@
+/*
+ * 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.quarkus.k.support;
+
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.ExtendedCamelContext;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.quarkus.k.core.Runtime;
+import org.apache.camel.spi.Registry;
+
+public class DelegatingRuntime implements Runtime {
+
+ private final Runtime runtime;
+
+ public DelegatingRuntime(Runtime runtime) {
+ this.runtime = runtime;
+ }
+
+ @Override
+ public ExtendedCamelContext getExtendedCamelContext() {
+ return runtime.getExtendedCamelContext();
+ }
+
+ @Override
+ public Registry getRegistry() {
+ return runtime.getRegistry();
+ }
+
+ @Override
+ public void setProperties(Properties properties) {
+ runtime.setProperties(properties);
+ }
+
+ @Override
+ public void setProperties(Map<String, String> properties) {
+ runtime.setProperties(properties);
+ }
+
+ @Override
+ public void setProperties(String key, String value, String... keyVals) {
+ runtime.setProperties(key, value, keyVals);
+ }
+
+ @Override
+ public void addRoutes(RoutesBuilder builder) {
+ runtime.addRoutes(builder);
+ }
+
+ @Override
+ public void stop() throws Exception {
+ runtime.stop();
+ }
+
+ @Override
+ public void close() throws Exception {
+ runtime.close();
+ }
+
+ @Override
+ public CamelContext getCamelContext() {
+ return runtime.getCamelContext();
+ }
+}
diff --git a/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/support/PropertiesSupport.java b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/support/PropertiesSupport.java
new file mode 100644
index 0000000000..61cda7d5d2
--- /dev/null
+++ b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/support/PropertiesSupport.java
@@ -0,0 +1,93 @@
+/*
+ * 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.quarkus.k.support;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.function.Predicate;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Component;
+import org.apache.camel.ExtendedCamelContext;
+import org.apache.camel.spi.PropertiesComponent;
+import org.apache.camel.spi.PropertyConfigurer;
+import org.apache.camel.support.PluginHelper;
+import org.apache.camel.support.PropertyBindingSupport;
+import org.apache.camel.support.service.ServiceHelper;
+
+public final class PropertiesSupport {
+
+ private PropertiesSupport() {
+ }
+
+ public static <T> T bindProperties(CamelContext context, T target, String prefix) {
+ return bindProperties(context, target, prefix, false);
+ }
+
+ public static <T> T bindProperties(CamelContext context, T target, String prefix, boolean stripPrefix) {
+ return bindProperties(context, target, k -> k.startsWith(prefix), prefix, stripPrefix);
+ }
+
+ public static <T> T bindProperties(CamelContext context, T target, Predicate<String> filter, String prefix) {
+ return bindProperties(context, target, filter, prefix, false);
+ }
+
+ public static <T> T bindProperties(CamelContext context, T target, Predicate<String> filter, String prefix,
+ boolean stripPrefix) {
+ final PropertiesComponent component = context.getPropertiesComponent();
+ final Properties propertiesWithPrefix = component.loadProperties(filter);
+ final Map<String, Object> properties = new HashMap<>();
+
+ propertiesWithPrefix.stringPropertyNames().forEach(
+ name -> properties.put(
+ stripPrefix ? name.substring(prefix.length()) : name,
+ propertiesWithPrefix.getProperty(name)));
+
+ PropertyConfigurer configurer = null;
+ if (target instanceof Component) {
+ // the component needs to be initialized to have the configurer ready
+ ServiceHelper.initService(target);
+ configurer = ((Component) target).getComponentPropertyConfigurer();
+ }
+
+ if (configurer == null) {
+ String name = target.getClass().getName();
+ if (target instanceof ExtendedCamelContext) {
+ // special for camel context itself as we have an extended configurer
+ name = ExtendedCamelContext.class.getName();
+ }
+
+ // see if there is a configurer for it
+ configurer = PluginHelper.getConfigurerResolver(context.getCamelContextExtension()).resolvePropertyConfigurer(name,
+ context);
+ }
+
+ PropertyBindingSupport.build()
+ .withIgnoreCase(true)
+ .withCamelContext(context)
+ .withTarget(target)
+ .withProperties(properties)
+ .withRemoveParameters(true)
+ .withOptionPrefix(stripPrefix ? null : prefix)
+ .withConfigurer(configurer)
+ .bind();
+
+ return target;
+ }
+
+}
diff --git a/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/support/RouteBuilders.java b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/support/RouteBuilders.java
new file mode 100644
index 0000000000..e889f68bcd
--- /dev/null
+++ b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/support/RouteBuilders.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.quarkus.k.support;
+
+import java.io.Reader;
+
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.builder.endpoint.EndpointRouteBuilder;
+import org.apache.camel.quarkus.k.core.Source;
+import org.apache.camel.util.function.ThrowingBiConsumer;
+import org.apache.camel.util.function.ThrowingConsumer;
+
+public final class RouteBuilders {
+
+ private RouteBuilders() {
+ }
+
+ public static EndpointRouteBuilder endpoint(Source source,
+ ThrowingBiConsumer<Reader, EndpointRouteBuilder, Exception> consumer) {
+ return new EndpointRouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ try (Reader reader = source.resolveAsReader(getContext())) {
+ consumer.accept(reader, this);
+ }
+ }
+ };
+ }
+
+ public static EndpointRouteBuilder endpoint(ThrowingConsumer<EndpointRouteBuilder, Exception> consumer) {
+ return new EndpointRouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ consumer.accept(this);
+ }
+ };
+ }
+
+ public static RoutesBuilder route(Source source, ThrowingBiConsumer<Reader, RouteBuilder, Exception> consumer) {
+ return new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ try (Reader reader = source.resolveAsReader(getContext())) {
+ consumer.accept(reader, this);
+ }
+ }
+ };
+ }
+
+ public static RoutesBuilder route(ThrowingConsumer<RouteBuilder, Exception> consumer) {
+ return new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ consumer.accept(this);
+ }
+ };
+ }
+}
diff --git a/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/support/RuntimeSupport.java b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/support/RuntimeSupport.java
new file mode 100644
index 0000000000..51a3caabb5
--- /dev/null
+++ b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/support/RuntimeSupport.java
@@ -0,0 +1,341 @@
+/*
+ * 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.quarkus.k.support;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.nio.charset.MalformedInputException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.FileVisitResult;
+import java.nio.file.FileVisitor;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.ExtendedCamelContext;
+import org.apache.camel.builder.RouteBuilderLifecycleStrategy;
+import org.apache.camel.quarkus.k.core.Source;
+import org.apache.camel.spi.CamelContextCustomizer;
+import org.apache.camel.spi.HasCamelContext;
+import org.apache.camel.util.IOHelper;
+import org.apache.camel.util.ObjectHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class RuntimeSupport {
+ private static final Logger LOGGER = LoggerFactory.getLogger(RuntimeSupport.class);
+
+ private RuntimeSupport() {
+ }
+
+ // *********************************
+ //
+ // Helpers - Customizers
+ //
+ // *********************************
+
+ public static List<CamelContextCustomizer> configureContextCustomizers(HasCamelContext hasCamelContext) {
+ return configureContextCustomizers(hasCamelContext.getCamelContext());
+ }
+
+ public static List<CamelContextCustomizer> configureContextCustomizers(CamelContext context) {
+ List<CamelContextCustomizer> appliedCustomizers = new ArrayList<>();
+ Map<String, CamelContextCustomizer> customizers = lookupCustomizers(context);
+
+ customizers.entrySet().stream()
+ .sorted(Map.Entry.comparingByValue())
+ .forEach(e -> {
+ LOGGER.debug("Apply ContextCustomizer with id={} and type={}", e.getKey(),
+ e.getValue().getClass().getName());
+
+ PropertiesSupport.bindProperties(context, e.getValue(), Constants.CUSTOMIZER_PREFIX + e.getKey() + ".");
+ PropertiesSupport.bindProperties(context, e.getValue(),
+ Constants.CUSTOMIZER_PREFIX_FALLBACK + e.getKey() + ".");
+
+ e.getValue().configure(context);
+
+ appliedCustomizers.add(e.getValue());
+ });
+
+ return appliedCustomizers;
+ }
+
+ public static Map<String, CamelContextCustomizer> lookupCustomizers(CamelContext context) {
+ Map<String, CamelContextCustomizer> customizers = new ConcurrentHashMap<>();
+ Properties properties = context.getPropertiesComponent().loadProperties(
+ n -> n.startsWith(Constants.CUSTOMIZER_PREFIX) || n.startsWith(Constants.CUSTOMIZER_PREFIX_FALLBACK));
+
+ if (properties != null) {
+ //
+ // Lookup customizers listed in Constants.ENV_CAMEL_K_CUSTOMIZERS or Constants.PROPERTY_CAMEL_K_CUSTOMIZER
+ // for backward compatibility
+ //
+ for (String customizerId : lookupCustomizerIDs(context)) {
+ customizers.computeIfAbsent(customizerId, id -> lookupCustomizerByID(context, id));
+ }
+
+ Pattern pattern = Pattern.compile(Constants.ENABLE_CUSTOMIZER_PATTERN);
+
+ properties.entrySet().stream()
+ .filter(entry -> entry.getKey() instanceof String)
+ .filter(entry -> entry.getValue() != null)
+ .forEach(entry -> {
+ final String key = (String) entry.getKey();
+ final Object val = entry.getValue();
+ final Matcher matcher = pattern.matcher(key);
+
+ if (matcher.matches()) {
+ String customizerId = null;
+
+ if (matcher.groupCount() == 1) {
+ customizerId = matcher.group(1);
+ } else if (matcher.groupCount() == 2) {
+ customizerId = matcher.group(2);
+ }
+
+ if (customizerId != null && Boolean.parseBoolean(String.valueOf(val))) {
+ //
+ // Do not override customizers eventually found
+ // in the registry
+ //
+ customizers.computeIfAbsent(customizerId, id -> lookupCustomizerByID(context, id));
+ }
+ }
+ });
+ }
+
+ return customizers;
+ }
+
+ public static CamelContextCustomizer lookupCustomizerByID(CamelContext context, String customizerId) {
+ CamelContextCustomizer customizer = context.getRegistry().lookupByNameAndType(customizerId,
+ CamelContextCustomizer.class);
+ if (customizer == null) {
+ customizer = context.getCamelContextExtension()
+ .getFactoryFinder(Constants.CONTEXT_CUSTOMIZER_RESOURCE_PATH)
+ .newInstance(customizerId, CamelContextCustomizer.class)
+ .orElseThrow(() -> new RuntimeException("Error creating instance for customizer: " + customizerId));
+
+ LOGGER.debug("Found customizer {} with id {} from service definition", customizer, customizerId);
+ } else {
+ LOGGER.debug("Found customizer {} with id {} from the registry", customizer, customizerId);
+ }
+
+ return customizer;
+ }
+
+ public static Set<String> lookupCustomizerIDs(CamelContext context) {
+ Set<String> customizers = new TreeSet<>();
+ String customizerIDs = System.getenv().getOrDefault(Constants.ENV_CAMEL_K_CUSTOMIZERS, "");
+ if (ObjectHelper.isEmpty(customizerIDs)) {
+ // TODO: getPropertiesComponent().resolveProperty() throws exception instead
+ // of returning abd empty optional
+ customizerIDs = context.getPropertiesComponent()
+ .loadProperties(Constants.PROPERTY_CAMEL_K_CUSTOMIZER::equals)
+ .getProperty(Constants.PROPERTY_CAMEL_K_CUSTOMIZER, "");
+ }
+
+ if (ObjectHelper.isNotEmpty(customizerIDs)) {
+ for (String customizerId : customizerIDs.split(",", -1)) {
+ customizers.add(customizerId);
+ }
+ }
+ return customizers;
+ }
+
+ // *********************************
+ //
+ // Helpers - Interceptors
+ //
+ // *********************************
+
+ public static List<RouteBuilderLifecycleStrategy> loadInterceptors(CamelContext context, Source source) {
+ ExtendedCamelContext ecc = context.getCamelContextExtension();
+ List<RouteBuilderLifecycleStrategy> answer = new ArrayList<>();
+
+ for (String id : source.getInterceptors()) {
+ try {
+ // first check the registry
+ RouteBuilderLifecycleStrategy interceptor = ecc.getRegistry()
+ .lookupByNameAndType(id, RouteBuilderLifecycleStrategy.class);
+
+ if (interceptor == null) {
+ // then try with factory finder
+ interceptor = ecc.getFactoryFinder(Constants.SOURCE_LOADER_INTERCEPTOR_RESOURCE_PATH)
+ .newInstance(id, RouteBuilderLifecycleStrategy.class)
+ .orElseThrow(
+ () -> new IllegalArgumentException("Unable to find source loader interceptor for: " + id));
+
+ LOGGER.debug("Found source loader interceptor {} from service definition", id);
+ } else {
+ LOGGER.debug("Found source loader interceptor {} from registry", id);
+ }
+
+ PropertiesSupport.bindProperties(context, interceptor, Constants.LOADER_INTERCEPTOR_PREFIX + id + ".");
+ PropertiesSupport.bindProperties(context, interceptor, Constants.LOADER_INTERCEPTOR_PREFIX_FALLBACK + id + ".");
+
+ answer.add(interceptor);
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Unable to find source loader interceptor for: " + id, e);
+ }
+ }
+
+ return answer;
+ }
+
+ // *********************************
+ //
+ // Helpers - Misc
+ //
+ // *********************************
+
+ public static String getRuntimeVersion() {
+ String version = null;
+
+ InputStream is = null;
+ // try to load from maven properties first
+ try {
+ Properties p = new Properties();
+ is = RuntimeSupport.class.getResourceAsStream(
+ "/META-INF/maven/org.apache.camel.quarkus/camel-quarkus-k-core-api/pom.properties");
+ if (is != null) {
+ p.load(is);
+ version = p.getProperty("version", "");
+ }
+ } catch (Exception e) {
+ // ignore
+ } finally {
+ if (is != null) {
+ IOHelper.close(is);
+ }
+ }
+
+ // fallback to using Java API
+ if (version == null) {
+ Package aPackage = RuntimeSupport.class.getPackage();
+ if (aPackage != null) {
+ version = aPackage.getImplementationVersion();
+ if (version == null) {
+ version = aPackage.getSpecificationVersion();
+ }
+ }
+ }
+
+ if (version == null) {
+ // we could not compute the version so use a blank
+ version = "";
+ }
+
+ return Objects.requireNonNull(version, "Could not determine Camel K Runtime version");
+ }
+
+ // *********************************
+ //
+ // Properties
+ //
+ // *********************************
+
+ public static Map<String, String> loadApplicationProperties() {
+ final String conf = System.getProperty(Constants.PROPERTY_CAMEL_K_CONF, System.getenv(Constants.ENV_CAMEL_K_CONF));
+ final Map<String, String> properties = new HashMap<>();
+
+ if (ObjectHelper.isEmpty(conf)) {
+ return properties;
+ }
+
+ try {
+ Path confPath = Paths.get(conf);
+ if (Files.exists(confPath) && !Files.isDirectory(confPath)) {
+ try (Reader reader = Files.newBufferedReader(confPath)) {
+ Properties p = new Properties();
+ p.load(reader);
+ p.forEach((key, value) -> properties.put(String.valueOf(key), String.valueOf(value)));
+ }
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ return properties;
+ }
+
+ public static Map<String, String> loadUserProperties() {
+ final String conf = System.getProperty(Constants.PROPERTY_CAMEL_K_CONF_D, System.getenv(Constants.ENV_CAMEL_K_CONF_D));
+ final Map<String, String> properties = new HashMap<>();
+
+ if (ObjectHelper.isEmpty(conf)) {
+ return properties;
+ }
+
+ FileVisitor<Path> visitor = new SimpleFileVisitor<>() {
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+ Objects.requireNonNull(file);
+ Objects.requireNonNull(attrs);
+
+ if (Files.isDirectory(file) || Files.isSymbolicLink(file)) {
+ return FileVisitResult.CONTINUE;
+ }
+
+ if (file.toFile().getAbsolutePath().endsWith(".properties")) {
+ try (Reader reader = Files.newBufferedReader(file)) {
+ Properties p = new Properties();
+ p.load(reader);
+ p.forEach((key, value) -> properties.put(String.valueOf(key), String.valueOf(value)));
+ }
+ } else {
+ try {
+ properties.put(
+ file.getFileName().toString(),
+ Files.readString(file, StandardCharsets.UTF_8));
+ } catch (MalformedInputException mie) {
+ // Just skip if it is not a UTF-8 encoded file (ie a binary)
+ LOGGER.info("Cannot transform {} into UTF-8 text, skipping.", file);
+ }
+ }
+ return FileVisitResult.CONTINUE;
+ }
+ };
+
+ Path root = Paths.get(conf);
+
+ if (Files.exists(root)) {
+ try {
+ Files.walkFileTree(root, visitor);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ return properties;
+ }
+}
diff --git a/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/support/Sources.java b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/support/Sources.java
new file mode 100644
index 0000000000..faf3a6b7e0
--- /dev/null
+++ b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/support/Sources.java
@@ -0,0 +1,243 @@
+/*
+ * 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.quarkus.k.support;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.nio.charset.Charset;
+import java.util.Base64;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.zip.GZIPInputStream;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.quarkus.k.core.Source;
+import org.apache.camel.quarkus.k.core.SourceDefinition;
+import org.apache.camel.quarkus.k.core.SourceType;
+import org.apache.camel.spi.Resource;
+import org.apache.camel.support.ResourceHelper;
+import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.URISupport;
+
+public final class Sources {
+
+ private Sources() {
+ }
+
+ public static Source fromURI(String uri) throws Exception {
+ return fromDefinition(computeDefinitionFromURI(uri));
+ }
+
+ public static SourceDefinition fromBytes(String id, String name, String language, String loader, List<String> interceptors,
+ byte[] content) {
+ SourceDefinition answer = new SourceDefinition();
+ answer.setId(id);
+ answer.setName(name);
+ answer.setLanguage(language);
+ answer.setLoader(loader);
+ answer.setInterceptors(interceptors != null ? interceptors : Collections.emptyList());
+ answer.setContent(content);
+
+ return answer;
+ }
+
+ public static Source fromBytes(String name, String language, String loader, List<String> interceptors, byte[] content) {
+ return fromDefinition(fromBytes(null, name, language, loader, interceptors, content));
+ }
+
+ public static Source fromBytes(String name, String language, String loader, byte[] content) {
+ return fromDefinition(fromBytes(null, name, language, loader, null, content));
+ }
+
+ public static Source fromBytes(String language, byte[] content) {
+ return fromDefinition(fromBytes(null, UUID.randomUUID().toString(), language, null, null, content));
+ }
+
+ public static Source fromDefinition(SourceDefinition definition) {
+ if (definition.getLocation() == null && definition.getContent() == null) {
+ throw new IllegalArgumentException("Either the source location or the source content should be set");
+ }
+ return new Source() {
+ @Override
+ public String getLocation() {
+ return definition.getLocation();
+ }
+
+ @Override
+ public String getId() {
+ return ObjectHelper.supplyIfEmpty(definition.getId(), this::getName);
+ }
+
+ @Override
+ public String getName() {
+ String answer = definition.getName();
+ if (ObjectHelper.isEmpty(answer) && ObjectHelper.isNotEmpty(definition.getLocation())) {
+ answer = StringSupport.substringAfter(definition.getLocation(), ":");
+ answer = StringSupport.substringBeforeLast(answer, ".");
+
+ if (answer.contains("/")) {
+ answer = StringSupport.substringAfterLast(answer, "/");
+ }
+ }
+
+ return answer;
+ }
+
+ @Override
+ public String getLanguage() {
+ String answer = definition.getLanguage();
+ if (ObjectHelper.isEmpty(answer) && ObjectHelper.isNotEmpty(definition.getLocation())) {
+ answer = StringSupport.substringAfterLast(definition.getLocation(), ":");
+ answer = StringSupport.substringAfterLast(answer, ".");
+ }
+
+ return answer;
+ }
+
+ @Override
+ public SourceType getType() {
+ return ObjectHelper.supplyIfEmpty(definition.getType(), () -> SourceType.source);
+ }
+
+ @Override
+ public Optional<String> getLoader() {
+ return Optional.ofNullable(definition.getLoader());
+ }
+
+ @Override
+ public List<String> getInterceptors() {
+ return ObjectHelper.supplyIfEmpty(definition.getInterceptors(), Collections::emptyList);
+ }
+
+ @Override
+ public List<String> getPropertyNames() {
+ return ObjectHelper.supplyIfEmpty(definition.getPropertyNames(), Collections::emptyList);
+ }
+
+ /**
+ * Read the content of the source as {@link InputStream}.
+ *
+ * @param ctx the {@link CamelContext}
+ * @return the {@link InputStream} representing the source content
+ */
+ @Override
+ public InputStream resolveAsInputStream(CamelContext ctx) {
+ try {
+ InputStream is;
+
+ if (definition.getContent() != null) {
+ is = new ByteArrayInputStream(definition.getContent());
+ } else {
+ is = ResourceHelper.resolveMandatoryResourceAsInputStream(ctx, definition.getLocation());
+ }
+
+ return definition.isCompressed()
+ ? new GZIPInputStream(Base64.getDecoder().wrap(is))
+ : is;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ };
+ }
+
+ // ******************************
+ //
+ // Helpers
+ //
+ // ******************************
+
+ public static Resource asResource(CamelContext camelContext, Source source) {
+ return new Resource() {
+ @Override
+ public String getLocation() {
+ return source.getLocation();
+ }
+
+ @Override
+ public boolean exists() {
+ return true;
+ }
+
+ @Override
+ public InputStream getInputStream() throws IOException {
+ return source.resolveAsInputStream(camelContext);
+ }
+
+ @Override
+ public Reader getReader() throws Exception {
+ return source.resolveAsReader(camelContext);
+ }
+
+ @Override
+ public Reader getReader(Charset charset) throws Exception {
+ return source.resolveAsReader(camelContext, charset);
+ }
+
+ @Override
+ public String getScheme() {
+ return source.getLocation();
+ }
+ };
+ }
+
+ public static SourceDefinition computeDefinitionFromURI(String uri) throws Exception {
+ final String location = StringSupport.substringBefore(uri, "?");
+
+ if (!location.startsWith(Constants.SCHEME_PREFIX_CLASSPATH) && !location.startsWith(Constants.SCHEME_PREFIX_FILE)) {
+ throw new IllegalArgumentException("No valid resource format, expected scheme:path, found " + uri);
+ }
+
+ final String query = StringSupport.substringAfter(uri, "?");
+ final Map<String, Object> params = URISupport.parseQuery(query);
+
+ String language = (String) params.get("language");
+ if (ObjectHelper.isEmpty(language)) {
+ language = StringSupport.substringAfterLast(location, ":");
+ language = StringSupport.substringAfterLast(language, ".");
+ }
+ if (ObjectHelper.isEmpty(language)) {
+ throw new IllegalArgumentException("Unknown language " + language);
+ }
+
+ String name = (String) params.get("name");
+ if (name == null) {
+ name = StringSupport.substringAfter(location, ":");
+ name = StringSupport.substringBeforeLast(name, ".");
+
+ if (name.contains("/")) {
+ name = StringSupport.substringAfterLast(name, "/");
+ }
+ }
+
+ SourceDefinition answer = new SourceDefinition();
+ answer.setId((String) params.get("id"));
+ answer.setLocation(location);
+ answer.setName(name);
+ answer.setLanguage(language);
+ answer.setLoader((String) params.get("loader"));
+ answer.setInterceptors(StringSupport.split((String) params.get("interceptors"), ","));
+ answer.setCompressed(Boolean.parseBoolean((String) params.get("compression")));
+
+ return answer;
+ }
+}
diff --git a/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/support/SourcesSupport.java b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/support/SourcesSupport.java
new file mode 100644
index 0000000000..d88e115e1d
--- /dev/null
+++ b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/support/SourcesSupport.java
@@ -0,0 +1,187 @@
+/*
+ * 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.quarkus.k.support;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.camel.ExtendedCamelContext;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.builder.RouteBuilderLifecycleStrategy;
+import org.apache.camel.model.RouteDefinition;
+import org.apache.camel.model.RouteTemplateDefinition;
+import org.apache.camel.quarkus.k.core.Runtime;
+import org.apache.camel.quarkus.k.core.RuntimeAware;
+import org.apache.camel.quarkus.k.core.Source;
+import org.apache.camel.quarkus.k.core.SourceDefinition;
+import org.apache.camel.quarkus.k.listener.AbstractPhaseListener;
+import org.apache.camel.spi.Resource;
+import org.apache.camel.support.PluginHelper;
+import org.apache.camel.util.ObjectHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class SourcesSupport {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(SourcesSupport.class);
+
+ private SourcesSupport() {
+ }
+
+ public static Runtime.Listener forRoutes(String... sources) {
+ return new AbstractPhaseListener(Runtime.Phase.ConfigureRoutes) {
+ @Override
+ protected void accept(Runtime runtime) {
+ loadSources(runtime, sources);
+ }
+ };
+ }
+
+ public static Runtime.Listener forRoutes(SourceDefinition... definitions) {
+ return new AbstractPhaseListener(Runtime.Phase.ConfigureRoutes) {
+ @Override
+ protected void accept(Runtime runtime) {
+ loadSources(runtime, definitions);
+ }
+ };
+ }
+
+ public static void loadSources(Runtime runtime, String... routes) {
+ for (String route : routes) {
+ if (ObjectHelper.isEmpty(route)) {
+ continue;
+ }
+
+ LOGGER.info("Loading routes from: {}", route);
+
+ try {
+ load(runtime, Sources.fromURI(route));
+ } catch (Exception e) {
+ throw RuntimeCamelException.wrapRuntimeCamelException(e);
+ }
+ }
+ }
+
+ public static void loadSources(Runtime runtime, SourceDefinition... definitions) {
+ for (SourceDefinition definition : definitions) {
+ LOGGER.info("Loading routes from: {}", definition);
+
+ load(runtime, Sources.fromDefinition(definition));
+ }
+ }
+
+ public static void load(Runtime runtime, Source source) {
+ final List<RouteBuilderLifecycleStrategy> interceptors;
+
+ switch (source.getType()) {
+ case source:
+ interceptors = RuntimeSupport.loadInterceptors(runtime.getCamelContext(), source);
+ interceptors.forEach(interceptor -> {
+ if (interceptor instanceof RuntimeAware) {
+ ((RuntimeAware) interceptor).setRuntime(runtime);
+ }
+ });
+
+ break;
+ case template:
+ if (!source.getInterceptors().isEmpty()) {
+ LOGGER.warn("Interceptors associated to the route template {} will be ignored", source.getName());
+ }
+
+ interceptors = List.of(new RouteBuilderLifecycleStrategy() {
+ @Override
+ public void afterConfigure(RouteBuilder builder) {
+ List<RouteDefinition> routes = builder.getRouteCollection().getRoutes();
+ List<RouteTemplateDefinition> templates = builder.getRouteTemplateCollection().getRouteTemplates();
+
+ if (routes.size() != 1) {
+ throw new IllegalArgumentException(
+ "There should be a single route definition when configuring route templates, got "
+ + routes.size());
+ }
+ if (!templates.isEmpty()) {
+ throw new IllegalArgumentException(
+ "There should not be any template definition when configuring route templates, got "
+ + templates.size());
+ }
+
+ // create a new template from the source
+ RouteTemplateDefinition templatesDefinition = builder.getRouteTemplateCollection()
+ .routeTemplate(source.getId());
+ templatesDefinition.setRoute(routes.get(0));
+
+ source.getPropertyNames().forEach(templatesDefinition::templateParameter);
+
+ // remove all routes definitions as they have been translated
+ // in the related route template
+ routes.clear();
+ }
+ });
+ break;
+ case errorHandler:
+ if (!source.getInterceptors().isEmpty()) {
+ LOGGER.warn("Interceptors associated to the error handler {} will be ignored", source.getName());
+ }
+
+ interceptors = List.of(new RouteBuilderLifecycleStrategy() {
+ @Override
+ public void afterConfigure(RouteBuilder builder) {
+ List<RouteDefinition> routes = builder.getRouteCollection().getRoutes();
+ List<RouteTemplateDefinition> templates = builder.getRouteTemplateCollection().getRouteTemplates();
+
+ if (!routes.isEmpty()) {
+ throw new IllegalArgumentException(
+ "There should be no route definition when configuring error handler, got " + routes.size());
+ }
+ if (!templates.isEmpty()) {
+ throw new IllegalArgumentException(
+ "There should not be any template definition when configuring error handler, got "
+ + templates.size());
+ }
+ if (builder.hasErrorHandlerFactory()) {
+ LOGGER.debug("Setting default error handler builder factory as type {}",
+ builder.getErrorHandlerFactory().getClass());
+ runtime.getExtendedCamelContext().setErrorHandlerFactory(builder.getErrorHandlerFactory());
+ }
+ }
+ });
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown source type: " + source.getType());
+ }
+
+ try {
+ final Resource resource = Sources.asResource(runtime.getCamelContext(), source);
+ final ExtendedCamelContext ecc = runtime.getExtendedCamelContext();
+ final Collection<RoutesBuilder> builders = PluginHelper.getRoutesLoader(ecc).findRoutesBuilders(resource);
+
+ builders.stream()
+ .map(RouteBuilder.class::cast)
+ .peek(b -> interceptors.forEach(b::addLifecycleInterceptor))
+ .forEach(runtime::addRoutes);
+ } catch (Exception e) {
+ throw RuntimeCamelException.wrapRuntimeCamelException(e);
+ }
+ }
+
+ public static void loadErrorHandlerSource(Runtime runtime, SourceDefinition errorHandlerSourceDefinition) {
+ LOGGER.info("Loading error handler from: {}", errorHandlerSourceDefinition);
+ load(runtime, Sources.fromDefinition(errorHandlerSourceDefinition));
+ }
+}
diff --git a/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/support/StringSupport.java b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/support/StringSupport.java
new file mode 100644
index 0000000000..370f6fc7f8
--- /dev/null
+++ b/extensions/camel-k/runtime/src/main/java/org/apache/camel/quarkus/k/support/StringSupport.java
@@ -0,0 +1,75 @@
+/*
+ * 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.quarkus.k.support;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.StringHelper;
+
+public final class StringSupport {
+ private StringSupport() {
+ }
+
+ public static String substringBefore(String str, String separator) {
+ String answer = StringHelper.before(str, separator);
+ if (answer == null) {
+ answer = str;
+ }
+
+ return answer;
+ }
+
+ public static String substringAfter(String str, String separator) {
+ String answer = StringHelper.after(str, separator);
+ if (answer == null) {
+ answer = "";
+ }
+
+ return answer;
+ }
+
+ public static String substringAfterLast(String str, String separator) {
+ if (ObjectHelper.isEmpty(str)) {
+ return str;
+ }
+ if (ObjectHelper.isEmpty(separator)) {
+ return "";
+ }
+ int pos = str.lastIndexOf(separator);
+ if (pos == -1 || pos == str.length() - separator.length()) {
+ return "";
+ }
+ return str.substring(pos + separator.length());
+ }
+
+ public static String substringBeforeLast(String str, String separator) {
+ if (ObjectHelper.isEmpty(str) || ObjectHelper.isEmpty(separator)) {
+ return str;
+ }
+ int pos = str.lastIndexOf(separator);
+ if (pos == -1) {
+ return str;
+ }
+ return str.substring(0, pos);
+ }
+
+ public static List<String> split(String input, String regex) {
+ return input != null ? List.of(input.split(regex)) : Collections.emptyList();
+ }
+}
diff --git a/extensions/camel-k/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions/camel-k/runtime/src/main/resources/META-INF/quarkus-extension.yaml
new file mode 100644
index 0000000000..61d12cde1c
--- /dev/null
+++ b/extensions/camel-k/runtime/src/main/resources/META-INF/quarkus-extension.yaml
@@ -0,0 +1,33 @@
+#
+# 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.
+#
+
+# This is a generated file. Do not edit directly!
+# To re-generate, run the following command from the top level directory:
+#
+# mvn -N cq:update-quarkus-metadata
+#
+---
+name: "Camel K"
+description: "Camel runtime specialization for Camel K"
+icon-url: "https://camel.apache.org/_/img/logo-d-f21b25ba38.svg"
+metadata:
+ unlisted: true
+ guide: "https://camel.apache.org/camel-quarkus/latest/reference/extensions/camel-k.html"
+ categories:
+ - "integration"
+ status:
+ - "stable"
diff --git a/extensions/camel-k/runtime/src/main/resources/META-INF/services/org.apache.camel.quarkus.k.core.Runtime$Listener b/extensions/camel-k/runtime/src/main/resources/META-INF/services/org.apache.camel.quarkus.k.core.Runtime$Listener
new file mode 100644
index 0000000000..bdd638af63
--- /dev/null
+++ b/extensions/camel-k/runtime/src/main/resources/META-INF/services/org.apache.camel.quarkus.k.core.Runtime$Listener
@@ -0,0 +1,19 @@
+#
+# 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.
+#
+
+org.apache.camel.quarkus.k.listener.ContextConfigurer
+org.apache.camel.quarkus.k.listener.SourcesConfigurer
diff --git a/extensions/camel-k/runtime/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSourceProvider b/extensions/camel-k/runtime/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSourceProvider
new file mode 100644
index 0000000000..060b38082f
--- /dev/null
+++ b/extensions/camel-k/runtime/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSourceProvider
@@ -0,0 +1,17 @@
+#
+# 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.
+#
+org.apache.camel.quarkus.k.runtime.ApplicationConfigSourceProvider
\ No newline at end of file
diff --git a/extensions/camel-k/runtime/src/test/java/org/apache/camel/quarkus/k/SourceTest.java b/extensions/camel-k/runtime/src/test/java/org/apache/camel/quarkus/k/SourceTest.java
new file mode 100644
index 0000000000..7942c0295c
--- /dev/null
+++ b/extensions/camel-k/runtime/src/test/java/org/apache/camel/quarkus/k/SourceTest.java
@@ -0,0 +1,54 @@
+/*
+ * 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.quarkus.k;
+
+import org.apache.camel.quarkus.k.core.SourceDefinition;
+import org.apache.camel.quarkus.k.support.Sources;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.AssertionsForClassTypes.assertThatExceptionOfType;
+
+public class SourceTest {
+ @Test
+ public void testResourceWithoutScheme() {
+ assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(
+ () -> Sources.fromURI("routes.js"));
+ }
+
+ @Test
+ public void testResourceWithIllegalScheme() {
+ assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(
+ () -> Sources.fromURI("http:routes.js"));
+ }
+
+ @Test
+ public void testUnsupportedLanguage() {
+ assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(
+ () -> Sources.fromURI(" test"));
+ }
+
+ @Test
+ public void sourceCanBeContructedFromLocation() {
+ SourceDefinition definition = new SourceDefinition();
+ definition.setLocation("classpath:MyRoutes.java");
+
+ assertThat(Sources.fromDefinition(definition))
+ .hasFieldOrPropertyWithValue("name", "MyRoutes")
+ .hasFieldOrPropertyWithValue("language", "java");
+ }
+}
diff --git a/extensions/camel-k/runtime/src/test/java/org/apache/camel/quarkus/k/listener/PropertiesFunctionsConfigurerTest.java b/extensions/camel-k/runtime/src/test/java/org/apache/camel/quarkus/k/listener/PropertiesFunctionsConfigurerTest.java
new file mode 100644
index 0000000000..b715c6b991
--- /dev/null
+++ b/extensions/camel-k/runtime/src/test/java/org/apache/camel/quarkus/k/listener/PropertiesFunctionsConfigurerTest.java
@@ -0,0 +1,55 @@
+/*
+ * 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.quarkus.k.listener;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.quarkus.k.core.Runtime;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+public class PropertiesFunctionsConfigurerTest {
+
+ @Test
+ public void testKubernetesFunction() {
+ Runtime runtime = Runtime.on(new DefaultCamelContext());
+ runtime.setProperties("my.property", "{{secret:my-secret/my-property}}");
+
+ assertThat(runtime.getCamelContext().resolvePropertyPlaceholders("{{secret:my-secret/my-property}}"))
+ .isEqualTo("my-secret-property");
+ assertThat(runtime.getCamelContext().resolvePropertyPlaceholders("{{secret:none/my-property:my-default-secret}}"))
+ .isEqualTo("my-default-secret");
+ CamelContext context = runtime.getCamelContext();
+
+ assertThatThrownBy(() -> context.resolvePropertyPlaceholders("{{secret:none/my-property}}"))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("returned null value which is not allowed, from input");
+
+ assertThat(runtime.getCamelContext().resolvePropertyPlaceholders("{{configmap:my-cm/my-property}}"))
+ .isEqualTo("my-cm-property");
+ assertThat(runtime.getCamelContext().resolvePropertyPlaceholders("{{configmap:my-cm/my-property:my-default-cm}}"))
+ .isEqualTo("my-default-cm");
+
+ assertThatThrownBy(() -> context.resolvePropertyPlaceholders("{{configmap:none/my-property}}"))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("returned null value which is not allowed, from input");
+
+ assertThat(runtime.getCamelContext().resolvePropertyPlaceholders("{{my.property}}")).isEqualTo("my-secret-property");
+ }
+}
diff --git a/extensions/camel-k/runtime/src/test/java/org/apache/camel/quarkus/k/listener/SourceConfigurerTest.java b/extensions/camel-k/runtime/src/test/java/org/apache/camel/quarkus/k/listener/SourceConfigurerTest.java
new file mode 100644
index 0000000000..9a727d855e
--- /dev/null
+++ b/extensions/camel-k/runtime/src/test/java/org/apache/camel/quarkus/k/listener/SourceConfigurerTest.java
@@ -0,0 +1,143 @@
+/*
+ * 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.quarkus.k.listener;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.quarkus.k.core.SourceType;
+import org.apache.camel.quarkus.k.support.PropertiesSupport;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import static org.apache.camel.util.PropertiesHelper.asProperties;
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class SourceConfigurerTest {
+ @Test
+ public void shouldLoadMultipleSources() {
+ CamelContext context = new DefaultCamelContext();
+ context.getPropertiesComponent().setInitialProperties(asProperties(
+ "camel.k.sources[0].name", "templateName",
+ "camel.k.sources[0].location", "classpath:MyTemplate.java",
+ "camel.k.sources[0].type", "template",
+ "camel.k.sources[1].name", "src",
+ "camel.k.sources[1].location", "classpath:MySrc.java",
+ "camel.k.sources[2].name", "err",
+ "camel.k.sources[2].location", "classpath:Err.java",
+ "camel.k.sources[2].type", "errorHandler"));
+
+ SourcesConfigurer configuration = new SourcesConfigurer();
+
+ PropertiesSupport.bindProperties(
+ context,
+ configuration,
+ k -> k.startsWith(SourcesConfigurer.CAMEL_K_SOURCES_PREFIX),
+ SourcesConfigurer.CAMEL_K_PREFIX);
+
+ assertThat(configuration.getSources()).hasSize(3);
+ }
+
+ @Test
+ public void shouldFailOnMultipleErrorHandlers() {
+ CamelContext context = new DefaultCamelContext();
+ context.getPropertiesComponent().setInitialProperties(asProperties(
+ "camel.k.sources[0].name", "templateName0",
+ "camel.k.sources[0].location", "classpath:MyTemplate1.java",
+ "camel.k.sources[0].type", "template",
+ "camel.k.sources[1].name", "err1",
+ "camel.k.sources[1].location", "classpath:Err1.java",
+ "camel.k.sources[1].type", "errorHandler",
+ "camel.k.sources[2].name", "err2",
+ "camel.k.sources[2].location", "classpath:Err2.java",
+ "camel.k.sources[2].type", "errorHandler"));
+
+ SourcesConfigurer configuration = new SourcesConfigurer();
+
+ PropertiesSupport.bindProperties(
+ context,
+ configuration,
+ k -> k.startsWith(SourcesConfigurer.CAMEL_K_SOURCES_PREFIX),
+ SourcesConfigurer.CAMEL_K_PREFIX);
+
+ assertThat(configuration.getSources()).hasSize(3);
+ Assertions.assertThrows(IllegalArgumentException.class, () -> {
+ SourcesConfigurer.checkUniqueErrorHandler(configuration.getSources());
+ }, "java.lang.IllegalArgumentException: Expected only one error handler source type, got 2");
+ }
+
+ @Test
+ public void shouldDefaultSourcesWithEmptyType() {
+ CamelContext context = new DefaultCamelContext();
+ context.getPropertiesComponent().setInitialProperties(asProperties(
+ "camel.k.sources[0].name", "source0",
+ "camel.k.sources[1].name", "source1",
+ "camel.k.sources[2].name", "source2",
+ "camel.k.sources[2].type", "source"));
+
+ SourcesConfigurer configuration = new SourcesConfigurer();
+
+ PropertiesSupport.bindProperties(
+ context,
+ configuration,
+ k -> k.startsWith(SourcesConfigurer.CAMEL_K_SOURCES_PREFIX),
+ SourcesConfigurer.CAMEL_K_PREFIX);
+
+ assertThat(configuration.getSources().length).isEqualTo(3);
+ assertThat(configuration.getSources()[0].getType()).isEqualTo(SourceType.source);
+ assertThat(configuration.getSources()[1].getType()).isEqualTo(SourceType.source);
+ assertThat(configuration.getSources()[2].getType()).isEqualTo(SourceType.source);
+ }
+
+ @Test
+ public void shouldOrderSourcesByType() {
+ CamelContext context = new DefaultCamelContext();
+ context.getPropertiesComponent().setInitialProperties(asProperties(
+ "camel.k.sources[0].name", "template1",
+ "camel.k.sources[0].type", "template",
+ "camel.k.sources[1].name", "source1",
+ "camel.k.sources[1].type", "source",
+ "camel.k.sources[2].name", "source2",
+ "camel.k.sources[3].name", "errorHandler1",
+ "camel.k.sources[3].type", "errorHandler"));
+
+ SourcesConfigurer configuration = new SourcesConfigurer();
+
+ PropertiesSupport.bindProperties(
+ context,
+ configuration,
+ k -> k.startsWith(SourcesConfigurer.CAMEL_K_SOURCES_PREFIX),
+ SourcesConfigurer.CAMEL_K_PREFIX);
+ SourcesConfigurer.sortSources(configuration.getSources());
+
+ assertThat(configuration.getSources()).hasSize(4);
+ assertThat(configuration.getSources()[0].getName()).isEqualTo("errorHandler1");
+ assertThat(configuration.getSources()[0].getType()).isEqualTo(SourceType.errorHandler);
+ assertThat(configuration.getSources()[1].getName()).isEqualTo("template1");
+ assertThat(configuration.getSources()[1].getType()).isEqualTo(SourceType.template);
+ // Order for the same type does not matter
+ assertThat(configuration.getSources()[2].getName()).contains("source");
+ assertThat(configuration.getSources()[2].getType()).isEqualTo(SourceType.source);
+ assertThat(configuration.getSources()[3].getName()).contains("source");
+ assertThat(configuration.getSources()[3].getType()).isEqualTo(SourceType.source);
+ }
+
+ @Test
+ public void shouldNotFailOnEmptySources() {
+ SourcesConfigurer.sortSources(null);
+ SourcesConfigurer.checkUniqueErrorHandler(null);
+ }
+}
diff --git a/extensions/camel-k/runtime/src/test/java/org/apache/camel/quarkus/k/support/NameCustomizer.java b/extensions/camel-k/runtime/src/test/java/org/apache/camel/quarkus/k/support/NameCustomizer.java
new file mode 100644
index 0000000000..e0033e3f1a
--- /dev/null
+++ b/extensions/camel-k/runtime/src/test/java/org/apache/camel/quarkus/k/support/NameCustomizer.java
@@ -0,0 +1,45 @@
+/*
+ * 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.quarkus.k.support;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Ordered;
+import org.apache.camel.impl.engine.ExplicitCamelContextNameStrategy;
+import org.apache.camel.spi.CamelContextCustomizer;
+
+public final class NameCustomizer implements CamelContextCustomizer {
+
+ private String name;
+
+ public NameCustomizer() {
+ this("default");
+ }
+
+ public NameCustomizer(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public int getOrder() {
+ return Ordered.HIGHEST;
+ }
+
+ @Override
+ public void configure(CamelContext camelContext) {
+ camelContext.setNameStrategy(new ExplicitCamelContextNameStrategy(name));
+ }
+}
diff --git a/extensions/camel-k/runtime/src/test/java/org/apache/camel/quarkus/k/support/PropertiesSupportTest.java b/extensions/camel-k/runtime/src/test/java/org/apache/camel/quarkus/k/support/PropertiesSupportTest.java
new file mode 100644
index 0000000000..2c11d02d19
--- /dev/null
+++ b/extensions/camel-k/runtime/src/test/java/org/apache/camel/quarkus/k/support/PropertiesSupportTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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.quarkus.k.support;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.function.Predicate;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.quarkus.k.core.SourceDefinition;
+import org.apache.camel.quarkus.k.listener.SourcesConfigurer;
+import org.junit.jupiter.api.Test;
+
+import static org.apache.camel.util.PropertiesHelper.asProperties;
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class PropertiesSupportTest {
+ @Test
+ public void propertiesAreBoundToSourcesConfigurer() {
+ CamelContext context = new DefaultCamelContext();
+ context.getPropertiesComponent().setInitialProperties(asProperties(
+ "camel.k.sources[0].name", "MyRoutesWithBeans",
+ "camel.k.sources[0].location", "classpath:MyRoutesWithBeans.java",
+ "camel.k.sources[1].name", "MyRoutesConfig",
+ "camel.k.sources[1].location", "classpath:MyRoutesConfig.java",
+ "camel.k.sources[1].property-names[0]", "foo",
+ "camel.k.sources[1].property-names[1]", "bar"));
+
+ SourcesConfigurer configuration = new SourcesConfigurer();
+
+ PropertiesSupport.bindProperties(
+ context,
+ configuration,
+ k -> k.startsWith(SourcesConfigurer.CAMEL_K_SOURCES_PREFIX),
+ SourcesConfigurer.CAMEL_K_PREFIX);
+
+ assertThat(configuration.getSources())
+ .hasSize(2)
+ .anyMatch(byNameAndLocation("MyRoutesWithBeans", "classpath:MyRoutesWithBeans.java")
+ .and(d -> d.getPropertyNames() == null))
+ .anyMatch(byNameAndLocation("MyRoutesConfig", "classpath:MyRoutesConfig.java")
+ .and(d -> d.getPropertyNames() != null && d.getPropertyNames().containsAll(List.of("foo", "bar"))));
+ }
+
+ @Test
+ public void propertiesWithGapsAreBoundToSourcesConfigurer() {
+ CamelContext context = new DefaultCamelContext();
+ context.getPropertiesComponent().setInitialProperties(asProperties(
+ "camel.k.sources[0].name", "MyRoutesWithBeans",
+ "camel.k.sources[0].location", "classpath:MyRoutesWithBeans.java",
+ "camel.k.sources[2].name", "MyRoutesConfig",
+ "camel.k.sources[2].location", "classpath:MyRoutesConfig.java"));
+
+ SourcesConfigurer configuration = new SourcesConfigurer();
+
+ PropertiesSupport.bindProperties(
+ context,
+ configuration,
+ k -> k.startsWith(SourcesConfigurer.CAMEL_K_SOURCES_PREFIX),
+ SourcesConfigurer.CAMEL_K_PREFIX);
+
+ assertThat(configuration.getSources())
+ .hasSize(3)
+ .filteredOn(Objects::nonNull)
+ .hasSize(2)
+ .anyMatch(byNameAndLocation("MyRoutesWithBeans", "classpath:MyRoutesWithBeans.java"))
+ .anyMatch(byNameAndLocation("MyRoutesConfig", "classpath:MyRoutesConfig.java"));
+ }
+
+ // ***************************
+ //
+ // Helpers
+ //
+ // ***************************
+
+ private static Predicate<SourceDefinition> byNameAndLocation(String name, String location) {
+ return def -> Objects.equals(def.getName(), name) && Objects.equals(def.getLocation(), location);
+ }
+}
diff --git a/extensions/camel-k/runtime/src/test/java/org/apache/camel/quarkus/k/support/RuntimeSupportTest.java b/extensions/camel-k/runtime/src/test/java/org/apache/camel/quarkus/k/support/RuntimeSupportTest.java
new file mode 100644
index 0000000000..393ba49370
--- /dev/null
+++ b/extensions/camel-k/runtime/src/test/java/org/apache/camel/quarkus/k/support/RuntimeSupportTest.java
@@ -0,0 +1,194 @@
+/*
+ * 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.quarkus.k.support;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Ordered;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.impl.engine.ExplicitCamelContextNameStrategy;
+import org.apache.camel.spi.CamelContextCustomizer;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class RuntimeSupportTest {
+
+ @Test
+ public void testLoadCustomizersWithPropertiesFlags() {
+ CamelContext context = new DefaultCamelContext();
+
+ NameCustomizer customizer = new NameCustomizer("from-registry");
+ context.getRegistry().bind("name", customizer);
+
+ List<CamelContextCustomizer> customizers = RuntimeSupport.configureContextCustomizers(context);
+ assertThat(context.getName()).isNotEqualTo("from-registry");
+ assertThat(context.getName()).isNotEqualTo("default");
+ assertThat(customizers).isEmpty();
+
+ Properties properties = new Properties();
+ properties.setProperty("camel.k.customizer.name.enabled", "true");
+ context.getPropertiesComponent().setInitialProperties(properties);
+
+ customizers = RuntimeSupport.configureContextCustomizers(context);
+ assertThat(context.getName()).isEqualTo("from-registry");
+ assertThat(customizers).hasSize(1);
+ }
+
+ @Test
+ public void testLoadCustomizersWithList() {
+ CamelContext context = new DefaultCamelContext();
+
+ NameCustomizer customizer = new NameCustomizer("from-registry");
+ context.getRegistry().bind("name", customizer);
+
+ List<CamelContextCustomizer> customizers = RuntimeSupport.configureContextCustomizers(context);
+ assertThat(context.getName()).isNotEqualTo("from-registry");
+ assertThat(context.getName()).isNotEqualTo("default");
+ assertThat(customizers).isEmpty();
+
+ Properties properties = new Properties();
+ properties.setProperty(Constants.PROPERTY_CAMEL_K_CUSTOMIZER, "name");
+ context.getPropertiesComponent().setInitialProperties(properties);
+
+ customizers = RuntimeSupport.configureContextCustomizers(context);
+ assertThat(context.getName()).isEqualTo("from-registry");
+ assertThat(customizers).hasSize(1);
+ }
+
+ @Test
+ public void testLoadCustomizers() {
+ CamelContext context = new DefaultCamelContext();
+ context.getRegistry().bind("converters",
+ (CamelContextCustomizer) camelContext -> camelContext.setLoadTypeConverters(true));
+
+ List<CamelContextCustomizer> customizers = RuntimeSupport.configureContextCustomizers(context);
+ assertThat(context.getName()).isNotEqualTo("from-registry");
+ assertThat(context.getName()).isNotEqualTo("default");
+ assertThat(context.isLoadTypeConverters()).isFalse();
+ assertThat(customizers).isEmpty();
+
+ Properties properties = new Properties();
+ properties.setProperty("camel.k.customizer.name.enabled", "true");
+ context.getPropertiesComponent().setInitialProperties(properties);
+
+ customizers = RuntimeSupport.configureContextCustomizers(context);
+ assertThat(context.getName()).isEqualTo("default");
+ assertThat(customizers).hasSize(1);
+
+ properties.setProperty("camel.k.customizer.converters.enabled", "true");
+ context.getPropertiesComponent().setInitialProperties(properties);
+
+ customizers = RuntimeSupport.configureContextCustomizers(context);
+ assertThat(context.getName()).isEqualTo("default");
+ assertThat(context.isLoadTypeConverters()).isTrue();
+ assertThat(customizers).hasSize(2);
+ }
+
+ @Test
+ public void testLoadCustomizersFallback() {
+ CamelContext context = new DefaultCamelContext();
+ context.getRegistry().bind("converters",
+ (CamelContextCustomizer) camelContext -> camelContext.setLoadTypeConverters(true));
+
+ List<CamelContextCustomizer> customizers = RuntimeSupport.configureContextCustomizers(context);
+ assertThat(context.getName()).isNotEqualTo("from-registry");
+ assertThat(context.getName()).isNotEqualTo("default");
+ assertThat(context.isLoadTypeConverters()).isFalse();
+ assertThat(customizers).isEmpty();
+
+ Properties properties = new Properties();
+ properties.setProperty("customizer.name.enabled", "true");
+ context.getPropertiesComponent().setInitialProperties(properties);
+
+ customizers = RuntimeSupport.configureContextCustomizers(context);
+ assertThat(context.getName()).isEqualTo("default");
+ assertThat(customizers).hasSize(1);
+
+ properties.setProperty("customizer.converters.enabled", "true");
+ properties.setProperty("customizer.converters.enabled", "true");
+ context.getPropertiesComponent().setInitialProperties(properties);
+
+ customizers = RuntimeSupport.configureContextCustomizers(context);
+ assertThat(context.getName()).isEqualTo("default");
+ assertThat(context.isLoadTypeConverters()).isTrue();
+ assertThat(customizers).hasSize(2);
+ }
+
+ @Test
+ public void testLoadCustomizerOrder() {
+ DefaultCamelContext context = new DefaultCamelContext();
+ context.setName("camel");
+ context.getRegistry().bind("c1", new CamelContextCustomizer() {
+ @Override
+ public int getOrder() {
+ return Ordered.LOWEST;
+ }
+
+ @Override
+ public void configure(CamelContext camelContext) {
+ camelContext.setNameStrategy(new ExplicitCamelContextNameStrategy(camelContext.getName() + "-c1"));
+ }
+ });
+ context.getRegistry().bind("c2", new CamelContextCustomizer() {
+ @Override
+ public int getOrder() {
+ return Ordered.HIGHEST;
+ }
+
+ @Override
+ public void configure(CamelContext camelContext) {
+ camelContext.setNameStrategy(new ExplicitCamelContextNameStrategy(camelContext.getName() + "-c2"));
+ }
+ });
+ context.getRegistry().bind("c3", new CamelContextCustomizer() {
+ @Override
+ public void configure(CamelContext camelContext) {
+ camelContext.setNameStrategy(new ExplicitCamelContextNameStrategy(camelContext.getName() + "-c3"));
+ }
+ });
+
+ Properties properties = new Properties();
+ properties.setProperty("camel.k.customizer.c1.enabled", "true");
+ properties.setProperty("camel.k.customizer.c2.enabled", "true");
+ properties.setProperty("camel.k.customizer.c3.enabled", "true");
+
+ context.getPropertiesComponent().setInitialProperties(properties);
+
+ List<CamelContextCustomizer> customizers = RuntimeSupport.configureContextCustomizers(context);
+ assertThat(customizers).hasSize(3);
+ assertThat(context.getName()).isEqualTo("camel-c2-c3-c1");
+ }
+
+ @Test
+ public void shouldLoadUsePropertiesFromTextConfigMap() {
+ System.setProperty(Constants.PROPERTY_CAMEL_K_CONF_D, getClass().getResource("/configmaps/my-cm").getFile());
+ Map<String, String> loadedProperties = RuntimeSupport.loadUserProperties();
+ assertThat(loadedProperties).hasSize(1);
+ assertThat(loadedProperties.get("my-property")).isEqualTo("my-cm-property");
+ }
+
+ @Test
+ public void shouldSkipLoadUsePropertiesFromBinaryConfigMap() {
+ System.setProperty(Constants.PROPERTY_CAMEL_K_CONF_D, getClass().getResource("/configmaps/my-binary-cm").getFile());
+ Map<String, String> loadedProperties = RuntimeSupport.loadUserProperties();
+ assertThat(loadedProperties).isEmpty();
+ }
+}
diff --git a/extensions/camel-k/runtime/src/test/resources/META-INF/services/org.apache.camel.quarkus.k/customizer/name b/extensions/camel-k/runtime/src/test/resources/META-INF/services/org.apache.camel.quarkus.k/customizer/name
new file mode 100644
index 0000000000..26286751d8
--- /dev/null
+++ b/extensions/camel-k/runtime/src/test/resources/META-INF/services/org.apache.camel.quarkus.k/customizer/name
@@ -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.
+#
+
+class=org.apache.camel.quarkus.k.support.NameCustomizer
\ No newline at end of file
diff --git a/extensions/camel-k/runtime/src/test/resources/configmaps/my-binary-cm/my-property.zip b/extensions/camel-k/runtime/src/test/resources/configmaps/my-binary-cm/my-property.zip
new file mode 100644
index 0000000000..39610526e3
Binary files /dev/null and b/extensions/camel-k/runtime/src/test/resources/configmaps/my-binary-cm/my-property.zip differ
diff --git a/extensions/camel-k/runtime/src/test/resources/configmaps/my-cm/my-property b/extensions/camel-k/runtime/src/test/resources/configmaps/my-cm/my-property
new file mode 100644
index 0000000000..38c6ea5bd6
--- /dev/null
+++ b/extensions/camel-k/runtime/src/test/resources/configmaps/my-cm/my-property
@@ -0,0 +1 @@
+my-cm-property
\ No newline at end of file
diff --git a/extensions/camel-k/runtime/src/test/resources/my-cp-resource.txt b/extensions/camel-k/runtime/src/test/resources/my-cp-resource.txt
new file mode 100644
index 0000000000..64ec491e4d
--- /dev/null
+++ b/extensions/camel-k/runtime/src/test/resources/my-cp-resource.txt
@@ -0,0 +1 @@
+my cp content
\ No newline at end of file
diff --git a/extensions/camel-k/runtime/src/test/resources/my-file-resource.txt b/extensions/camel-k/runtime/src/test/resources/my-file-resource.txt
new file mode 100644
index 0000000000..63d3cca605
--- /dev/null
+++ b/extensions/camel-k/runtime/src/test/resources/my-file-resource.txt
@@ -0,0 +1 @@
+my file content
\ No newline at end of file
diff --git a/extensions/camel-k/runtime/src/test/resources/secrets/my-secret/my-property b/extensions/camel-k/runtime/src/test/resources/secrets/my-secret/my-property
new file mode 100644
index 0000000000..01b39e434e
--- /dev/null
+++ b/extensions/camel-k/runtime/src/test/resources/secrets/my-secret/my-property
@@ -0,0 +1 @@
+my-secret-property
\ No newline at end of file
diff --git a/extensions/pom.xml b/extensions/pom.xml
index f318d7f4d8..ab26cb300d 100644
--- a/extensions/pom.xml
+++ b/extensions/pom.xml
@@ -72,6 +72,7 @@
<module>braintree</module>
<module>browse</module>
<module>caffeine</module>
+ <module>camel-k</module>
<module>cassandraql</module>
<module>cbor</module>
<module>cloudevents</module>
diff --git a/integration-tests/camel-k-runtime/pom.xml b/integration-tests/camel-k-runtime/pom.xml
new file mode 100644
index 0000000000..43d862feb0
--- /dev/null
+++ b/integration-tests/camel-k-runtime/pom.xml
@@ -0,0 +1,187 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-build-parent-it</artifactId>
+ <version>3.3.0-SNAPSHOT</version>
+ <relativePath>../../poms/build-parent-it/pom.xml</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>camel-quarkus-integration-test-camel-k-runtime</artifactId>
+ <name>Camel Quarkus :: Integration Tests :: Camel K Runtime</name>
+ <description>Integration tests for Camel Quarkus K Runtime extension</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-camel-k</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-yaml-dsl</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-xml-io-dsl</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-timer</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-log</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-rest</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-platform-http</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-direct</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-knative</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-jsonb</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-resteasy</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-resteasy-jsonb</artifactId>
+ </dependency>
+
+ <!-- test dependencies -->
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-junit5</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>io.rest-assured</groupId>
+ <artifactId>rest-assured</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <environmentVariables>
+ <CAMEL_K_CONF>${project.basedir}/src/test/resources/conf.properties</CAMEL_K_CONF>
+ <CAMEL_K_CONF_D>${project.basedir}/src/test/resources/conf.d</CAMEL_K_CONF_D>
+ </environmentVariables>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>native</id>
+ <activation>
+ <property>
+ <name>native</name>
+ </property>
+ </activation>
+ <properties>
+ <quarkus.package.type>native</quarkus.package.type>
+ </properties>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>integration-test</goal>
+ <goal>verify</goal>
+ </goals>
+ <configuration>
+ <environmentVariables>
+ <CAMEL_K_CONF>${project.basedir}/src/test/resources/conf.properties</CAMEL_K_CONF>
+ <CAMEL_K_CONF_D>${project.basedir}/src/test/resources/conf.d</CAMEL_K_CONF_D>
+ </environmentVariables>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>virtualDependencies</id>
+ <activation>
+ <property>
+ <name>!noVirtualDependencies</name>
+ </property>
+ </activation>
+ <dependencies>
+ <!-- The following dependencies guarantee that this module is built after them. You can update them by running `mvn process-resources -Pformat -N` from the source tree root directory -->
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-yaml-dsl-deployment</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>*</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ </dependencies>
+ </profile>
+ <profile>
+ <id>skip-testcontainers-tests</id>
+ <activation>
+ <property>
+ <name>skip-testcontainers-tests</name>
+ </property>
+ </activation>
+ <properties>
+ <skipTests>true</skipTests>
+ </properties>
+ </profile>
+ </profiles>
+</project>
diff --git a/integration-tests/camel-k-runtime/src/main/java/org/apache/camel/quarkus/k/it/Application.java b/integration-tests/camel-k-runtime/src/main/java/org/apache/camel/quarkus/k/it/Application.java
new file mode 100644
index 0000000000..d498de2f60
--- /dev/null
+++ b/integration-tests/camel-k-runtime/src/main/java/org/apache/camel/quarkus/k/it/Application.java
@@ -0,0 +1,108 @@
+/*
+ * 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.quarkus.k.it;
+
+import java.util.Collections;
+import java.util.Map;
+
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
+import jakarta.json.Json;
+import jakarta.json.JsonObject;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.core.MediaType;
+import org.apache.camel.CamelContext;
+import org.apache.camel.component.properties.PropertiesComponent;
+import org.apache.camel.main.BaseMainSupport;
+import org.apache.camel.quarkus.k.core.Runtime;
+import org.apache.camel.quarkus.main.CamelMain;
+
+import static org.apache.camel.quarkus.k.runtime.Application.instance;
+
+@Path("/camel-k")
+@ApplicationScoped
+public class Application {
+
+ @Inject
+ CamelContext camelContext;
+
+ @GET
+ @Path("/inspect")
+ @Produces(MediaType.APPLICATION_JSON)
+ @SuppressWarnings("unchecked")
+ 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(
+ "routes-collector",
+ instance(CamelMain.class).map(BaseMainSupport::getRoutesCollector).map(Object::getClass)
+ .map(Class::getName).orElse(""))
+ .add(
+ "global-options",
+ Json.createObjectBuilder(
+ (Map) instance(CamelMain.class)
+ .map(BaseMainSupport::getCamelContext)
+ .map(CamelContext::getGlobalOptions)
+ .orElseGet(Collections::emptyMap))
+ .build())
+ .build();
+ }
+
+ @GET
+ @Path("/inspect/context")
+ @Produces(MediaType.APPLICATION_JSON)
+ public JsonObject inspectContext() {
+ return Json.createObjectBuilder()
+ .add("message-history", camelContext.isMessageHistory())
+ .add("load-type-converters", camelContext.isLoadTypeConverters())
+ .add("name", camelContext.getName())
+ .build();
+ }
+
+ @GET
+ @Path("/property/{name}")
+ @Produces(MediaType.TEXT_PLAIN)
+ public String property(@PathParam("name") String name) {
+ return instance(CamelContext.class)
+ .map(CamelContext::getPropertiesComponent)
+ .map(PropertiesComponent.class::cast)
+ .flatMap(pc -> pc.resolveProperty(name)).orElse("");
+ }
+
+ @SuppressWarnings("unchecked")
+ @GET
+ @Path("/properties")
+ @Produces(MediaType.APPLICATION_JSON)
+ public JsonObject properties() {
+ return Json.createObjectBuilder(
+ instance(CamelContext.class)
+ .map(CamelContext::getPropertiesComponent)
+ .map(PropertiesComponent.class::cast)
+ .map(PropertiesComponent::loadProperties)
+ .map(Map.class::cast)
+ .orElseGet(Collections::emptyMap))
+ .build();
+ }
+}
diff --git a/integration-tests/camel-k-runtime/src/main/java/org/apache/camel/quarkus/k/it/RuntimeInspector.java b/integration-tests/camel-k-runtime/src/main/java/org/apache/camel/quarkus/k/it/RuntimeInspector.java
new file mode 100644
index 0000000000..cb186d1c88
--- /dev/null
+++ b/integration-tests/camel-k-runtime/src/main/java/org/apache/camel/quarkus/k/it/RuntimeInspector.java
@@ -0,0 +1,111 @@
+/*
+ * 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.quarkus.k.it;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
+import jakarta.json.Json;
+import jakarta.json.JsonArray;
+import jakarta.json.JsonObject;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.core.MediaType;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Route;
+import org.apache.camel.model.Model;
+import org.apache.camel.model.RouteDefinition;
+import org.apache.camel.model.ToDefinition;
+import org.apache.camel.model.rest.RestDefinition;
+import org.eclipse.microprofile.config.Config;
+
+import static org.apache.camel.model.ProcessorDefinitionHelper.filterTypeInOutputs;
+
+@Path("/camel-k/runtime")
+@ApplicationScoped
+public class RuntimeInspector {
+ @Inject
+ CamelContext camelContext;
+ @Inject
+ Config config;
+
+ @GET
+ @Path("/inspect")
+ @Produces(MediaType.APPLICATION_JSON)
+ public JsonObject inspect() {
+ return Json.createObjectBuilder()
+ .add("routes", Json.createArrayBuilder(
+ camelContext.getRoutes().stream()
+ .map(Route::getId)
+ .collect(Collectors.toList())))
+ .add("route-definitions", Json.createArrayBuilder(
+ camelContext.getCamelContextExtension().getContextPlugin(Model.class).getRouteDefinitions().stream()
+ .map(RouteDefinition::getId)
+ .collect(Collectors.toList())))
+ .add("rest-definitions", Json.createArrayBuilder(
+ camelContext.getCamelContextExtension().getContextPlugin(Model.class).getRestDefinitions().stream()
+ .map(RestDefinition::getId)
+ .collect(Collectors.toList())))
+ .build();
+ }
+
+ @GET
+ @Path("/property/{name}")
+ @Produces(MediaType.TEXT_PLAIN)
+ public String property(@PathParam("name") String name) {
+ return config.getValue(name, String.class);
+ }
+
+ @GET
+ @Path("/registry/beans/{name}")
+ @Produces(MediaType.APPLICATION_JSON)
+ public String bean(@PathParam("name") String name) throws Exception {
+ Object bean = camelContext.getRegistry().lookupByName(name);
+ if (bean == null) {
+ throw new IllegalArgumentException("Bean with name: " + name + " not found");
+ }
+
+ try (Jsonb jsonb = JsonbBuilder.create()) {
+ return jsonb.toJson(bean);
+ }
+ }
+
+ @GET
+ @Path("/route-outputs/{name}")
+ @Produces(MediaType.APPLICATION_JSON)
+ public JsonArray routeOutputs(@PathParam("name") String name) {
+ RouteDefinition def = camelContext.getCamelContextExtension().getContextPlugin(Model.class).getRouteDefinition(name);
+ if (def == null) {
+ throw new IllegalArgumentException("RouteDefinition with name: " + name + " not found");
+ }
+
+ Collection<ToDefinition> toDefinitions = filterTypeInOutputs(def.getOutputs(), ToDefinition.class);
+
+ List<String> endpoints = toDefinitions.stream()
+ .map(td -> td.getEndpointUri())
+ .collect(Collectors.toList());
+
+ return Json.createArrayBuilder(endpoints).build();
+ }
+}
diff --git a/integration-tests/camel-k-runtime/src/main/java/org/apache/camel/quarkus/k/it/yaml/BeanProducers.java b/integration-tests/camel-k-runtime/src/main/java/org/apache/camel/quarkus/k/it/yaml/BeanProducers.java
new file mode 100644
index 0000000000..f5d2f8c462
--- /dev/null
+++ b/integration-tests/camel-k-runtime/src/main/java/org/apache/camel/quarkus/k/it/yaml/BeanProducers.java
@@ -0,0 +1,36 @@
+/*
+ * 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.quarkus.k.it.yaml;
+
+import io.quarkus.arc.Unremovable;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.inject.Produces;
+import org.apache.camel.component.knative.spi.Knative;
+import org.apache.camel.component.knative.spi.KnativeEnvironment;
+
+@ApplicationScoped
+public class BeanProducers {
+ @Unremovable
+ @Produces
+ KnativeEnvironment knativeEnvironment() {
+ return KnativeEnvironment.on(
+ KnativeEnvironment.serviceBuilder(Knative.Type.endpoint, "sink")
+ .withUrl("http://localhost:8080")
+ .withEndpointKind(Knative.EndpointKind.sink)
+ .build());
+ }
+}
diff --git a/integration-tests/camel-k-runtime/src/main/java/org/apache/camel/quarkus/k/it/yaml/MyBean.java b/integration-tests/camel-k-runtime/src/main/java/org/apache/camel/quarkus/k/it/yaml/MyBean.java
new file mode 100644
index 0000000000..02ebd4d260
--- /dev/null
+++ b/integration-tests/camel-k-runtime/src/main/java/org/apache/camel/quarkus/k/it/yaml/MyBean.java
@@ -0,0 +1,46 @@
+/*
+ * 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.quarkus.k.it.yaml;
+
+import io.quarkus.runtime.annotations.RegisterForReflection;
+
+@RegisterForReflection
+public class MyBean {
+ private String name;
+
+ public MyBean() {
+ }
+
+ public MyBean(String name) {
+ this.name = name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public String toString() {
+ return "MyBean{" +
+ "name='" + name + '\'' +
+ '}';
+ }
+}
diff --git a/integration-tests/camel-k-runtime/src/main/java/org/apache/camel/quarkus/k/it/yaml/MyProcessor.java b/integration-tests/camel-k-runtime/src/main/java/org/apache/camel/quarkus/k/it/yaml/MyProcessor.java
new file mode 100644
index 0000000000..75bc5bcfa9
--- /dev/null
+++ b/integration-tests/camel-k-runtime/src/main/java/org/apache/camel/quarkus/k/it/yaml/MyProcessor.java
@@ -0,0 +1,28 @@
+/*
+ * 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.quarkus.k.it.yaml;
+
+import io.quarkus.runtime.annotations.RegisterForReflection;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+
+@RegisterForReflection
+public class MyProcessor implements Processor {
+ @Override
+ public void process(Exchange exchange) throws Exception {
+ }
+}
diff --git a/integration-tests/camel-k-runtime/src/main/resources/application.properties b/integration-tests/camel-k-runtime/src/main/resources/application.properties
new file mode 100644
index 0000000000..73989eb473
--- /dev/null
+++ b/integration-tests/camel-k-runtime/src/main/resources/application.properties
@@ -0,0 +1,21 @@
+## ---------------------------------------------------------------------------
+## 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.banner.enabled = false
diff --git a/integration-tests/camel-k-runtime/src/test/java/org/apache/camel/quarkus/k/it/RuntimeCustomizerFallbackIT.java b/integration-tests/camel-k-runtime/src/test/java/org/apache/camel/quarkus/k/it/RuntimeCustomizerFallbackIT.java
new file mode 100644
index 0000000000..31ba970ed9
--- /dev/null
+++ b/integration-tests/camel-k-runtime/src/test/java/org/apache/camel/quarkus/k/it/RuntimeCustomizerFallbackIT.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.quarkus.k.it;
+
+import io.quarkus.test.junit.QuarkusIntegrationTest;
+
+@QuarkusIntegrationTest
+public class RuntimeCustomizerFallbackIT extends RuntimeCustomizerFallbackTest {
+}
diff --git a/integration-tests/camel-k-runtime/src/test/java/org/apache/camel/quarkus/k/it/RuntimeCustomizerFallbackTest.java b/integration-tests/camel-k-runtime/src/test/java/org/apache/camel/quarkus/k/it/RuntimeCustomizerFallbackTest.java
new file mode 100644
index 0000000000..6e8025f76f
--- /dev/null
+++ b/integration-tests/camel-k-runtime/src/test/java/org/apache/camel/quarkus/k/it/RuntimeCustomizerFallbackTest.java
@@ -0,0 +1,58 @@
+/*
+ * 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.quarkus.k.it;
+
+import java.util.Map;
+
+import io.quarkus.test.junit.QuarkusTestProfile;
+import io.restassured.path.json.JsonPath;
+import jakarta.ws.rs.core.MediaType;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+
+import static io.restassured.RestAssured.given;
+import static org.apache.camel.util.CollectionHelper.mapOf;
+import static org.assertj.core.api.Assertions.assertThat;
+
+@Disabled("https://github.com/apache/camel-quarkus/issues/5235")
+//@TestProfile(RuntimeCustomizerFallbackTest.Profile.class)
+//@QuarkusTest
+public class RuntimeCustomizerFallbackTest {
+ @Test
+ public void testContextCustomizerFromPropertiesFallback() {
+ JsonPath p = given()
+ .accept(MediaType.APPLICATION_JSON)
+ .get("/camel-k/inspect/context")
+ .then()
+ .statusCode(200)
+ .extract()
+ .body()
+ .jsonPath();
+
+ assertThat(p.getBoolean("message-history")).isFalse();
+ assertThat(p.getBoolean("load-type-converters")).isFalse();
+ }
+
+ public static class Profile implements QuarkusTestProfile {
+ @Override
+ public Map<String, String> getConfigOverrides() {
+ return mapOf(
+ "customizer.test.enabled", "true",
+ "customizer.test.message-history", "false");
+ }
+ }
+}
diff --git a/integration-tests/camel-k-runtime/src/test/java/org/apache/camel/quarkus/k/it/RuntimeCustomizerIT.java b/integration-tests/camel-k-runtime/src/test/java/org/apache/camel/quarkus/k/it/RuntimeCustomizerIT.java
new file mode 100644
index 0000000000..991bc91f56
--- /dev/null
+++ b/integration-tests/camel-k-runtime/src/test/java/org/apache/camel/quarkus/k/it/RuntimeCustomizerIT.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.quarkus.k.it;
+
+import io.quarkus.test.junit.QuarkusIntegrationTest;
+
+@QuarkusIntegrationTest
+public class RuntimeCustomizerIT extends RuntimeCustomizerTest {
+}
diff --git a/integration-tests/camel-k-runtime/src/test/java/org/apache/camel/quarkus/k/it/RuntimeCustomizerTest.java b/integration-tests/camel-k-runtime/src/test/java/org/apache/camel/quarkus/k/it/RuntimeCustomizerTest.java
new file mode 100644
index 0000000000..6560a9f224
--- /dev/null
+++ b/integration-tests/camel-k-runtime/src/test/java/org/apache/camel/quarkus/k/it/RuntimeCustomizerTest.java
@@ -0,0 +1,58 @@
+/*
+ * 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.quarkus.k.it;
+
+import java.util.Map;
+
+import io.quarkus.test.junit.QuarkusTestProfile;
+import io.restassured.path.json.JsonPath;
+import jakarta.ws.rs.core.MediaType;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+
+import static io.restassured.RestAssured.given;
+import static org.apache.camel.util.CollectionHelper.mapOf;
+import static org.assertj.core.api.Assertions.assertThat;
+
+@Disabled("https://github.com/apache/camel-quarkus/issues/5235")
+//@TestProfile(RuntimeCustomizerTest.Profile.class)
+//@QuarkusTest
+public class RuntimeCustomizerTest {
+ @Test
+ public void testContextCustomizerFromProperties() {
+ JsonPath p = given()
+ .accept(MediaType.APPLICATION_JSON)
+ .get("/camel-k/inspect/context")
+ .then()
+ .statusCode(200)
+ .extract()
+ .body()
+ .jsonPath();
+
+ assertThat(p.getBoolean("message-history")).isFalse();
+ assertThat(p.getBoolean("load-type-converters")).isFalse();
+ }
+
+ public static class Profile implements QuarkusTestProfile {
+ @Override
+ public Map<String, String> getConfigOverrides() {
+ return mapOf(
+ "camel.k.customizer.test.enabled", "true",
+ "camel.k.customizer.test.message-history", "false");
+ }
+ }
+}
diff --git a/integration-tests/camel-k-runtime/src/test/java/org/apache/camel/quarkus/k/it/RuntimeIT.java b/integration-tests/camel-k-runtime/src/test/java/org/apache/camel/quarkus/k/it/RuntimeIT.java
new file mode 100644
index 0000000000..406cb104c0
--- /dev/null
+++ b/integration-tests/camel-k-runtime/src/test/java/org/apache/camel/quarkus/k/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.quarkus.k.it;
+
+import io.quarkus.test.junit.QuarkusIntegrationTest;
+
+@QuarkusIntegrationTest
+public class RuntimeIT extends RuntimeTest {
+}
diff --git a/integration-tests/camel-k-runtime/src/test/java/org/apache/camel/quarkus/k/it/RuntimeTest.java b/integration-tests/camel-k-runtime/src/test/java/org/apache/camel/quarkus/k/it/RuntimeTest.java
new file mode 100644
index 0000000000..c5eee3df86
--- /dev/null
+++ b/integration-tests/camel-k-runtime/src/test/java/org/apache/camel/quarkus/k/it/RuntimeTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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.quarkus.k.it;
+
+import io.quarkus.test.junit.QuarkusTest;
+import io.restassured.path.json.JsonPath;
+import jakarta.ws.rs.core.MediaType;
+import org.apache.camel.quarkus.core.FastCamelContext;
+import org.apache.camel.quarkus.k.runtime.Application;
+import org.junit.jupiter.api.Test;
+
+import static io.restassured.RestAssured.given;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.hamcrest.Matchers.is;
+
+@QuarkusTest
+public class RuntimeTest {
+ @Test
+ public void inspect() {
+ JsonPath p = given()
+ .accept(MediaType.APPLICATION_JSON)
+ .get("/camel-k/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("routes-collector"))
+ .isEqualTo(Application.NoRoutesCollector.class.getName());
+ }
+
+ @Test
+ public void properties() {
+ given().get("/camel-k/property/my-property").then().statusCode(200).body(is("my-test-value"));
+ given().get("/camel-k/property/root.key").then().statusCode(200).body(is("root.value"));
+ given().get("/camel-k/property/001.key").then().statusCode(200).body(is("001.value"));
+ given().get("/camel-k/property/002.key").then().statusCode(200).body(is("002.value"));
+ given().get("/camel-k/property/a.key").then().statusCode(200).body(is("a.002"));
+ given().get("/camel-k/property/flat-property").then().statusCode(200).body(is("flat-value"));
+ }
+}
diff --git a/integration-tests/camel-k-runtime/src/test/java/org/apache/camel/quarkus/k/it/RuntimeWithXmlIT.java b/integration-tests/camel-k-runtime/src/test/java/org/apache/camel/quarkus/k/it/RuntimeWithXmlIT.java
new file mode 100644
index 0000000000..8f0104b2fa
--- /dev/null
+++ b/integration-tests/camel-k-runtime/src/test/java/org/apache/camel/quarkus/k/it/RuntimeWithXmlIT.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.quarkus.k.it;
+
+import io.quarkus.test.junit.QuarkusIntegrationTest;
+
+@QuarkusIntegrationTest
+public class RuntimeWithXmlIT extends RuntimeWithXmlTest {
+}
diff --git a/integration-tests/camel-k-runtime/src/test/java/org/apache/camel/quarkus/k/it/RuntimeWithXmlTest.java b/integration-tests/camel-k-runtime/src/test/java/org/apache/camel/quarkus/k/it/RuntimeWithXmlTest.java
new file mode 100644
index 0000000000..b66a9eeb64
--- /dev/null
+++ b/integration-tests/camel-k-runtime/src/test/java/org/apache/camel/quarkus/k/it/RuntimeWithXmlTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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.quarkus.k.it;
+
+import java.nio.file.Paths;
+import java.util.Map;
+
+import io.quarkus.test.common.QuarkusTestResource;
+import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;
+import io.quarkus.test.junit.QuarkusTest;
+import io.restassured.RestAssured;
+import io.restassured.path.json.JsonPath;
+import jakarta.ws.rs.core.MediaType;
+import org.junit.jupiter.api.Test;
+
+import static org.apache.camel.util.CollectionHelper.mapOf;
+import static org.assertj.core.api.Assertions.assertThat;
+
+@QuarkusTest
+@QuarkusTestResource(RuntimeWithXmlTest.Resources.class)
+public class RuntimeWithXmlTest {
+ @Test
+ public void inspect() {
+ JsonPath p = RestAssured.given()
+ .accept(MediaType.APPLICATION_JSON)
+ .get("/camel-k/runtime/inspect")
+ .then()
+ .statusCode(200)
+ .extract()
+ .body()
+ .jsonPath();
+
+ assertThat(p.getList("route-definitions", String.class))
+ .contains("xml-simple-route", "xml-route-with-expression", "xml-greetings");
+ assertThat(p.getList("rest-definitions", String.class))
+ .contains("xml-rest-greetings");
+ }
+
+ public static class Resources implements QuarkusTestResourceLifecycleManager {
+ @Override
+ public Map<String, String> start() {
+ final String res = Paths.get("src/test/resources").toAbsolutePath().toString();
+
+ return mapOf(
+ // sources
+ "camel.k.sources[0].location", "file:" + res + "/routes.xml",
+ "camel.k.sources[0].type", "source",
+ "camel.k.sources[1].location", "file:" + res + "/rests.xml",
+ "camel.k.sources[1].type", "source",
+ "camel.k.sources[2].location", "file:" + res + "/routes-with-expression.xml",
+ "camel.k.sources[2].type", "source",
+ // misc
+ "the.body", "10");
+ }
+
+ @Override
+ public void stop() {
+ }
+ }
+}
diff --git a/integration-tests/camel-k-runtime/src/test/java/org/apache/camel/quarkus/k/it/RuntimeWithYamlIT.java b/integration-tests/camel-k-runtime/src/test/java/org/apache/camel/quarkus/k/it/RuntimeWithYamlIT.java
new file mode 100644
index 0000000000..3ab937dd9b
--- /dev/null
+++ b/integration-tests/camel-k-runtime/src/test/java/org/apache/camel/quarkus/k/it/RuntimeWithYamlIT.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.quarkus.k.it;
+
+import io.quarkus.test.junit.QuarkusIntegrationTest;
+
+@QuarkusIntegrationTest
+public class RuntimeWithYamlIT extends RuntimeWithYamlTest {
+}
diff --git a/integration-tests/camel-k-runtime/src/test/java/org/apache/camel/quarkus/k/it/RuntimeWithYamlTest.java b/integration-tests/camel-k-runtime/src/test/java/org/apache/camel/quarkus/k/it/RuntimeWithYamlTest.java
new file mode 100644
index 0000000000..4d28259a54
--- /dev/null
+++ b/integration-tests/camel-k-runtime/src/test/java/org/apache/camel/quarkus/k/it/RuntimeWithYamlTest.java
@@ -0,0 +1,77 @@
+/*
+ * 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.quarkus.k.it;
+
+import java.nio.file.Paths;
+import java.util.Map;
+
+import io.quarkus.test.common.QuarkusTestResource;
+import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;
+import io.quarkus.test.junit.QuarkusTest;
+import jakarta.ws.rs.core.MediaType;
+import org.apache.camel.quarkus.k.it.yaml.MyProcessor;
+import org.junit.jupiter.api.Test;
+
+import static io.restassured.RestAssured.given;
+import static org.apache.camel.util.CollectionHelper.mapOf;
+import static org.hamcrest.Matchers.hasItem;
+import static org.hamcrest.Matchers.is;
+
+@QuarkusTest
+@QuarkusTestResource(RuntimeWithYamlTest.Resources.class)
+public class RuntimeWithYamlTest {
+ @Test
+ public void inspect() {
+ given()
+ .accept(MediaType.APPLICATION_JSON)
+ .get("/camel-k/runtime/inspect")
+ .then()
+ .statusCode(200)
+ .body("route-definitions", hasItem("my-yaml-route"));
+
+ given()
+ .accept(MediaType.APPLICATION_JSON)
+ .get("/camel-k/runtime/registry/beans/my-bean")
+ .then()
+ .statusCode(200)
+ .body("name", is("my-bean-name"));
+
+ given()
+ .accept(MediaType.APPLICATION_JSON)
+ .get("/camel-k/runtime/registry/beans/myProcessor")
+ .then()
+ .statusCode(200);
+ }
+
+ public static class Resources implements QuarkusTestResourceLifecycleManager {
+ @Override
+ public Map<String, String> start() {
+ final String res = Paths.get("src/test/resources").toAbsolutePath().toString();
+
+ return mapOf(
+ // sources
+ "camel.k.sources[3].location", "file:" + res + "/routes-with-beans.yaml",
+ "camel.k.sources[3].type", "source",
+ // misc
+ "camel.beans.myProcessor", "#class:" + MyProcessor.class.getName());
+ }
+
+ @Override
+ public void stop() {
+ }
+ }
+}
diff --git a/integration-tests/camel-k-runtime/src/test/java/org/apache/camel/quarkus/k/it/TestCustomizer.java b/integration-tests/camel-k-runtime/src/test/java/org/apache/camel/quarkus/k/it/TestCustomizer.java
new file mode 100644
index 0000000000..c02e079756
--- /dev/null
+++ b/integration-tests/camel-k-runtime/src/test/java/org/apache/camel/quarkus/k/it/TestCustomizer.java
@@ -0,0 +1,50 @@
+/*
+ * 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.quarkus.k.it;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.impl.engine.ExplicitCamelContextNameStrategy;
+import org.apache.camel.spi.CamelContextCustomizer;
+
+public class TestCustomizer implements CamelContextCustomizer {
+
+ private String name;
+ private boolean messageHistory = true;
+
+ public TestCustomizer() {
+ this("default");
+ }
+
+ public TestCustomizer(String name) {
+ this.name = name;
+ }
+
+ public boolean isMessageHistory() {
+ return messageHistory;
+ }
+
+ public void setMessageHistory(boolean messageHistory) {
+ this.messageHistory = messageHistory;
+ }
+
+ @Override
+ public void configure(CamelContext camelContext) {
+ camelContext.setNameStrategy(new ExplicitCamelContextNameStrategy(name));
+ camelContext.setMessageHistory(messageHistory);
+ camelContext.setLoadTypeConverters(false);
+ }
+}
diff --git a/integration-tests/camel-k-runtime/src/test/resources/META-INF/services/org.apache.camel.quarkus.k/customizer/test b/integration-tests/camel-k-runtime/src/test/resources/META-INF/services/org.apache.camel.quarkus.k/customizer/test
new file mode 100644
index 0000000000..ea826819d6
--- /dev/null
+++ b/integration-tests/camel-k-runtime/src/test/resources/META-INF/services/org.apache.camel.quarkus.k/customizer/test
@@ -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.
+#
+
+class=org.apache.camel.quarkus.k.it.TestCustomizer
\ No newline at end of file
diff --git a/integration-tests/camel-k-runtime/src/test/resources/conf.d/001/conf.properties b/integration-tests/camel-k-runtime/src/test/resources/conf.d/001/conf.properties
new file mode 100644
index 0000000000..8479286073
--- /dev/null
+++ b/integration-tests/camel-k-runtime/src/test/resources/conf.d/001/conf.properties
@@ -0,0 +1,17 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+001.key = 001.value
\ No newline at end of file
diff --git a/integration-tests/camel-k-runtime/src/test/resources/conf.d/002/conf.properties b/integration-tests/camel-k-runtime/src/test/resources/conf.d/002/conf.properties
new file mode 100644
index 0000000000..3ddea2bdbe
--- /dev/null
+++ b/integration-tests/camel-k-runtime/src/test/resources/conf.d/002/conf.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.
+## ---------------------------------------------------------------------------
+002.key = 002.value
+a.key = a.002
\ No newline at end of file
diff --git a/integration-tests/camel-k-runtime/src/test/resources/conf.d/003/flat-property b/integration-tests/camel-k-runtime/src/test/resources/conf.d/003/flat-property
new file mode 100644
index 0000000000..313b57de3e
--- /dev/null
+++ b/integration-tests/camel-k-runtime/src/test/resources/conf.d/003/flat-property
@@ -0,0 +1 @@
+flat-value
\ No newline at end of file
diff --git a/integration-tests/camel-k-runtime/src/test/resources/conf.properties b/integration-tests/camel-k-runtime/src/test/resources/conf.properties
new file mode 100644
index 0000000000..9b09020aa9
--- /dev/null
+++ b/integration-tests/camel-k-runtime/src/test/resources/conf.properties
@@ -0,0 +1,21 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+root.key = root.value
+a.key = a.root
+
+my-property = my-test-value
\ No newline at end of file
diff --git a/integration-tests/camel-k-runtime/src/test/resources/rests.xml b/integration-tests/camel-k-runtime/src/test/resources/rests.xml
new file mode 100644
index 0000000000..272d106018
--- /dev/null
+++ b/integration-tests/camel-k-runtime/src/test/resources/rests.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+
+ 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.
+
+-->
+<rests xmlns="http://camel.apache.org/schema/spring">
+ <rest path="/camel/" id="xml-rest-greetings">
+ <get id="xml-greetings" path="/greetings/{name}">
+ <param dataType="string" name="name" required="true" type="path"/>
+ <to uri="direct:greeting-api"/>
+ </get>
+ </rest>
+</rests>
diff --git a/integration-tests/camel-k-runtime/src/test/resources/routes-with-beans.yaml b/integration-tests/camel-k-runtime/src/test/resources/routes-with-beans.yaml
new file mode 100644
index 0000000000..fb2a8012c8
--- /dev/null
+++ b/integration-tests/camel-k-runtime/src/test/resources/routes-with-beans.yaml
@@ -0,0 +1,31 @@
+#
+# 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.
+#
+
+- beans:
+ - name: my-bean
+ type: org.apache.camel.quarkus.k.it.yaml.MyBean
+ properties:
+ name: "my-bean-name"
+- route:
+ id: "my-yaml-route"
+ from:
+ uri: "direct:start"
+ steps:
+ - bean:
+ ref: "my-bean"
+ method: "getName"
+ - to: "log:info"
diff --git a/integration-tests/camel-k-runtime/src/test/resources/routes-with-expression.xml b/integration-tests/camel-k-runtime/src/test/resources/routes-with-expression.xml
new file mode 100644
index 0000000000..b3fe307470
--- /dev/null
+++ b/integration-tests/camel-k-runtime/src/test/resources/routes-with-expression.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<routes xmlns="http://camel.apache.org/schema/spring">
+ <route id="xml-route-with-expression">
+ <from uri="timer:tick"/>
+ <filter>
+ <simple>${in.body} == {{the.body}}</simple>
+ <to uri="log:info"/>
+ </filter>
+ </route>
+</routes>
\ No newline at end of file
diff --git a/integration-tests/camel-k-runtime/src/test/resources/routes.xml b/integration-tests/camel-k-runtime/src/test/resources/routes.xml
new file mode 100644
index 0000000000..0a0dca729b
--- /dev/null
+++ b/integration-tests/camel-k-runtime/src/test/resources/routes.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<routes xmlns="http://camel.apache.org/schema/spring">
+ <route id="xml-simple-route">
+ <from uri="timer:tick"/>
+ <to uri="log:info"/>
+ </route>
+</routes>
\ No newline at end of file
diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml
index 8dfaa18633..f2c9f8eb97 100644
--- a/integration-tests/pom.xml
+++ b/integration-tests/pom.xml
@@ -69,6 +69,7 @@
<module>box</module>
<module>braintree</module>
<module>caffeine</module>
+ <module>camel-k-runtime</module>
<module>cassandraql</module>
<module>cbor</module>
<module>compression-grouped</module>
diff --git a/pom.xml b/pom.xml
index 7ed9e260c4..7ccd556c12 100644
--- a/pom.xml
+++ b/pom.xml
@@ -110,11 +110,13 @@
<httpclient5.version>${httpclient-version}</httpclient5.version><!-- Saxon and Wiremock -->
<ibm.mq.client.version>9.3.2.1</ibm.mq.client.version>
<icu4j.version>${icu4j-version}</icu4j.version>
+ <immutables.version>2.9.3</immutables.version>
<influxdb.version>${influx-java-driver-version}</influxdb.version>
<jackson.version>2.15.2</jackson.version><!-- @sync io.quarkus:quarkus-bom:${quarkus.version} dep:com.fasterxml.jackson.core:jackson-core -->
<jakarta.jms-api.version>${jakarta-jms-api-version}</jakarta.jms-api.version>
<java-json-tools.json-patch.version>${json-patch-version}</java-json-tools.json-patch.version><!-- A replacement for com.github.fge:json-patch -->
<jodatime.version>${jodatime2-version}</jodatime.version><!-- Mess in transitive dependencies of Splunk -->
+ <jolokia.version>1.7.2</jolokia.version><!-- For camel-k -->
<jaxen.version>1.2.0</jaxen.version>
<javassist.version>${javassist-version}</javassist.version><!-- debezium -->
<jetty.version>${jetty-version}</jetty.version>
@@ -572,6 +574,7 @@
<exclude>node/**</exclude>
<exclude>**/resources/routes.1</exclude>
<exclude>**/resources/routes.2</exclude>
+ <exclude>**/conf.d/**</exclude>
<exclude>**/generated/**</exclude>
<exclude>.envrc</exclude>
<exclude>**/.idea/**</exclude>
@@ -579,6 +582,7 @@
<exclude>.gitattributes</exclude>
<exclude>**/src/test/resources/__files/*.xml</exclude>
<exclude>.github/actions/**</exclude>
+ <exclude>**/my-property</exclude>
</excludes>
<mapping>
<cli>CAMEL_PROPERTIES_STYLE</cli>
diff --git a/poms/bom-test/pom.xml b/poms/bom-test/pom.xml
index 49c39287c0..53cb86b53f 100644
--- a/poms/bom-test/pom.xml
+++ b/poms/bom-test/pom.xml
@@ -127,6 +127,16 @@
<artifactId>camel-quarkus-integration-tests-support-azure</artifactId>
<version>${camel-quarkus.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-integration-test-support-camel-k-loader-inspector</artifactId>
+ <version>${camel-quarkus.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-integration-test-support-camel-k-runtime-inspector</artifactId>
+ <version>${camel-quarkus.version}</version>
+ </dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-integration-tests-support-jdbc</artifactId>
diff --git a/poms/bom/pom.xml b/poms/bom/pom.xml
index 2c042826cf..6c7e0fe370 100644
--- a/poms/bom/pom.xml
+++ b/poms/bom/pom.xml
@@ -3157,6 +3157,16 @@
<artifactId>camel-quarkus-caffeine-deployment</artifactId>
<version>${camel-quarkus.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-camel-k</artifactId>
+ <version>${camel-quarkus.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-camel-k-deployment</artifactId>
+ <version>${camel-quarkus.version}</version>
+ </dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-cassandraql</artifactId>
@@ -3839,12 +3849,12 @@
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-grpc-deployment</artifactId>
+ <artifactId>camel-quarkus-grpc-codegen</artifactId>
<version>${camel-quarkus.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-grpc-codegen</artifactId>
+ <artifactId>camel-quarkus-grpc-deployment</artifactId>
<version>${camel-quarkus.version}</version>
</dependency>
<dependency>
@@ -6453,6 +6463,31 @@
<artifactId>avro-ipc-netty</artifactId>
<version>${avro.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.groovy</groupId>
+ <artifactId>groovy</artifactId>
+ <version>${groovy.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.groovy</groupId>
+ <artifactId>groovy-json</artifactId>
+ <version>${groovy.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.groovy</groupId>
+ <artifactId>groovy-test</artifactId>
+ <version>${groovy.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.groovy</groupId>
+ <artifactId>groovy-xml</artifactId>
+ <version>${groovy.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.groovy</groupId>
+ <artifactId>groovy-yaml</artifactId>
+ <version>${groovy.version}</version>
+ </dependency>
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
@@ -6614,6 +6649,21 @@
<artifactId>kotlin-scripting-jvm-host</artifactId>
<version>${kotlin.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.jolokia</groupId>
+ <artifactId>jolokia-jvm</artifactId>
+ <version>${jolokia.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.jolokia</groupId>
+ <artifactId>jolokia-core</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.googlecode.json-simple</groupId>
+ <artifactId>json-simple</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
diff --git a/poms/bom/src/main/generated/flattened-full-pom.xml b/poms/bom/src/main/generated/flattened-full-pom.xml
index bbe5aee3bf..0b54a5a059 100644
--- a/poms/bom/src/main/generated/flattened-full-pom.xml
+++ b/poms/bom/src/main/generated/flattened-full-pom.xml
@@ -3083,6 +3083,16 @@
<artifactId>camel-quarkus-caffeine-deployment</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
<version>3.3.0-SNAPSHOT</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
</dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <artifactId>camel-quarkus-camel-k</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <version>3.3.0-SNAPSHOT</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <artifactId>camel-quarkus-camel-k-deployment</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <version>3.3.0-SNAPSHOT</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ </dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
<artifactId>camel-quarkus-cassandraql</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
@@ -3765,12 +3775,12 @@
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
- <artifactId>camel-quarkus-grpc-deployment</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <artifactId>camel-quarkus-grpc-codegen</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
<version>3.3.0-SNAPSHOT</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
- <artifactId>camel-quarkus-grpc-codegen</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <artifactId>camel-quarkus-grpc-deployment</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
<version>3.3.0-SNAPSHOT</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
</dependency>
<dependency>
@@ -6376,6 +6386,31 @@
<artifactId>avro-ipc-netty</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
<version>1.11.1</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
</dependency>
+ <dependency>
+ <groupId>org.apache.groovy</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <artifactId>groovy</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <version>4.0.13</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ </dependency>
+ <dependency>
+ <groupId>org.apache.groovy</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <artifactId>groovy-json</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <version>4.0.13</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ </dependency>
+ <dependency>
+ <groupId>org.apache.groovy</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <artifactId>groovy-test</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <version>4.0.13</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ </dependency>
+ <dependency>
+ <groupId>org.apache.groovy</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <artifactId>groovy-xml</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <version>4.0.13</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ </dependency>
+ <dependency>
+ <groupId>org.apache.groovy</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <artifactId>groovy-yaml</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <version>4.0.13</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ </dependency>
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
<artifactId>httpclient5</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
@@ -6537,6 +6572,21 @@
<artifactId>kotlin-scripting-jvm-host</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
<version>1.8.22</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
</dependency>
+ <dependency>
+ <groupId>org.jolokia</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <artifactId>jolokia-jvm</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <version>1.7.2</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <exclusions>
+ <exclusion>
+ <groupId>org.jolokia</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <artifactId>jolokia-core</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ </exclusion>
+ <exclusion>
+ <groupId>com.googlecode.json-simple</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <artifactId>json-simple</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ </exclusion>
+ </exclusions>
+ </dependency>
<dependency>
<groupId>org.mapstruct</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
<artifactId>mapstruct-processor</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
@@ -7162,11 +7212,6 @@
<artifactId>cxf-tools-wsdlto-frontend-jaxws</artifactId><!-- io.quarkiverse.cxf:quarkus-cxf-bom:2.2.2 -->
<version>4.0.2</version><!-- io.quarkiverse.cxf:quarkus-cxf-bom:2.2.2 -->
</dependency>
- <dependency>
- <groupId>org.apache.groovy</groupId><!-- org.apache.groovy:groovy-bom:4.0.13 -->
- <artifactId>groovy</artifactId><!-- org.apache.groovy:groovy-bom:4.0.13 -->
- <version>4.0.13</version><!-- org.apache.groovy:groovy-bom:4.0.13 -->
- </dependency>
<dependency>
<groupId>org.apache.groovy</groupId><!-- org.apache.groovy:groovy-bom:4.0.13 -->
<artifactId>groovy-ant</artifactId><!-- org.apache.groovy:groovy-bom:4.0.13 -->
@@ -7232,11 +7277,6 @@
<artifactId>groovy-jmx</artifactId><!-- org.apache.groovy:groovy-bom:4.0.13 -->
<version>4.0.13</version><!-- org.apache.groovy:groovy-bom:4.0.13 -->
</dependency>
- <dependency>
- <groupId>org.apache.groovy</groupId><!-- org.apache.groovy:groovy-bom:4.0.13 -->
- <artifactId>groovy-json</artifactId><!-- org.apache.groovy:groovy-bom:4.0.13 -->
- <version>4.0.13</version><!-- org.apache.groovy:groovy-bom:4.0.13 -->
- </dependency>
<dependency>
<groupId>org.apache.groovy</groupId><!-- org.apache.groovy:groovy-bom:4.0.13 -->
<artifactId>groovy-jsr223</artifactId><!-- org.apache.groovy:groovy-bom:4.0.13 -->
@@ -7277,11 +7317,6 @@
<artifactId>groovy-templates</artifactId><!-- org.apache.groovy:groovy-bom:4.0.13 -->
<version>4.0.13</version><!-- org.apache.groovy:groovy-bom:4.0.13 -->
</dependency>
- <dependency>
- <groupId>org.apache.groovy</groupId><!-- org.apache.groovy:groovy-bom:4.0.13 -->
- <artifactId>groovy-test</artifactId><!-- org.apache.groovy:groovy-bom:4.0.13 -->
- <version>4.0.13</version><!-- org.apache.groovy:groovy-bom:4.0.13 -->
- </dependency>
<dependency>
<groupId>org.apache.groovy</groupId><!-- org.apache.groovy:groovy-bom:4.0.13 -->
<artifactId>groovy-test-junit5</artifactId><!-- org.apache.groovy:groovy-bom:4.0.13 -->
@@ -7302,16 +7337,6 @@
<artifactId>groovy-typecheckers</artifactId><!-- org.apache.groovy:groovy-bom:4.0.13 -->
<version>4.0.13</version><!-- org.apache.groovy:groovy-bom:4.0.13 -->
</dependency>
- <dependency>
- <groupId>org.apache.groovy</groupId><!-- org.apache.groovy:groovy-bom:4.0.13 -->
- <artifactId>groovy-xml</artifactId><!-- org.apache.groovy:groovy-bom:4.0.13 -->
- <version>4.0.13</version><!-- org.apache.groovy:groovy-bom:4.0.13 -->
- </dependency>
- <dependency>
- <groupId>org.apache.groovy</groupId><!-- org.apache.groovy:groovy-bom:4.0.13 -->
- <artifactId>groovy-yaml</artifactId><!-- org.apache.groovy:groovy-bom:4.0.13 -->
- <version>4.0.13</version><!-- org.apache.groovy:groovy-bom:4.0.13 -->
- </dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId><!-- software.amazon.awssdk:bom:2.20.128 -->
<artifactId>codegen-lite-maven-plugin</artifactId><!-- software.amazon.awssdk:bom:2.20.128 -->
diff --git a/poms/bom/src/main/generated/flattened-reduced-pom.xml b/poms/bom/src/main/generated/flattened-reduced-pom.xml
index ba990f9f76..1388418cd2 100644
--- a/poms/bom/src/main/generated/flattened-reduced-pom.xml
+++ b/poms/bom/src/main/generated/flattened-reduced-pom.xml
@@ -3083,6 +3083,16 @@
<artifactId>camel-quarkus-caffeine-deployment</artifactId>
<version>3.3.0-SNAPSHOT</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-camel-k</artifactId>
+ <version>3.3.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-camel-k-deployment</artifactId>
+ <version>3.3.0-SNAPSHOT</version>
+ </dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-cassandraql</artifactId>
@@ -3765,12 +3775,12 @@
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-grpc-deployment</artifactId>
+ <artifactId>camel-quarkus-grpc-codegen</artifactId>
<version>3.3.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-grpc-codegen</artifactId>
+ <artifactId>camel-quarkus-grpc-deployment</artifactId>
<version>3.3.0-SNAPSHOT</version>
</dependency>
<dependency>
@@ -6351,6 +6361,11 @@
<artifactId>antlr-runtime</artifactId>
<version>3.5.2</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.groovy</groupId>
+ <artifactId>groovy</artifactId>
+ <version>4.0.13</version>
+ </dependency>
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
@@ -7107,11 +7122,6 @@
<artifactId>cxf-tools-wsdlto-frontend-jaxws</artifactId>
<version>4.0.2</version>
</dependency>
- <dependency>
- <groupId>org.apache.groovy</groupId>
- <artifactId>groovy</artifactId>
- <version>4.0.13</version>
- </dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>annotations</artifactId>
diff --git a/poms/bom/src/main/generated/flattened-reduced-verbose-pom.xml b/poms/bom/src/main/generated/flattened-reduced-verbose-pom.xml
index 4c8e4b484c..802f4e42d4 100644
--- a/poms/bom/src/main/generated/flattened-reduced-verbose-pom.xml
+++ b/poms/bom/src/main/generated/flattened-reduced-verbose-pom.xml
@@ -3083,6 +3083,16 @@
<artifactId>camel-quarkus-caffeine-deployment</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
<version>3.3.0-SNAPSHOT</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
</dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <artifactId>camel-quarkus-camel-k</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <version>3.3.0-SNAPSHOT</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <artifactId>camel-quarkus-camel-k-deployment</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <version>3.3.0-SNAPSHOT</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ </dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
<artifactId>camel-quarkus-cassandraql</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
@@ -3765,12 +3775,12 @@
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
- <artifactId>camel-quarkus-grpc-deployment</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <artifactId>camel-quarkus-grpc-codegen</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
<version>3.3.0-SNAPSHOT</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
</dependency>
<dependency>
<groupId>org.apache.camel.quarkus</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
- <artifactId>camel-quarkus-grpc-codegen</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <artifactId>camel-quarkus-grpc-deployment</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
<version>3.3.0-SNAPSHOT</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
</dependency>
<dependency>
@@ -6351,6 +6361,11 @@
<artifactId>antlr-runtime</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
<version>3.5.2</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
</dependency>
+ <dependency>
+ <groupId>org.apache.groovy</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <artifactId>groovy</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ <version>4.0.13</version><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
+ </dependency>
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
<artifactId>httpclient5</artifactId><!-- org.apache.camel.quarkus:camel-quarkus-bom:${project.version} -->
@@ -7107,11 +7122,6 @@
<artifactId>cxf-tools-wsdlto-frontend-jaxws</artifactId><!-- io.quarkiverse.cxf:quarkus-cxf-bom:2.2.2 -->
<version>4.0.2</version><!-- io.quarkiverse.cxf:quarkus-cxf-bom:2.2.2 -->
</dependency>
- <dependency>
- <groupId>org.apache.groovy</groupId><!-- org.apache.groovy:groovy-bom:4.0.13 -->
- <artifactId>groovy</artifactId><!-- org.apache.groovy:groovy-bom:4.0.13 -->
- <version>4.0.13</version><!-- org.apache.groovy:groovy-bom:4.0.13 -->
- </dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId><!-- software.amazon.awssdk:bom:2.20.128 -->
<artifactId>annotations</artifactId><!-- software.amazon.awssdk:bom:2.20.128 -->
diff --git a/tooling/camel-k-catalog-model/pom.xml b/tooling/camel-k-catalog-model/pom.xml
new file mode 100644
index 0000000000..d65af2f0a2
--- /dev/null
+++ b/tooling/camel-k-catalog-model/pom.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus</artifactId>
+ <version>3.3.0-SNAPSHOT</version>
+ <relativePath>../../pom.xml</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>camel-quarkus-camel-k-catalog-model</artifactId>
+ <name>Camel Quarkus :: Tooling :: Camel K Catalog Model</name>
+ <description>Model classes specific to Camel K Maven Plugin to generate the Camel K Catalog.</description>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-bom</artifactId>
+ <version>${quarkus.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-bom</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.immutables</groupId>
+ <artifactId>value</artifactId>
+ <version>${immutables.version}</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.datatype</groupId>
+ <artifactId>jackson-datatype-jdk8</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.dataformat</groupId>
+ <artifactId>jackson-dataformat-yaml</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.immutables</groupId>
+ <artifactId>value</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-support</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifest>
+ <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+ <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
+ </manifest>
+ </archive>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/Artifact.java b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/Artifact.java
new file mode 100644
index 0000000000..dde1b0910a
--- /dev/null
+++ b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/Artifact.java
@@ -0,0 +1,59 @@
+/*
+ * 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.quarkus.k.catalog.model;
+
+import java.util.Comparator;
+import java.util.Optional;
+
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+@JsonPropertyOrder({ "groupId", "artifactId", "version" })
+public interface Artifact extends Comparable<Artifact> {
+ String getGroupId();;
+
+ String getArtifactId();
+
+ Optional<String> getVersion();
+
+ @Override
+ default int compareTo(Artifact o) {
+ return Comparator
+ .comparing(Artifact::getGroupId)
+ .thenComparing(Artifact::getArtifactId)
+ .thenComparing(Artifact::getVersion, Comparator.comparing(c -> c.orElse("")))
+ .compare(this, o);
+ }
+
+ static Artifact from(String groupId, String artifactId) {
+ return new Artifact() {
+ @Override
+ public String getGroupId() {
+ return groupId;
+ }
+
+ @Override
+ public String getArtifactId() {
+ return artifactId;
+ }
+
+ @Override
+ public Optional<String> getVersion() {
+ return Optional.empty();
+ }
+ };
+ }
+}
diff --git a/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/CamelArtifact.java b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/CamelArtifact.java
new file mode 100644
index 0000000000..4bf59316d6
--- /dev/null
+++ b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/CamelArtifact.java
@@ -0,0 +1,82 @@
+/*
+ * 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.quarkus.k.catalog.model;
+
+import java.util.Collections;
+import java.util.SortedSet;
+
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import org.immutables.value.Value;
+
+@Value.Immutable
+@Value.Style(depluralize = true)
+@JsonDeserialize(builder = CamelArtifact.Builder.class)
+@JsonPropertyOrder({ "groupId", "artifactId", "version" })
+public interface CamelArtifact extends Artifact {
+ @Value.Auxiliary
+ @Value.Default
+ @Value.NaturalOrder
+ default SortedSet<CamelScheme> getSchemes() {
+ return Collections.emptySortedSet();
+ }
+
+ @Value.Auxiliary
+ @Value.Default
+ @Value.NaturalOrder
+ default SortedSet<String> getLanguages() {
+ return Collections.emptySortedSet();
+ }
+
+ @Value.Auxiliary
+ @Value.Default
+ @Value.NaturalOrder
+ default SortedSet<String> getDataformats() {
+ return Collections.emptySortedSet();
+ }
+
+ @Value.Auxiliary
+ @Value.Default
+ @Value.NaturalOrder
+ default SortedSet<Artifact> getDependencies() {
+ return Collections.emptySortedSet();
+ }
+
+ @Value.Auxiliary
+ @Value.Default
+ @Value.NaturalOrder
+ default SortedSet<Artifact> getExclusions() {
+ return Collections.emptySortedSet();
+ }
+
+ @Value.Auxiliary
+ @Value.Default
+ @Value.NaturalOrder
+ default SortedSet<String> getJavaTypes() {
+ return Collections.emptySortedSet();
+ }
+
+ static Builder from(String groupId, String artifactId) {
+ return new Builder().groupId(groupId).artifactId(artifactId);
+ }
+
+ class Builder extends ImmutableCamelArtifact.Builder {
+ public Builder addDependency(String groupId, String artifactId) {
+ return super.addDependencies(Artifact.from(groupId, artifactId));
+ }
+ }
+}
diff --git a/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/CamelCapability.java b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/CamelCapability.java
new file mode 100644
index 0000000000..3b5485285c
--- /dev/null
+++ b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/CamelCapability.java
@@ -0,0 +1,47 @@
+/*
+ * 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.quarkus.k.catalog.model;
+
+import java.util.Collections;
+import java.util.SortedSet;
+
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import org.immutables.value.Value;
+
+@Value.Immutable
+@Value.Style(depluralize = true)
+@JsonDeserialize(builder = CamelCapability.Builder.class)
+@JsonPropertyOrder({ "groupId", "artifactId", "version" })
+public interface CamelCapability {
+ @Value.Auxiliary
+ @Value.Default
+ @Value.NaturalOrder
+ default SortedSet<Artifact> getDependencies() {
+ return Collections.emptySortedSet();
+ }
+
+ static CamelCapability forArtifact(String groupId, String artifactId) {
+ return new Builder().addDependency(groupId, artifactId).build();
+ }
+
+ class Builder extends ImmutableCamelCapability.Builder {
+ public Builder addDependency(String groupId, String artifactId) {
+ return super.addDependencies(Artifact.from(groupId, artifactId));
+ }
+ }
+}
diff --git a/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/CamelLoader.java b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/CamelLoader.java
new file mode 100644
index 0000000000..de952e3c66
--- /dev/null
+++ b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/CamelLoader.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.quarkus.k.catalog.model;
+
+import java.util.Collections;
+import java.util.SortedMap;
+import java.util.SortedSet;
+
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import org.immutables.value.Value;
+
+@Value.Immutable
+@Value.Style(depluralize = true)
+@JsonDeserialize(builder = CamelLoader.Builder.class)
+@JsonPropertyOrder({ "groupId", "artifactId", "version" })
+public interface CamelLoader extends Artifact {
+ @Value.Auxiliary
+ @Value.Default
+ @Value.NaturalOrder
+ default SortedSet<String> getLanguages() {
+ return Collections.emptySortedSet();
+ }
+
+ @Value.Auxiliary
+ @Value.Default
+ @Value.NaturalOrder
+ default SortedSet<Artifact> getDependencies() {
+ return Collections.emptySortedSet();
+ }
+
+ @Value.Auxiliary
+ @Value.Default
+ @Value.NaturalOrder
+ default SortedMap<String, String> getMetadata() {
+ return Collections.emptySortedMap();
+ }
+
+ static Builder fromArtifact(String groupId, String artifactId) {
+ return new Builder().groupId(groupId).artifactId(artifactId);
+ }
+
+ class Builder extends ImmutableCamelLoader.Builder {
+ public Builder addDependency(String groupId, String artifactId) {
+ return super.addDependencies(Artifact.from(groupId, artifactId));
+ }
+ }
+}
diff --git a/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/CamelScheme.java b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/CamelScheme.java
new file mode 100644
index 0000000000..a133e6f1bf
--- /dev/null
+++ b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/CamelScheme.java
@@ -0,0 +1,66 @@
+/*
+ * 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.quarkus.k.catalog.model;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Optional;
+import java.util.SortedSet;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import org.immutables.value.Value;
+
+@Value.Immutable
+@JsonDeserialize(builder = CamelScheme.Builder.class)
+public interface CamelScheme extends Comparable<CamelScheme> {
+ String getId();
+
+ @Value.Auxiliary
+ @Value.Default
+ default boolean http() {
+ return false;
+ }
+
+ @Value.Auxiliary
+ @Value.Default
+ default boolean passive() {
+ return false;
+ }
+
+ @Value.Auxiliary
+ @Value.Default
+ @Value.NaturalOrder
+ default SortedSet<String> getRequiredCapabilities() {
+ return Collections.emptySortedSet();
+ }
+
+ @Value.Auxiliary
+ Optional<CamelScopedArtifact> getProducer();
+
+ @Value.Auxiliary
+ Optional<CamelScopedArtifact> getConsumer();
+
+ @Override
+ default int compareTo(CamelScheme o) {
+ return Comparator
+ .comparing(CamelScheme::getId)
+ .compare(this, o);
+ }
+
+ class Builder extends ImmutableCamelScheme.Builder {
+ }
+}
diff --git a/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/CamelScopedArtifact.java b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/CamelScopedArtifact.java
new file mode 100644
index 0000000000..6960eb8a1b
--- /dev/null
+++ b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/CamelScopedArtifact.java
@@ -0,0 +1,50 @@
+/*
+ * 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.quarkus.k.catalog.model;
+
+import java.util.Collections;
+import java.util.SortedSet;
+
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import org.immutables.value.Value;
+
+@Value.Immutable
+@Value.Style(depluralize = true)
+@JsonDeserialize(builder = CamelScopedArtifact.Builder.class)
+@JsonPropertyOrder({ "dependencies", "required-capabilities" })
+public interface CamelScopedArtifact {
+ @Value.Auxiliary
+ @Value.Default
+ @Value.NaturalOrder
+ default SortedSet<Artifact> getDependencies() {
+ return Collections.emptySortedSet();
+ }
+
+ @Value.Auxiliary
+ @Value.Default
+ @Value.NaturalOrder
+ default SortedSet<String> getRequiredCapabilities() {
+ return Collections.emptySortedSet();
+ }
+
+ class Builder extends ImmutableCamelScopedArtifact.Builder {
+ public Builder addDependency(String groupId, String artifactId) {
+ return super.addDependencies(Artifact.from(groupId, artifactId));
+ }
+ }
+}
diff --git a/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/CatalogComponentDefinition.java b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/CatalogComponentDefinition.java
new file mode 100644
index 0000000000..94ec1fcd11
--- /dev/null
+++ b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/CatalogComponentDefinition.java
@@ -0,0 +1,80 @@
+/*
+ * 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.quarkus.k.catalog.model;
+
+import java.util.stream.Stream;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.apache.camel.util.StringHelper;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public final class CatalogComponentDefinition extends CatalogDefinition {
+ private String scheme;
+ private String alternativeSchemes;
+ private String javaType;
+
+ public Stream<String> getSchemes() {
+ final String schemeIDs = StringHelper.trimToNull(alternativeSchemes);
+
+ return schemeIDs == null
+ ? Stream.of(scheme)
+ : Stream.concat(
+ Stream.of(scheme),
+ StringHelper.splitAsStream(schemeIDs, ","));
+ }
+
+ public String getScheme() {
+ return scheme;
+ }
+
+ public void setScheme(String scheme) {
+ this.scheme = scheme;
+ }
+
+ public String getAlternativeSchemes() {
+ return alternativeSchemes;
+ }
+
+ public void setAlternativeSchemes(String alternativeSchemes) {
+ this.alternativeSchemes = alternativeSchemes;
+ }
+
+ public String getJavaType() {
+ return javaType;
+ }
+
+ public void setJavaType(String javaType) {
+ this.javaType = javaType;
+ }
+
+ @JsonIgnoreProperties(ignoreUnknown = true)
+ public static final class Container {
+ private final CatalogComponentDefinition delegate;
+
+ @JsonCreator
+ public Container(
+ @JsonProperty("component") CatalogComponentDefinition delegate) {
+ this.delegate = delegate;
+ }
+
+ public CatalogComponentDefinition unwrap() {
+ return delegate;
+ }
+ }
+}
diff --git a/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/CatalogDataFormatDefinition.java b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/CatalogDataFormatDefinition.java
new file mode 100644
index 0000000000..16f0a284d9
--- /dev/null
+++ b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/CatalogDataFormatDefinition.java
@@ -0,0 +1,58 @@
+/*
+ * 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.quarkus.k.catalog.model;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public final class CatalogDataFormatDefinition extends CatalogDefinition {
+ private String name;
+ private String javaType;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getJavaType() {
+ return javaType;
+ }
+
+ public void setJavaType(String javaType) {
+ this.javaType = javaType;
+ }
+
+ @JsonIgnoreProperties(ignoreUnknown = true)
+ public static final class Container {
+ private final CatalogDataFormatDefinition delegate;
+
+ @JsonCreator
+ public Container(
+ @JsonProperty("dataformat") CatalogDataFormatDefinition delegate) {
+ this.delegate = delegate;
+ }
+
+ public CatalogDataFormatDefinition unwrap() {
+ return delegate;
+ }
+ }
+}
diff --git a/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/CatalogDefinition.java b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/CatalogDefinition.java
new file mode 100644
index 0000000000..841d393e3d
--- /dev/null
+++ b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/CatalogDefinition.java
@@ -0,0 +1,47 @@
+/*
+ * 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.quarkus.k.catalog.model;
+
+public class CatalogDefinition {
+ private String groupId;
+ private String artifactId;
+ private String version;
+
+ public String getGroupId() {
+ return groupId;
+ }
+
+ public void setGroupId(String groupId) {
+ this.groupId = groupId;
+ }
+
+ public String getArtifactId() {
+ return artifactId;
+ }
+
+ public void setArtifactId(String artifactId) {
+ this.artifactId = artifactId;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+}
diff --git a/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/CatalogLanguageDefinition.java b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/CatalogLanguageDefinition.java
new file mode 100644
index 0000000000..44240711ec
--- /dev/null
+++ b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/CatalogLanguageDefinition.java
@@ -0,0 +1,58 @@
+/*
+ * 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.quarkus.k.catalog.model;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public final class CatalogLanguageDefinition extends CatalogDefinition {
+ private String name;
+ private String javaType;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getJavaType() {
+ return javaType;
+ }
+
+ public void setJavaType(String javaType) {
+ this.javaType = javaType;
+ }
+
+ @JsonIgnoreProperties(ignoreUnknown = true)
+ public static final class Container {
+ private final CatalogLanguageDefinition delegate;
+
+ @JsonCreator
+ public Container(
+ @JsonProperty("language") CatalogLanguageDefinition delegate) {
+ this.delegate = delegate;
+ }
+
+ public CatalogLanguageDefinition unwrap() {
+ return delegate;
+ }
+ }
+}
diff --git a/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/CatalogOtherDefinition.java b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/CatalogOtherDefinition.java
new file mode 100644
index 0000000000..69e658f0d5
--- /dev/null
+++ b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/CatalogOtherDefinition.java
@@ -0,0 +1,49 @@
+/*
+ * 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.quarkus.k.catalog.model;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public final class CatalogOtherDefinition extends CatalogDefinition {
+ private String label;
+
+ public String getLabel() {
+ return label;
+ }
+
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ @JsonIgnoreProperties(ignoreUnknown = true)
+ public static final class Container {
+ private final CatalogOtherDefinition delegate;
+
+ @JsonCreator
+ public Container(
+ @JsonProperty("other") CatalogOtherDefinition delegate) {
+ this.delegate = delegate;
+ }
+
+ public CatalogOtherDefinition unwrap() {
+ return delegate;
+ }
+ }
+}
diff --git a/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/CatalogSupport.java b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/CatalogSupport.java
new file mode 100644
index 0000000000..ea8ebe32c0
--- /dev/null
+++ b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/CatalogSupport.java
@@ -0,0 +1,51 @@
+/*
+ * 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.quarkus.k.catalog.model;
+
+import java.io.IOException;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public final class CatalogSupport {
+
+ private CatalogSupport() {
+ }
+
+ private static <T> T unmarshall(String json, Class<T> type) {
+ try {
+ return new ObjectMapper().readValue(json, type);
+ } catch (IOException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ public static CatalogComponentDefinition unmarshallComponent(String json) {
+ return unmarshall(json, CatalogComponentDefinition.Container.class).unwrap();
+ }
+
+ public static CatalogLanguageDefinition unmarshallLanguage(String json) {
+ return unmarshall(json, CatalogLanguageDefinition.Container.class).unwrap();
+ }
+
+ public static CatalogDataFormatDefinition unmarshallDataFormat(String json) {
+ return unmarshall(json, CatalogDataFormatDefinition.Container.class).unwrap();
+ }
+
+ public static CatalogOtherDefinition unmarshallOther(String json) {
+ return unmarshall(json, CatalogOtherDefinition.Container.class).unwrap();
+ }
+}
diff --git a/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/k8s/ObjectMeta.java b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/k8s/ObjectMeta.java
new file mode 100644
index 0000000000..5ee5b63e38
--- /dev/null
+++ b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/k8s/ObjectMeta.java
@@ -0,0 +1,38 @@
+/*
+ * 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.quarkus.k.catalog.model.k8s;
+
+import java.util.Collections;
+import java.util.SortedMap;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import org.immutables.value.Value;
+
+@Value.Immutable
+@JsonDeserialize(builder = ObjectMeta.Builder.class)
+public interface ObjectMeta {
+ String getName();
+
+ @Value.Default
+ @Value.NaturalOrder
+ default SortedMap<String, String> getLabels() {
+ return Collections.emptySortedMap();
+ }
+
+ class Builder extends ImmutableObjectMeta.Builder {
+ }
+}
diff --git a/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/k8s/TypeMeta.java b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/k8s/TypeMeta.java
new file mode 100644
index 0000000000..eca7a41213
--- /dev/null
+++ b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/k8s/TypeMeta.java
@@ -0,0 +1,37 @@
+/*
+ * 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.quarkus.k.catalog.model.k8s;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import org.immutables.value.Value;
+
+@Value.Immutable
+@JsonDeserialize(builder = TypeMeta.Builder.class)
+public interface TypeMeta {
+ @Value.Default
+ default String getApiVersion() {
+ return "camel.apache.org/v1";
+ }
+
+ @Value.Default
+ default String getKind() {
+ return "CamelCatalog";
+ }
+
+ class Builder extends ImmutableTypeMeta.Builder {
+ }
+}
diff --git a/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/k8s/crd/CamelCatalog.java b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/k8s/crd/CamelCatalog.java
new file mode 100644
index 0000000000..8747c81098
--- /dev/null
+++ b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/k8s/crd/CamelCatalog.java
@@ -0,0 +1,44 @@
+/*
+ * 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.quarkus.k.catalog.model.k8s.crd;
+
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import org.apache.camel.quarkus.k.catalog.model.k8s.ObjectMeta;
+import org.immutables.value.Value;
+
+@Value.Immutable
+@JsonDeserialize(builder = CamelCatalog.Builder.class)
+@JsonPropertyOrder({ "apiVersion", "kind", "metadata", "spec" })
+public interface CamelCatalog {
+ @Value.Default
+ default String getApiVersion() {
+ return "camel.apache.org/v1";
+ }
+
+ @Value.Default
+ default String getKind() {
+ return "CamelCatalog";
+ }
+
+ ObjectMeta getMetadata();
+
+ CamelCatalogSpec getSpec();
+
+ class Builder extends ImmutableCamelCatalog.Builder {
+ }
+}
diff --git a/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/k8s/crd/CamelCatalogSpec.java b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/k8s/crd/CamelCatalogSpec.java
new file mode 100644
index 0000000000..e36019947b
--- /dev/null
+++ b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/k8s/crd/CamelCatalogSpec.java
@@ -0,0 +1,56 @@
+/*
+ * 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.quarkus.k.catalog.model.k8s.crd;
+
+import java.util.Collections;
+import java.util.SortedMap;
+
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import org.apache.camel.quarkus.k.catalog.model.CamelArtifact;
+import org.apache.camel.quarkus.k.catalog.model.CamelLoader;
+import org.immutables.value.Value;
+
+@Value.Immutable
+@Value.Style(depluralize = true)
+@JsonDeserialize(builder = CamelCatalogSpec.Builder.class)
+@JsonPropertyOrder({ "runtime", "artifacts" })
+public interface CamelCatalogSpec {
+ RuntimeSpec getRuntime();
+
+ @Value.Default
+ @Value.NaturalOrder
+ default SortedMap<String, CamelArtifact> getArtifacts() {
+ return Collections.emptySortedMap();
+ }
+
+ @Value.Default
+ @Value.NaturalOrder
+ default SortedMap<String, CamelLoader> getLoaders() {
+ return Collections.emptySortedMap();
+ }
+
+ class Builder extends ImmutableCamelCatalogSpec.Builder {
+ public Builder putArtifact(CamelArtifact artifact) {
+ return putArtifact(artifact.getArtifactId(), artifact);
+ }
+
+ public Builder putArtifact(String groupId, String artifactId) {
+ return putArtifact(new CamelArtifact.Builder().groupId(groupId).artifactId(artifactId).build());
+ }
+ }
+}
diff --git a/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/k8s/crd/RuntimeSpec.java b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/k8s/crd/RuntimeSpec.java
new file mode 100644
index 0000000000..22c22ab62c
--- /dev/null
+++ b/tooling/camel-k-catalog-model/src/main/java/org/apache/camel/quarkus/k/catalog/model/k8s/crd/RuntimeSpec.java
@@ -0,0 +1,63 @@
+/*
+ * 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.quarkus.k.catalog.model.k8s.crd;
+
+import java.util.Collections;
+import java.util.SortedMap;
+import java.util.SortedSet;
+
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import org.apache.camel.quarkus.k.catalog.model.Artifact;
+import org.apache.camel.quarkus.k.catalog.model.CamelCapability;
+import org.immutables.value.Value;
+
+@Value.Immutable
+@Value.Style(depluralize = true)
+@JsonDeserialize(builder = RuntimeSpec.Builder.class)
+@JsonPropertyOrder({ "version", "runtimeVersion", "artifacts" })
+public interface RuntimeSpec {
+ String getProvider();
+
+ String getVersion();
+
+ String getApplicationClass();
+
+ @Value.Default
+ @Value.NaturalOrder
+ default SortedMap<String, String> getMetadata() {
+ return Collections.emptySortedMap();
+ }
+
+ @Value.Default
+ @Value.NaturalOrder
+ default SortedSet<Artifact> getDependencies() {
+ return Collections.emptySortedSet();
+ }
+
+ @Value.Default
+ @Value.NaturalOrder
+ default SortedMap<String, CamelCapability> getCapabilities() {
+ return Collections.emptySortedMap();
+ }
+
+ class Builder extends ImmutableRuntimeSpec.Builder {
+ public Builder addDependency(String groupId, String artifactId) {
+ return super.addDependencies(Artifact.from(groupId, artifactId));
+ }
+ }
+}
diff --git a/tooling/camel-k-maven-plugin/pom.xml b/tooling/camel-k-maven-plugin/pom.xml
new file mode 100644
index 0000000000..6abbc2b9e2
--- /dev/null
+++ b/tooling/camel-k-maven-plugin/pom.xml
@@ -0,0 +1,266 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-build-parent</artifactId>
+ <version>3.3.0-SNAPSHOT</version>
+ <relativePath>../../poms/build-parent/pom.xml</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>camel-quarkus-camel-k-maven-plugin</artifactId>
+ <name>Camel Quarkus :: Tooling :: Camel K Maven Plugin</name>
+ <description>Maven plugin to generate the catalog of artifacts specific to Camel K.</description>
+ <packaging>maven-plugin</packaging>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-bom</artifactId>
+ <version>${quarkus.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-bom</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-camel-k-catalog-model</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-openapi-rest-dsl-generator</artifactId>
+ <version>${camel.version}</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-core</artifactId>
+ <scope>provided</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>com.google.code.findbugs</groupId>
+ <artifactId>jsr305</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>javax.inject</groupId>
+ <artifactId>javax.inject</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-classworlds</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.plugin-tools</groupId>
+ <artifactId>maven-plugin-annotations</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-camel-k-catalog-model</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-openapi-rest-dsl-generator</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-core-catalog</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-catalog</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-catalog</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.datatype</groupId>
+ <artifactId>jackson-datatype-jdk8</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.dataformat</groupId>
+ <artifactId>jackson-dataformat-yaml</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifest>
+ <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+ <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
+ </manifest>
+ </archive>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <configuration>
+ <mojoDependencies>
+ <dep>org.apache.maven:maven-plugin-api</dep>
+ </mojoDependencies>
+ </configuration>
+ <executions>
+ <execution>
+ <id>default-descriptor</id>
+ <phase>process-classes</phase>
+ <goals>
+ <goal>descriptor</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <!-- Sanity checks and formatting are disabled when building with '-Dquickly' -->
+ <id>full</id>
+ <activation>
+ <property>
+ <name>!quickly</name>
+ </property>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-invoker-plugin</artifactId>
+ <configuration>
+ <scriptVariables>
+ <camelVersion>${camel.version}</camelVersion>
+ <camelQuarkusVersion>${project.version}</camelQuarkusVersion>
+ <quarkusVersion>${quarkus.version}</quarkusVersion>
+ </scriptVariables>
+ <pomIncludes>
+ <pomInclude>generate-catalog/pom.xml</pomInclude>
+ <pomInclude>generate-catalog-with-exclusions/pom.xml</pomInclude>
+ <pomInclude>generate-dependencies/pom.xml</pomInclude>
+ <pomInclude>generate-rest-dsl-from-v2/pom.xml</pomInclude>
+ <pomInclude>generate-rest-dsl-from-v3/pom.xml</pomInclude>
+ </pomIncludes>
+ <cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>
+ <cloneClean>true</cloneClean>
+ <postBuildHookScript>verify</postBuildHookScript>
+ <addTestClassPath>true</addTestClassPath>
+ <streamLogs>true</streamLogs>
+ <goals>
+ <goal>prepare-package</goal>
+ </goals>
+ </configuration>
+ <executions>
+ <execution>
+ <id>integration-tests</id>
+ <goals>
+ <goal>install</goal>
+ <goal>run</goal>
+ <goal>verify</goal>
+ </goals>
+ <configuration>
+ <properties>
+ <com.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize>true
+ </com.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize>
+ <failIfNoTests>false</failIfNoTests>
+ </properties>
+ </configuration>
+ </execution>
+ </executions>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.groovy</groupId>
+ <artifactId>groovy</artifactId>
+ <version>${groovy.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.groovy</groupId>
+ <artifactId>groovy-yaml</artifactId>
+ <version>${groovy.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.groovy</groupId>
+ <artifactId>groovy-json</artifactId>
+ <version>${groovy.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.groovy</groupId>
+ <artifactId>groovy-xml</artifactId>
+ <version>${groovy.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-collections4</artifactId>
+ <version>${commons-collections4-version}</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+
+ </profiles>
+</project>
diff --git a/tooling/camel-k-maven-plugin/src/it/generate-catalog-with-exclusions/pom.xml b/tooling/camel-k-maven-plugin/src/it/generate-catalog-with-exclusions/pom.xml
new file mode 100644
index 0000000000..05a73e4463
--- /dev/null
+++ b/tooling/camel-k-maven-plugin/src/it/generate-catalog-with-exclusions/pom.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.camel.k</groupId>
+ <artifactId>camel-k-catalog-generator</artifactId>
+ <version>1.0.0</version>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <catalog.dir>${project.basedir}</catalog.dir>
+ <catalog.runtime>quarkus</catalog.runtime>
+ <catalog.file>catalog.yaml</catalog.file>
+ <!-- exclusion list -->
+ <dsls.exclusion.list>jsh,js,kts,groovy</dsls.exclusion.list>
+ <dataformats.exclusion.list>avro-jackson</dataformats.exclusion.list>
+ <languages.exclusion.list>csimple</languages.exclusion.list>
+ <components.exclusion.list>disruptor,disruptor-vm</components.exclusion.list>
+ <others.exclusion.list>jta,redis</others.exclusion.list>
+ <capabilities.exclusion.list>master</capabilities.exclusion.list>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-camel-k-maven-plugin</artifactId>
+ <version>@project.version@</version>
+ <executions>
+ <execution>
+ <id>generate-catalog</id>
+ <goals>
+ <goal>generate-catalog</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <repositories>
+ <repository>
+ <id>apache.snapshots</id>
+ <name>Apache Development Snapshot Repository</name>
+ <url>https://repository.apache.org/content/repositories/snapshots/</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </repository>
+ <repository>
+ <id>oss.snapshots</id>
+ <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+
+ <pluginRepositories>
+ <pluginRepository>
+ <id>apache.snapshots</id>
+ <name>Apache Development Snapshot Repository</name>
+ <url>https://repository.apache.org/content/repositories/snapshots/</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </pluginRepository>
+ <pluginRepository>
+ <id>oss.snapshots</id>
+ <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </pluginRepository>
+ </pluginRepositories>
+
+</project>
diff --git a/tooling/camel-k-maven-plugin/src/it/generate-catalog-with-exclusions/verify.groovy b/tooling/camel-k-maven-plugin/src/it/generate-catalog-with-exclusions/verify.groovy
new file mode 100644
index 0000000000..53725658e7
--- /dev/null
+++ b/tooling/camel-k-maven-plugin/src/it/generate-catalog-with-exclusions/verify.groovy
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+new File(basedir, "catalog.yaml").withReader {
+ def catalog = new groovy.yaml.YamlSlurper().parse(it)
+
+ assert catalog.spec.loaders['jsh'] == null
+ assert catalog.spec.loaders['kts'] == null
+ assert catalog.spec.loaders['js'] == null
+ assert catalog.spec.loaders['groovy'] == null
+
+ assert catalog.spec.loaders['java'] != null
+ assert catalog.spec.loaders['xml'] != null
+ assert catalog.spec.loaders['yaml'] != null
+
+ assert catalog.spec.artifacts['camel-quarkus-jackson-avro'] != null
+ assert catalog.spec.artifacts['camel-quarkus-csimple'] == null
+ assert catalog.spec.artifacts['camel-quarkus-disruptor'] == null
+
+ assert catalog.spec.artifacts['camel-quarkus-debug'] != null
+ assert catalog.spec.artifacts['camel-quarkus-jta'] == null
+ assert catalog.spec.artifacts['camel-quarkus-redis'] == null
+
+ assert catalog.spec.runtime.capabilities['master'] == null
+ assert catalog.spec.artifacts['camel-k-master'] == null
+}
diff --git a/tooling/camel-k-maven-plugin/src/it/generate-catalog/pom.xml b/tooling/camel-k-maven-plugin/src/it/generate-catalog/pom.xml
new file mode 100644
index 0000000000..ef164af6ff
--- /dev/null
+++ b/tooling/camel-k-maven-plugin/src/it/generate-catalog/pom.xml
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.camel.k</groupId>
+ <artifactId>camel-k-catalog-generator</artifactId>
+ <version>1.0.0</version>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <catalog.dir>${project.basedir}</catalog.dir>
+ <catalog.runtime>quarkus</catalog.runtime>
+ <catalog.file>catalog.yaml</catalog.file>
+ <!-- If needed, components can be excluded with the exclusion.list property -->
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-camel-k-maven-plugin</artifactId>
+ <version>@project.version@</version>
+ <executions>
+ <execution>
+ <id>generate-catalog</id>
+ <goals>
+ <goal>generate-catalog</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <repositories>
+ <repository>
+ <id>apache.snapshots</id>
+ <name>Apache Development Snapshot Repository</name>
+ <url>https://repository.apache.org/content/repositories/snapshots/</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </repository>
+ <repository>
+ <id>oss.snapshots</id>
+ <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+
+ <pluginRepositories>
+ <pluginRepository>
+ <id>apache.snapshots</id>
+ <name>Apache Development Snapshot Repository</name>
+ <url>https://repository.apache.org/content/repositories/snapshots/</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </pluginRepository>
+ <pluginRepository>
+ <id>oss.snapshots</id>
+ <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </pluginRepository>
+ </pluginRepositories>
+
+</project>
diff --git a/tooling/camel-k-maven-plugin/src/it/generate-catalog/verify.groovy b/tooling/camel-k-maven-plugin/src/it/generate-catalog/verify.groovy
new file mode 100644
index 0000000000..43c1d13f2d
--- /dev/null
+++ b/tooling/camel-k-maven-plugin/src/it/generate-catalog/verify.groovy
@@ -0,0 +1,121 @@
+/*
+ * 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.
+ */
+
+new File(basedir, "catalog.yaml").withReader {
+ def catalog = new groovy.yaml.YamlSlurper().parse(it)
+
+ // assert catalog.spec.runtime.version == runtimeVersion
+ assert catalog.spec.runtime.applicationClass == 'io.quarkus.bootstrap.runner.QuarkusEntryPoint'
+ assert catalog.spec.runtime.metadata['camel.version'] == camelVersion
+ // Re-enabled this when the version will be the same again
+ assert catalog.spec.runtime.metadata['quarkus.version'] == quarkusVersion
+ assert catalog.spec.runtime.metadata['camel-quarkus.version'] == camelQuarkusVersion
+ // assert catalog.spec.runtime.metadata['quarkus.native-builder-image'] == quarkusNativeBuilderImage
+
+ assert catalog.spec.runtime.dependencies.any {
+ it.groupId == 'org.apache.camel.quarkus' && it.artifactId == 'camel-quarkus-k-runtime'
+ }
+
+ assert catalog.spec.runtime.capabilities['cron'].dependencies[0].groupId == 'org.apache.camel.quarkus'
+ assert catalog.spec.runtime.capabilities['cron'].dependencies[0].artifactId == 'camel-k-cron'
+ assert catalog.spec.runtime.capabilities['health'].dependencies[0].groupId == 'org.apache.camel.quarkus'
+ assert catalog.spec.runtime.capabilities['health'].dependencies[0].artifactId == 'camel-quarkus-microprofile-health'
+ assert catalog.spec.runtime.capabilities['rest'].dependencies.any { it.groupId == 'org.apache.camel.quarkus' && it.artifactId == 'camel-quarkus-rest' }
+ assert catalog.spec.runtime.capabilities['rest'].dependencies.any { it.groupId == 'org.apache.camel.quarkus' && it.artifactId == 'camel-quarkus-platform-http' }
+ assert catalog.spec.runtime.capabilities['platform-http'].dependencies[0].groupId == 'org.apache.camel.quarkus'
+ assert catalog.spec.runtime.capabilities['platform-http'].dependencies[0].artifactId == 'camel-quarkus-platform-http'
+ assert catalog.spec.runtime.capabilities['circuit-breaker'].dependencies[0].groupId == 'org.apache.camel.quarkus'
+ assert catalog.spec.runtime.capabilities['circuit-breaker'].dependencies[0].artifactId == 'camel-quarkus-microprofile-fault-tolerance'
+ assert catalog.spec.runtime.capabilities['tracing'].dependencies[0].groupId == 'org.apache.camel.quarkus'
+ assert catalog.spec.runtime.capabilities['tracing'].dependencies[0].artifactId == 'camel-quarkus-opentracing'
+ assert catalog.spec.runtime.capabilities['telemetry'].dependencies[0].groupId == 'org.apache.camel.quarkus'
+ assert catalog.spec.runtime.capabilities['telemetry'].dependencies[0].artifactId == 'camel-quarkus-opentelemetry'
+ assert catalog.spec.runtime.capabilities['master'].dependencies[0].groupId == 'org.apache.camel.quarkus'
+ assert catalog.spec.runtime.capabilities['master'].dependencies[0].artifactId == 'camel-k-master'
+
+ assert catalog.spec.loaders['groovy'].groupId == 'org.apache.camel.quarkus'
+ assert catalog.spec.loaders['groovy'].artifactId == 'camel-quarkus-groovy-dsl'
+ assert catalog.spec.loaders['groovy'].languages[0] == 'groovy'
+ assert catalog.spec.loaders['groovy'].metadata['native'] == 'true'
+ assert catalog.spec.loaders['groovy'].metadata['sources-required-at-build-time'] == 'true'
+ assert catalog.spec.loaders['java'].groupId == 'org.apache.camel.quarkus'
+ assert catalog.spec.loaders['java'].artifactId == 'camel-quarkus-java-joor-dsl'
+ assert catalog.spec.loaders['java'].languages[0] == 'java'
+ assert catalog.spec.loaders['java'].metadata['native'] == 'true'
+ assert catalog.spec.loaders['java'].metadata['sources-required-at-build-time'] == 'true'
+ assert catalog.spec.loaders['jsh'].groupId == 'org.apache.camel.quarkus'
+ assert catalog.spec.loaders['jsh'].artifactId == 'camel-quarkus-jsh-dsl'
+ assert catalog.spec.loaders['jsh'].languages[0] == 'jsh'
+ assert catalog.spec.loaders['jsh'].metadata['native'] == 'false'
+ assert catalog.spec.loaders['jsh'].metadata['sources-required-at-build-time'] == 'true'
+ assert catalog.spec.loaders['kts'].groupId == 'org.apache.camel.quarkus'
+ assert catalog.spec.loaders['kts'].artifactId == 'camel-quarkus-kotlin-dsl'
+ assert catalog.spec.loaders['kts'].languages[0] == 'kts'
+ assert catalog.spec.loaders['kts'].metadata['native'] == 'true'
+ assert catalog.spec.loaders['kts'].metadata['sources-required-at-build-time'] == 'true'
+ assert catalog.spec.loaders['js'].groupId == 'org.apache.camel.quarkus'
+ assert catalog.spec.loaders['js'].artifactId == 'camel-quarkus-js-dsl'
+ assert catalog.spec.loaders['js'].languages[0] == 'js'
+ assert catalog.spec.loaders['js'].metadata['native'] == 'false'
+ assert catalog.spec.loaders['js'].metadata['sources-required-at-build-time'] == null
+ assert catalog.spec.loaders['xml'].groupId == 'org.apache.camel.quarkus'
+ assert catalog.spec.loaders['xml'].artifactId == 'camel-quarkus-xml-io-dsl'
+ assert catalog.spec.loaders['xml'].languages[0] == 'xml'
+ assert catalog.spec.loaders['xml'].metadata['native'] == 'true'
+ assert catalog.spec.loaders['xml'].metadata['sources-required-at-build-time'] == null
+ assert catalog.spec.loaders['yaml'].groupId == 'org.apache.camel.quarkus'
+ assert catalog.spec.loaders['yaml'].artifactId == 'camel-quarkus-yaml-dsl'
+ assert catalog.spec.loaders['yaml'].languages[0] == 'yaml'
+ assert catalog.spec.loaders['yaml'].metadata['native'] == 'true'
+ assert catalog.spec.loaders['yaml'].metadata['sources-required-at-build-time'] == null
+
+ assert catalog.metadata.labels['camel.apache.org/runtime.version'] == camelQuarkusVersion
+
+ catalog.spec.artifacts['camel-k-master'].with {
+ schemes == null
+ }
+ catalog.spec.artifacts['camel-k-cron'].with {
+ schemes == null
+ }
+
+ def diff = org.apache.commons.collections4.CollectionUtils.disjunction(
+ catalog.spec.artifacts.values()
+ .findAll { it.schemes != null }
+ .collect { it.schemes.collect { it.id } }
+ .flatten(),
+ catalog.spec.artifacts.values()
+ .findAll { it.schemes != null }
+ .collect { it.schemes.collect { it.id } }
+ .flatten()
+ .unique()
+ )
+
+ assert diff.size() == 0 : "Duplicated schemes: ${diff}"
+
+ catalog.spec.artifacts.each { k,v ->
+ assert k != null
+ assert v.groupId != null
+ assert v.artifactId != null
+ assert v.version == null
+ }
+
+ catalog.spec.artifacts['camel-quarkus-knative'].with {
+ assert dependencies == null
+ assert requiredCapabilities == null
+ assert schemes.size() == 1
+ }
+}
diff --git a/tooling/camel-k-maven-plugin/src/it/generate-dependencies/pom.xml b/tooling/camel-k-maven-plugin/src/it/generate-dependencies/pom.xml
new file mode 100644
index 0000000000..2e86fee3c4
--- /dev/null
+++ b/tooling/camel-k-maven-plugin/src/it/generate-dependencies/pom.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.camel.k</groupId>
+ <artifactId>camel-k-catalog-generator</artifactId>
+ <version>1.0.0</version>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <dependencies.file>${project.basedir}/dependencies.yaml</dependencies.file>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ <version>1.14</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-camel-k-maven-plugin</artifactId>
+ <version>@project.version@</version>
+ <executions>
+ <execution>
+ <id>generate-dependency-list</id>
+ <goals>
+ <goal>generate-dependency-list</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <repositories>
+ <repository>
+ <id>apache.snapshots</id>
+ <name>Apache Development Snapshot Repository</name>
+ <url>https://repository.apache.org/content/repositories/snapshots/</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </repository>
+ <repository>
+ <id>oss.snapshots</id>
+ <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+
+ <pluginRepositories>
+ <pluginRepository>
+ <id>apache.snapshots</id>
+ <name>Apache Development Snapshot Repository</name>
+ <url>https://repository.apache.org/content/repositories/snapshots/</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </pluginRepository>
+ <pluginRepository>
+ <id>oss.snapshots</id>
+ <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </pluginRepository>
+ </pluginRepositories>
+
+</project>
diff --git a/tooling/camel-k-maven-plugin/src/it/generate-dependencies/verify.groovy b/tooling/camel-k-maven-plugin/src/it/generate-dependencies/verify.groovy
new file mode 100644
index 0000000000..465fa68ddf
--- /dev/null
+++ b/tooling/camel-k-maven-plugin/src/it/generate-dependencies/verify.groovy
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+import org.apache.commons.codec.digest.DigestUtils
+
+import java.nio.charset.StandardCharsets
+import java.nio.file.Files
+
+new File(basedir, "dependencies.yaml").withReader {
+ def deps = new groovy.yaml.YamlSlurper().parse(it)
+
+ assert deps.dependencies.size() != 0
+
+ for (Map<String, String> dependency: deps.dependencies) {
+ dependency.checksum != null
+ dependency.location != null
+ dependency.id != null
+
+ File checksum
+
+ if ((checksum = new File("${dependency.location}.md5")).exists()) {
+ assert dependency.checksum == "md5:" + Files.readString(checksum.toPath(), StandardCharsets.UTF_8)
+ } else if ((checksum = new File("${dependency.location}.sha1")).exists()) {
+ assert dependency.checksum == "sha1:" + Files.readString(checksum.toPath(), StandardCharsets.UTF_8)
+ } else {
+ def file = new File(dependency.location)
+ def bytes = Files.readAllBytes(file.toPath())
+
+ assert dependency.checksum == "sha1:" + DigestUtils.sha1Hex(bytes)
+ }
+ }
+}
diff --git a/tooling/camel-k-maven-plugin/src/it/generate-rest-dsl-from-v2/document.json b/tooling/camel-k-maven-plugin/src/it/generate-rest-dsl-from-v2/document.json
new file mode 100644
index 0000000000..48e8f9e7fd
--- /dev/null
+++ b/tooling/camel-k-maven-plugin/src/it/generate-rest-dsl-from-v2/document.json
@@ -0,0 +1,46 @@
+{
+ "swagger" : "2.0",
+ "info" : {
+ "version" : "1.0",
+ "title" : "Greeting REST API"
+ },
+ "host" : "",
+ "basePath" : "/camel/",
+ "tags" : [ {
+ "name" : "greetings",
+ "description" : "Greeting to {name}"
+ } ],
+ "schemes" : [ "http" ],
+ "paths" : {
+ "/greetings/{name}" : {
+ "get" : {
+ "tags" : [ "greetings" ],
+ "operationId" : "greeting-api",
+ "parameters" : [ {
+ "name" : "name",
+ "in" : "path",
+ "required" : true,
+ "type" : "string"
+ } ],
+ "responses" : {
+ "200" : {
+ "description" : "Output type",
+ "schema" : {
+ "$ref" : "#/definitions/Greetings"
+ }
+ }
+ }
+ }
+ }
+ },
+ "definitions" : {
+ "Greetings" : {
+ "type" : "object",
+ "properties" : {
+ "greetings" : {
+ "type" : "string"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/tooling/camel-k-maven-plugin/src/it/generate-rest-dsl-from-v2/pom.xml b/tooling/camel-k-maven-plugin/src/it/generate-rest-dsl-from-v2/pom.xml
new file mode 100644
index 0000000000..2d1e7cd007
--- /dev/null
+++ b/tooling/camel-k-maven-plugin/src/it/generate-rest-dsl-from-v2/pom.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.camel.k</groupId>
+ <artifactId>camel-k-catalog-generator</artifactId>
+ <version>1.0.0</version>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <openapi.spec>${project.basedir}/document.json</openapi.spec>
+ <dsl.out>${project.basedir}/document.xml</dsl.out>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-camel-k-maven-plugin</artifactId>
+ <version>@project.version@</version>
+ <executions>
+ <execution>
+ <id>generate-rest-xml</id>
+ <goals>
+ <goal>generate-rest-xml</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <repositories>
+ <repository>
+ <id>apache.snapshots</id>
+ <name>Apache Development Snapshot Repository</name>
+ <url>https://repository.apache.org/content/repositories/snapshots/</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </repository>
+ <repository>
+ <id>oss.snapshots</id>
+ <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+
+ <pluginRepositories>
+ <pluginRepository>
+ <id>apache.snapshots</id>
+ <name>Apache Development Snapshot Repository</name>
+ <url>https://repository.apache.org/content/repositories/snapshots/</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </pluginRepository>
+ <pluginRepository>
+ <id>oss.snapshots</id>
+ <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </pluginRepository>
+ </pluginRepositories>
+
+</project>
diff --git a/tooling/camel-k-maven-plugin/src/it/generate-rest-dsl-from-v2/verify.groovy b/tooling/camel-k-maven-plugin/src/it/generate-rest-dsl-from-v2/verify.groovy
new file mode 100644
index 0000000000..9dfe128c1f
--- /dev/null
+++ b/tooling/camel-k-maven-plugin/src/it/generate-rest-dsl-from-v2/verify.groovy
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+
+new File(basedir, "document.xml").withReader {
+ def document = new groovy.util.XmlSlurper().parse(it)
+
+ assert document.rest.@path == '/camel/'
+ assert document.rest.get.size() == 1
+ assert document.rest.get[0].@id == 'greeting-api'
+ assert document.rest.get[0].@path == '/greetings/{name}'
+ assert document.rest.get[0].to.@uri == 'direct:greeting-api'
+}
diff --git a/tooling/camel-k-maven-plugin/src/it/generate-rest-dsl-from-v3/document.yaml b/tooling/camel-k-maven-plugin/src/it/generate-rest-dsl-from-v3/document.yaml
new file mode 100644
index 0000000000..7d0d31a214
--- /dev/null
+++ b/tooling/camel-k-maven-plugin/src/it/generate-rest-dsl-from-v3/document.yaml
@@ -0,0 +1,128 @@
+#
+# 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.
+#
+
+openapi: "3.0.0"
+info:
+ version: 1.0.0
+ title: Swagger Petstore
+ license:
+ name: MIT
+servers:
+ - url: http://petstore.swagger.io/v1
+paths:
+ /pets:
+ get:
+ summary: List all pets
+ operationId: listPets
+ tags:
+ - pets
+ parameters:
+ - name: limit
+ in: query
+ description: How many items to return at one time (max 100)
+ required: false
+ schema:
+ type: integer
+ format: int32
+ responses:
+ '200':
+ description: A paged array of pets
+ headers:
+ x-next:
+ description: A link to the next page of responses
+ schema:
+ type: string
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Pets"
+ default:
+ description: unexpected error
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+ post:
+ summary: Create a pet
+ operationId: createPets
+ tags:
+ - pets
+ responses:
+ '201':
+ description: Null response
+ default:
+ description: unexpected error
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+ /pets/{petId}:
+ get:
+ summary: Info for a specific pet
+ operationId: showPetById
+ tags:
+ - pets
+ parameters:
+ - name: petId
+ in: path
+ required: true
+ description: The id of the pet to retrieve
+ schema:
+ type: string
+ responses:
+ '200':
+ description: Expected response to a valid request
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Pet"
+ default:
+ description: unexpected error
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Error"
+components:
+ schemas:
+ Pet:
+ type: object
+ required:
+ - id
+ - name
+ properties:
+ id:
+ type: integer
+ format: int64
+ name:
+ type: string
+ tag:
+ type: string
+ Pets:
+ type: array
+ items:
+ $ref: "#/components/schemas/Pet"
+ Error:
+ type: object
+ required:
+ - code
+ - message
+ properties:
+ code:
+ type: integer
+ format: int32
+ message:
+ type: string
diff --git a/tooling/camel-k-maven-plugin/src/it/generate-rest-dsl-from-v3/pom.xml b/tooling/camel-k-maven-plugin/src/it/generate-rest-dsl-from-v3/pom.xml
new file mode 100644
index 0000000000..5ebe40e0a6
--- /dev/null
+++ b/tooling/camel-k-maven-plugin/src/it/generate-rest-dsl-from-v3/pom.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.camel.k</groupId>
+ <artifactId>camel-k-catalog-generator</artifactId>
+ <version>1.0.0</version>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <openapi.spec>${project.basedir}/document.yaml</openapi.spec>
+ <dsl.out>${project.basedir}/document.xml</dsl.out>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-camel-k-maven-plugin</artifactId>
+ <version>@project.version@</version>
+ <executions>
+ <execution>
+ <id>generate-rest-xml</id>
+ <goals>
+ <goal>generate-rest-xml</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <repositories>
+ <repository>
+ <id>apache.snapshots</id>
+ <name>Apache Development Snapshot Repository</name>
+ <url>https://repository.apache.org/content/repositories/snapshots/</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </repository>
+ <repository>
+ <id>oss.snapshots</id>
+ <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+
+ <pluginRepositories>
+ <pluginRepository>
+ <id>apache.snapshots</id>
+ <name>Apache Development Snapshot Repository</name>
+ <url>https://repository.apache.org/content/repositories/snapshots/</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </pluginRepository>
+ <pluginRepository>
+ <id>oss.snapshots</id>
+ <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </pluginRepository>
+ </pluginRepositories>
+
+</project>
diff --git a/tooling/camel-k-maven-plugin/src/it/generate-rest-dsl-from-v3/verify.groovy b/tooling/camel-k-maven-plugin/src/it/generate-rest-dsl-from-v3/verify.groovy
new file mode 100644
index 0000000000..6be540e4c8
--- /dev/null
+++ b/tooling/camel-k-maven-plugin/src/it/generate-rest-dsl-from-v3/verify.groovy
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+new File(basedir, "document.xml").withReader {
+ def document = new groovy.util.XmlSlurper().parse(it)
+
+ assert document.rest.@path == '/v1'
+ assert document.rest.get.size() == 2
+ assert document.rest.get.find { it.@id == 'listPets' }.@path == '/pets'
+ assert document.rest.get.find { it.@id == 'listPets' }.to.@uri == 'direct:listPets'
+ assert document.rest.get.find { it.@id == 'showPetById' }.@path == '/pets/{petId}'
+ assert document.rest.get.find { it.@id == 'showPetById' }.to.@uri == 'direct:showPetById'
+ assert document.rest.post.find { it.@id == 'createPets' }.@path == '/pets'
+ assert document.rest.post.find { it.@id == 'createPets' }.to.@uri == 'direct:createPets'
+}
diff --git a/tooling/camel-k-maven-plugin/src/main/java/org/apache/camel/quarkus/k/tooling/maven/GenerateCatalogMojo.java b/tooling/camel-k-maven-plugin/src/main/java/org/apache/camel/quarkus/k/tooling/maven/GenerateCatalogMojo.java
new file mode 100644
index 0000000000..894cfc746e
--- /dev/null
+++ b/tooling/camel-k-maven-plugin/src/main/java/org/apache/camel/quarkus/k/tooling/maven/GenerateCatalogMojo.java
@@ -0,0 +1,512 @@
+/*
+ * 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.quarkus.k.tooling.maven;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
+import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;
+import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
+import org.apache.camel.catalog.DefaultCamelCatalog;
+import org.apache.camel.catalog.quarkus.QuarkusRuntimeProvider;
+import org.apache.camel.impl.engine.AbstractCamelContext;
+import org.apache.camel.quarkus.core.FastCamelContext;
+import org.apache.camel.quarkus.k.catalog.model.CamelArtifact;
+import org.apache.camel.quarkus.k.catalog.model.CamelCapability;
+import org.apache.camel.quarkus.k.catalog.model.CamelLoader;
+import org.apache.camel.quarkus.k.catalog.model.CamelScheme;
+import org.apache.camel.quarkus.k.catalog.model.CatalogComponentDefinition;
+import org.apache.camel.quarkus.k.catalog.model.CatalogDataFormatDefinition;
+import org.apache.camel.quarkus.k.catalog.model.CatalogDefinition;
+import org.apache.camel.quarkus.k.catalog.model.CatalogLanguageDefinition;
+import org.apache.camel.quarkus.k.catalog.model.CatalogOtherDefinition;
+import org.apache.camel.quarkus.k.catalog.model.CatalogSupport;
+import org.apache.camel.quarkus.k.catalog.model.k8s.ObjectMeta;
+import org.apache.camel.quarkus.k.catalog.model.k8s.crd.CamelCatalog;
+import org.apache.camel.quarkus.k.catalog.model.k8s.crd.CamelCatalogSpec;
+import org.apache.camel.quarkus.k.catalog.model.k8s.crd.RuntimeSpec;
+import org.apache.camel.quarkus.k.tooling.maven.support.MavenSupport;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+
+@Mojo(name = "generate-catalog", defaultPhase = LifecyclePhase.GENERATE_RESOURCES, threadSafe = true, requiresProject = false, requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, requiresDependencyCollection = ResolutionScope.COMPILE_PLUS_RUNTIME)
+public class GenerateCatalogMojo extends AbstractMojo {
+ private static final List<String> KNOWN_HTTP_URIS = Arrays.asList(
+ "ahc",
+ "ahc-ws",
+ "atmosphere-websocket",
+ "cxf",
+ "cxfrs",
+ "grpc",
+ "jetty",
+ "knative",
+ "netty-http",
+ "platform-http",
+ "rest",
+ "restlet",
+ "servlet",
+ "spark-rest",
+ "spring-ws",
+ "undertow",
+ "webhook",
+ "websocket");
+
+ private static final List<String> KNOWN_PASSIVE_URIS = Arrays.asList(
+ "bean",
+ "binding",
+ "browse",
+ "class",
+ "controlbus",
+ "dataformat",
+ "dataset",
+ "direct",
+ "direct-vm",
+ "language",
+ "log",
+ "mock",
+ "ref",
+ "seda",
+ "stub",
+ "test",
+ "validator",
+ "vm");
+
+ @Parameter(property = "catalog.dir", defaultValue = "${project.build.directory}")
+ private String outputPath;
+
+ @Parameter(property = "catalog.file", defaultValue = "camel-k-catalog.yaml")
+ private String outputFile;
+
+ @Parameter(property = "components.exclusion.list")
+ private Set<String> componentsExclusionList;
+
+ @Parameter(property = "dataformats.exclusion.list")
+ private Set<String> dataformatsExclusionList;
+
+ @Parameter(property = "languages.exclusion.list")
+ private Set<String> languagesExclusionList;
+
+ @Parameter(property = "others.exclusion.list")
+ private Set<String> othersExclusionList;
+
+ @Parameter(property = "dsls.exclusion.list")
+ private Set<String> dslsExclusionList;
+
+ @Parameter(property = "capabilities.exclusion.list")
+ private Set<String> capabilitiesExclusionList;
+
+ // ********************
+ //
+ // ********************
+
+ @Override
+ public void execute() throws MojoExecutionException, MojoFailureException {
+ final Path output = Paths.get(this.outputPath, this.outputFile);
+
+ try {
+ if (Files.notExists(output.getParent())) {
+ Files.createDirectories(output.getParent());
+ }
+ if (Files.exists(output)) {
+ Files.delete(output);
+ }
+ } catch (IOException e) {
+ throw new MojoExecutionException("Exception while generating camel catalog", e);
+ }
+
+ final org.apache.camel.catalog.CamelCatalog catalog = new DefaultCamelCatalog();
+ catalog.setRuntimeProvider(new QuarkusRuntimeProvider());
+
+ final String runtimeVersion = MavenSupport.getVersion(getClass(),
+ "/META-INF/maven/org.apache.camel.quarkus.k.camel-k-maven-plugin/pom.properties");
+ final String catalogName = String.format("camel-catalog-%s", runtimeVersion.toLowerCase(Locale.US));
+
+ try {
+ CamelCatalogSpec.Builder catalogSpec = new CamelCatalogSpec.Builder();
+
+ RuntimeSpec.Builder runtimeSpec = new RuntimeSpec.Builder()
+ .version(runtimeVersion)
+ .provider("quarkus");
+
+ MavenSupport.getVersion(
+ AbstractCamelContext.class,
+ "org.apache.camel", "camel-base",
+ version -> runtimeSpec.putMetadata("camel.version", version));
+ MavenSupport.getVersion(
+ FastCamelContext.class,
+ "io.quarkus", "quarkus-core",
+ version -> runtimeSpec.putMetadata("quarkus.version", version));
+ MavenSupport.getVersion(
+ QuarkusRuntimeProvider.class,
+ "org.apache.camel.quarkus", "camel-quarkus-catalog",
+ version -> runtimeSpec.putMetadata("camel-quarkus.version", version));
+
+ runtimeSpec.putMetadata("quarkus.native-builder-image",
+ MavenSupport.getApplicationProperty(getClass(), "quarkus.native-builder-image"));
+
+ runtimeSpec.applicationClass("io.quarkus.bootstrap.runner.QuarkusEntryPoint");
+ runtimeSpec.addDependency("org.apache.camel.quarkus", "camel-quarkus-k-runtime");
+
+ if (capabilitiesExclusionList != null && !capabilitiesExclusionList.contains("cron")) {
+ runtimeSpec.putCapability(
+ "cron",
+ CamelCapability.forArtifact(
+ "org.apache.camel.quarkus", "camel-k-cron"));
+
+ catalogSpec.putArtifact(
+ new CamelArtifact.Builder()
+ .groupId("org.apache.camel.quarkus")
+ .artifactId("camel-k-cron")
+ .build());
+ }
+ if (capabilitiesExclusionList != null && !capabilitiesExclusionList.contains("health")) {
+ runtimeSpec.putCapability(
+ "health",
+ CamelCapability.forArtifact(
+ "org.apache.camel.quarkus", "camel-quarkus-microprofile-health"));
+ }
+ if (capabilitiesExclusionList != null && !capabilitiesExclusionList.contains("platform-http")) {
+ runtimeSpec.putCapability(
+ "platform-http",
+ CamelCapability.forArtifact(
+ "org.apache.camel.quarkus", "camel-quarkus-platform-http"));
+ }
+ if (capabilitiesExclusionList != null && !capabilitiesExclusionList.contains("rest")) {
+ runtimeSpec.putCapability(
+ "rest",
+ new CamelCapability.Builder()
+ .addDependency("org.apache.camel.quarkus", "camel-quarkus-rest")
+ .addDependency("org.apache.camel.quarkus", "camel-quarkus-platform-http")
+ .build());
+ }
+ if (capabilitiesExclusionList != null && !capabilitiesExclusionList.contains("circuit-breaker")) {
+ runtimeSpec.putCapability(
+ "circuit-breaker",
+ CamelCapability.forArtifact(
+ "org.apache.camel.quarkus", "camel-quarkus-microprofile-fault-tolerance"));
+ }
+ if (capabilitiesExclusionList != null && !capabilitiesExclusionList.contains("tracing")) {
+ runtimeSpec.putCapability(
+ "tracing",
+ CamelCapability.forArtifact(
+ "org.apache.camel.quarkus", "camel-quarkus-opentracing"));
+ }
+ if (capabilitiesExclusionList != null && !capabilitiesExclusionList.contains("telemetry")) {
+ runtimeSpec.putCapability(
+ "telemetry",
+ CamelCapability.forArtifact(
+ "org.apache.camel.quarkus", "camel-quarkus-opentelemetry"));
+ }
+ if (capabilitiesExclusionList != null && !capabilitiesExclusionList.contains("master")) {
+ runtimeSpec.putCapability(
+ "master",
+ CamelCapability.forArtifact(
+ "org.apache.camel.quarkus", "camel-k-master"));
+
+ catalogSpec.putArtifact(
+ new CamelArtifact.Builder()
+ .groupId("org.apache.camel.quarkus")
+ .artifactId("camel-k-master")
+ .build());
+ }
+ if (capabilitiesExclusionList != null && !capabilitiesExclusionList.contains("resume-kafka")) {
+ runtimeSpec.putCapability(
+ "resume-kafka",
+ CamelCapability.forArtifact(
+ "org.apache.camel.quarkus", "camel-k-resume-kafka"));
+
+ catalogSpec.putArtifact(
+ new CamelArtifact.Builder()
+ .groupId("org.apache.camel.quarkus")
+ .artifactId("camel-k-resume-kafka")
+ .build());
+ }
+
+ catalogSpec.runtime(runtimeSpec.build());
+
+ process(catalog, catalogSpec);
+
+ ObjectMeta.Builder metadata = new ObjectMeta.Builder()
+ .name(catalogName)
+ .putLabels("app", "camel-k")
+ .putLabels("camel.apache.org/catalog.version", catalog.getCatalogVersion())
+ .putLabels("camel.apache.org/catalog.loader.version", catalog.getLoadedVersion())
+ .putLabels("camel.apache.org/runtime.version", runtimeVersion);
+
+ CamelCatalog cr = new CamelCatalog.Builder()
+ .metadata(metadata.build())
+ .spec(catalogSpec.build())
+ .build();
+
+ //
+ // apiVersion: camel.apache.org/v1
+ // kind: CamelCatalog
+ // metadata:
+ // name: catalog-x.y.z-main
+ // labels:
+ // app: "camel-k"
+ // camel.apache.org/catalog.version: x.y.x
+ // camel.apache.org/catalog.loader.version: x.y.z
+ // camel.apache.org/runtime.version: x.y.x
+ // camel.apache.org/runtime.provider: main
+ // spec:
+ // version:
+ // runtimeVersion:
+ // status:
+ // artifacts:
+ //
+ try (Writer writer = Files.newBufferedWriter(output, StandardCharsets.UTF_8)) {
+
+ YAMLFactory factory = new YAMLFactory()
+ .configure(YAMLGenerator.Feature.MINIMIZE_QUOTES, true)
+ .configure(YAMLGenerator.Feature.ALWAYS_QUOTE_NUMBERS_AS_STRINGS, true)
+ .configure(YAMLGenerator.Feature.USE_NATIVE_TYPE_ID, false)
+ .configure(YAMLGenerator.Feature.WRITE_DOC_START_MARKER, false);
+
+ // write license header
+ writer.write(
+ GenerateSupport.getResourceAsString("/catalog-license.txt"));
+
+ getLog().info("Writing catalog file to: " + output);
+
+ // write catalog data
+ ObjectMapper mapper = new ObjectMapper(factory);
+ mapper.registerModule(new Jdk8Module());
+ mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+ mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
+ mapper.writeValue(writer, cr);
+ }
+ } catch (IOException e) {
+ throw new MojoExecutionException("Exception while generating catalog", e);
+ }
+ }
+
+ // ********************
+ //
+ // ********************
+
+ public void process(
+ org.apache.camel.catalog.CamelCatalog catalog,
+ CamelCatalogSpec.Builder specBuilder) {
+
+ Map<String, CamelArtifact> artifacts = new TreeMap<>();
+
+ processComponents(catalog, artifacts);
+ processLanguages(catalog, artifacts);
+ processDataFormats(catalog, artifacts);
+ processOthers(catalog, artifacts);
+ processLoaders(specBuilder);
+
+ specBuilder.putAllArtifacts(artifacts);
+ }
+
+ private void processLoaders(CamelCatalogSpec.Builder specBuilder) {
+ if (dslsExclusionList != null) {
+ getLog().info("dsls.exclusion.list: " + dslsExclusionList);
+ }
+
+ if (dslsExclusionList != null && !dslsExclusionList.contains("yaml")) {
+ specBuilder.putLoader(
+ "yaml",
+ CamelLoader.fromArtifact("org.apache.camel.quarkus", "camel-quarkus-yaml-dsl")
+ .addLanguage("yaml")
+ .putMetadata("native", "true")
+ .build());
+ }
+ if (dslsExclusionList != null && !dslsExclusionList.contains("groovy")) {
+ specBuilder.putLoader(
+ "groovy",
+ CamelLoader.fromArtifact("org.apache.camel.quarkus", "camel-quarkus-groovy-dsl")
+ .addLanguage("groovy")
+ .putMetadata("native", "true")
+ .putMetadata("sources-required-at-build-time", "true")
+ .build());
+ }
+ if (dslsExclusionList != null && !dslsExclusionList.contains("kts")) {
+ specBuilder.putLoader(
+ "kts",
+ CamelLoader.fromArtifact("org.apache.camel.quarkus", "camel-quarkus-kotlin-dsl")
+ .addLanguage("kts")
+ .putMetadata("native", "true")
+ .putMetadata("sources-required-at-build-time", "true")
+ .build());
+ }
+ if (dslsExclusionList != null && !dslsExclusionList.contains("js")) {
+ specBuilder.putLoader(
+ "js",
+ CamelLoader.fromArtifact("org.apache.camel.quarkus", "camel-quarkus-js-dsl")
+ .addLanguage("js")
+ // Guest languages are not yet supported on Mandrel in native mode.
+ .putMetadata("native", "false")
+ .build());
+ }
+ if (dslsExclusionList != null && !dslsExclusionList.contains("xml")) {
+ specBuilder.putLoader(
+ "xml",
+ CamelLoader.fromArtifact("org.apache.camel.quarkus", "camel-quarkus-xml-io-dsl")
+ .addLanguage("xml")
+ .putMetadata("native", "true")
+ .build());
+ }
+ if (dslsExclusionList != null && !dslsExclusionList.contains("java")) {
+ specBuilder.putLoader(
+ "java",
+ CamelLoader.fromArtifact("org.apache.camel.quarkus", "camel-quarkus-java-joor-dsl")
+ .addLanguages("java")
+ .putMetadata("native", "true")
+ .putMetadata("sources-required-at-build-time", "true")
+ .build());
+ }
+ if (dslsExclusionList != null && !dslsExclusionList.contains("jsh")) {
+ specBuilder.putLoader(
+ "jsh",
+ CamelLoader.fromArtifact("org.apache.camel.quarkus", "camel-quarkus-jsh-dsl")
+ .addLanguages("jsh")
+ // Native mode is not yet supported due to https://github.com/apache/camel-quarkus/issues/4458.
+ .putMetadata("native", "false")
+ .putMetadata("sources-required-at-build-time", "true")
+ .build());
+ }
+ }
+
+ private void processComponents(org.apache.camel.catalog.CamelCatalog catalog, Map<String, CamelArtifact> artifacts) {
+ final Set<String> elements = new TreeSet<>(catalog.findComponentNames());
+
+ if (componentsExclusionList != null) {
+ getLog().info("components.exclusion.list: " + componentsExclusionList);
+ elements.removeAll(componentsExclusionList);
+ }
+
+ for (String name : elements) {
+ String json = catalog.componentJSonSchema(name);
+ CatalogComponentDefinition definition = CatalogSupport.unmarshallComponent(json);
+
+ artifacts.compute(definition.getArtifactId(), (key, artifact) -> {
+ CamelArtifact.Builder builder = artifactBuilder(artifact, definition);
+ builder.addJavaType(definition.getJavaType());
+
+ definition.getSchemes().map(StringUtils::trimToNull).filter(Objects::nonNull).forEach(scheme -> {
+ builder.addScheme(
+ new CamelScheme.Builder()
+ .id(scheme)
+ .http(KNOWN_HTTP_URIS.contains(scheme))
+ .passive(KNOWN_PASSIVE_URIS.contains(scheme))
+ .build());
+ });
+
+ return builder.build();
+ });
+ }
+ }
+
+ private void processLanguages(org.apache.camel.catalog.CamelCatalog catalog, Map<String, CamelArtifact> artifacts) {
+ final Set<String> elements = new TreeSet<>(catalog.findLanguageNames());
+
+ if (languagesExclusionList != null) {
+ getLog().info("languages.exclusion.list: " + languagesExclusionList);
+ elements.removeAll(languagesExclusionList);
+ }
+
+ for (String name : elements) {
+ String json = catalog.languageJSonSchema(name);
+ CatalogLanguageDefinition definition = CatalogSupport.unmarshallLanguage(json);
+
+ artifacts.compute(definition.getArtifactId(), (key, artifact) -> {
+ CamelArtifact.Builder builder = artifactBuilder(artifact, definition);
+ builder.addLanguage(definition.getName());
+ builder.addJavaType(definition.getJavaType());
+
+ return builder.build();
+ });
+ }
+ }
+
+ private void processDataFormats(org.apache.camel.catalog.CamelCatalog catalog, Map<String, CamelArtifact> artifacts) {
+ final Set<String> elements = new TreeSet<>(catalog.findDataFormatNames());
+
+ if (dataformatsExclusionList != null) {
+ getLog().info("dataformats.exclusion.list: " + dataformatsExclusionList);
+ elements.removeAll(dataformatsExclusionList);
+ }
+
+ for (String name : elements) {
+ String json = catalog.dataFormatJSonSchema(name);
+ CatalogDataFormatDefinition definition = CatalogSupport.unmarshallDataFormat(json);
+
+ artifacts.compute(definition.getArtifactId(), (key, artifact) -> {
+ CamelArtifact.Builder builder = artifactBuilder(artifact, definition);
+ builder.addDataformat(definition.getName());
+ builder.addJavaType(definition.getJavaType());
+
+ return builder.build();
+ });
+ }
+ }
+
+ private void processOthers(org.apache.camel.catalog.CamelCatalog catalog, Map<String, CamelArtifact> artifacts) {
+ final Set<String> elements = new TreeSet<>(catalog.findOtherNames());
+
+ if (othersExclusionList != null) {
+ getLog().info("others.exclusion.list: " + othersExclusionList);
+ elements.removeAll(othersExclusionList);
+ }
+
+ for (String name : elements) {
+ String json = catalog.otherJSonSchema(name);
+ CatalogOtherDefinition definition = CatalogSupport.unmarshallOther(json);
+
+ artifacts.compute(definition.getArtifactId(), (key, artifact) -> artifactBuilder(artifact, definition).build());
+ }
+ }
+
+ private CamelArtifact.Builder artifactBuilder(CamelArtifact artifact, CatalogDefinition definition) {
+ CamelArtifact.Builder builder = new CamelArtifact.Builder();
+
+ if (artifact != null) {
+ builder.from(artifact);
+ } else {
+ Objects.requireNonNull(definition.getGroupId());
+ Objects.requireNonNull(definition.getArtifactId());
+
+ builder.groupId(definition.getGroupId());
+ builder.artifactId(definition.getArtifactId());
+ }
+
+ return builder;
+ }
+}
diff --git a/tooling/camel-k-maven-plugin/src/main/java/org/apache/camel/quarkus/k/tooling/maven/GenerateDependencyListMojo.java b/tooling/camel-k-maven-plugin/src/main/java/org/apache/camel/quarkus/k/tooling/maven/GenerateDependencyListMojo.java
new file mode 100644
index 0000000000..306e006255
--- /dev/null
+++ b/tooling/camel-k-maven-plugin/src/main/java/org/apache/camel/quarkus/k/tooling/maven/GenerateDependencyListMojo.java
@@ -0,0 +1,132 @@
+/*
+ * 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.quarkus.k.tooling.maven;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Writer;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.NoSuchAlgorithmException;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.DefaultArtifact;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+import org.apache.maven.project.MavenProject;
+import org.yaml.snakeyaml.DumperOptions;
+import org.yaml.snakeyaml.Yaml;
+
+import static org.apache.camel.quarkus.k.tooling.maven.support.MavenSupport.sha1Hex;
+
+@Mojo(name = "generate-dependency-list", defaultPhase = LifecyclePhase.PREPARE_PACKAGE, threadSafe = true, requiresProject = false, requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, requiresDependencyCollection = ResolutionScope.COMPILE_PLUS_RUNTIME)
+public class GenerateDependencyListMojo extends AbstractMojo {
+ private static final String[] CHECKSUM_TYPES = { "md5", "sha1" };
+
+ @Parameter(readonly = true, defaultValue = "${project}")
+ private MavenProject project;
+
+ @Parameter(property = "dependencies.file", defaultValue = "${project.build.directory}/dependencies.yaml")
+ private String outputFile;
+
+ @Parameter(defaultValue = "true")
+ private boolean includeLocation;
+
+ @Override
+ public void execute() throws MojoExecutionException, MojoFailureException {
+ final Path output = Paths.get(this.outputFile);
+
+ try {
+ if (Files.notExists(output.getParent())) {
+ Files.createDirectories(output.getParent());
+ }
+ } catch (IOException e) {
+ throw new MojoExecutionException("Exception while generating dependencies list", e);
+ }
+
+ try (Writer writer = Files.newBufferedWriter(output, StandardCharsets.UTF_8)) {
+ List<Map<String, String>> deps = project.getArtifacts().stream()
+ .filter(this::isCompileOrRuntime)
+ .map(this::artifactToMap)
+ .collect(Collectors.toList());
+
+ DumperOptions options = new DumperOptions();
+ options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
+
+ Yaml yaml = new Yaml(options);
+ yaml.dump(Collections.singletonMap("dependencies", deps), writer);
+ } catch (IOException e) {
+ throw new MojoExecutionException("Exception while generating dependencies list", e);
+ }
+ }
+
+ private boolean isCompileOrRuntime(Artifact artifact) {
+ return Objects.equals(artifact.getScope(), DefaultArtifact.SCOPE_COMPILE)
+ || Objects.equals(artifact.getScope(), DefaultArtifact.SCOPE_RUNTIME);
+ }
+
+ private Map<String, String> artifactToMap(Artifact artifact) {
+ Map<String, String> dep = new LinkedHashMap<>();
+ dep.put("id", artifact.getId());
+
+ if (artifact.getFile() == null) {
+ return dep;
+ }
+
+ if (includeLocation) {
+ dep.put("location", artifact.getFile().getAbsolutePath());
+ }
+
+ try {
+ String location = artifact.getFile().getAbsolutePath();
+ String checksum = null;
+
+ for (String checksumType : CHECKSUM_TYPES) {
+ Path checksumFile = Paths.get(location + "." + checksumType);
+ if (Files.exists(checksumFile)) {
+ checksum = checksumType + ":" + Files.readString(checksumFile, StandardCharsets.UTF_8);
+ break;
+ }
+ }
+
+ if (checksum == null) {
+ try (InputStream is = Files.newInputStream(artifact.getFile().toPath())) {
+ checksum = "sha1:" + sha1Hex(is);
+ }
+ }
+
+ dep.put("checksum", checksum);
+ } catch (IOException | NoSuchAlgorithmException e) {
+ throw new RuntimeException(e);
+ }
+
+ return dep;
+ }
+}
diff --git a/tooling/camel-k-maven-plugin/src/main/java/org/apache/camel/quarkus/k/tooling/maven/GenerateRestXML.java b/tooling/camel-k-maven-plugin/src/main/java/org/apache/camel/quarkus/k/tooling/maven/GenerateRestXML.java
new file mode 100644
index 0000000000..c451167248
--- /dev/null
+++ b/tooling/camel-k-maven-plugin/src/main/java/org/apache/camel/quarkus/k/tooling/maven/GenerateRestXML.java
@@ -0,0 +1,102 @@
+/*
+ * 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.quarkus.k.tooling.maven;
+
+import java.io.FileInputStream;
+import java.io.PrintWriter;
+import java.io.Writer;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
+import io.apicurio.datamodels.Library;
+import io.apicurio.datamodels.models.openapi.OpenApiDocument;
+import io.apicurio.datamodels.models.util.JsonUtil;
+import org.apache.camel.CamelContext;
+import org.apache.camel.generator.openapi.RestDslXmlGenerator;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+
+@Mojo(name = "generate-rest-xml", inheritByDefault = false, defaultPhase = LifecyclePhase.GENERATE_SOURCES, requiresProject = false, requiresDependencyResolution = ResolutionScope.COMPILE, threadSafe = true)
+class GenerateRestXML extends AbstractMojo {
+ @Parameter(property = "openapi.spec")
+ private String inputFile;
+ @Parameter(property = "dsl.out")
+ private String outputFile;
+
+ @Override
+ public void execute() throws MojoExecutionException {
+ if (inputFile == null) {
+ throw new MojoExecutionException("Missing input file: " + inputFile);
+ }
+
+ Path input = Paths.get(this.inputFile);
+ if (!Files.exists(input)) {
+ throw new MojoExecutionException("Unable to read the input file: " + inputFile);
+ }
+
+ try {
+ JsonFactory factory = null;
+ if (inputFile.endsWith(".yaml") || inputFile.endsWith(".yml")) {
+ factory = new YAMLFactory();
+ }
+
+ ObjectMapper mapper = new ObjectMapper(factory);
+ mapper.findAndRegisterModules();
+
+ FileInputStream fis = new FileInputStream(inputFile);
+
+ JsonNode node = mapper.readTree(fis);
+ OpenApiDocument document = (OpenApiDocument) Library.readDocument(JsonUtil.toObject(node));
+
+ final Writer writer;
+
+ if (outputFile != null) {
+ Path output = Paths.get(this.outputFile);
+
+ if (output.getParent() != null && Files.notExists(output.getParent())) {
+ Files.createDirectories(output.getParent());
+ }
+ if (Files.exists(output)) {
+ Files.delete(output);
+ }
+
+ writer = Files.newBufferedWriter(output);
+ } else {
+ writer = new PrintWriter(System.out);
+ }
+
+ final CamelContext context = new DefaultCamelContext();
+ final String dsl = RestDslXmlGenerator.toXml(document).generate(context);
+
+ try (writer) {
+ writer.write(dsl);
+ }
+ } catch (Exception e) {
+ throw new MojoExecutionException("Exception while generating rest xml", e);
+ }
+ }
+}
diff --git a/tooling/camel-k-maven-plugin/src/main/java/org/apache/camel/quarkus/k/tooling/maven/GenerateSupport.java b/tooling/camel-k-maven-plugin/src/main/java/org/apache/camel/quarkus/k/tooling/maven/GenerateSupport.java
new file mode 100644
index 0000000000..ff36c331a6
--- /dev/null
+++ b/tooling/camel-k-maven-plugin/src/main/java/org/apache/camel/quarkus/k/tooling/maven/GenerateSupport.java
@@ -0,0 +1,38 @@
+/*
+ * 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.quarkus.k.tooling.maven;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+
+import org.apache.commons.io.IOUtils;
+
+public final class GenerateSupport {
+ private GenerateSupport() {
+ }
+
+ public static String getResourceAsString(String resource) throws IOException {
+ try (InputStream is = GenerateSupport.class.getResourceAsStream(resource)) {
+ if (is == null) {
+ throw new IllegalStateException("Unable to find catalog-license.txt");
+ }
+
+ return IOUtils.toString(is, StandardCharsets.UTF_8);
+ }
+ }
+}
diff --git a/tooling/camel-k-maven-plugin/src/main/java/org/apache/camel/quarkus/k/tooling/maven/support/MavenSupport.java b/tooling/camel-k-maven-plugin/src/main/java/org/apache/camel/quarkus/k/tooling/maven/support/MavenSupport.java
new file mode 100644
index 0000000000..4502fe94a5
--- /dev/null
+++ b/tooling/camel-k-maven-plugin/src/main/java/org/apache/camel/quarkus/k/tooling/maven/support/MavenSupport.java
@@ -0,0 +1,120 @@
+/*
+ * 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.quarkus.k.tooling.maven.support;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Properties;
+import java.util.function.Consumer;
+
+public final class MavenSupport {
+ private MavenSupport() {
+ }
+
+ public static String getApplicationProperty(Class<?> clazz, String property) {
+ try (InputStream is = clazz.getResourceAsStream("/app.properties")) {
+ Properties p = new Properties();
+ p.load(is);
+ return p.getProperty(property);
+ } catch (Exception ignored) {
+ }
+ return "";
+ }
+
+ public static String getVersion(Class<?> clazz, String path) {
+ String version = null;
+
+ // try to load from maven properties first
+ try (InputStream is = clazz.getResourceAsStream(path)) {
+ if (is != null) {
+ Properties p = new Properties();
+ p.load(is);
+ version = p.getProperty("version", "");
+ }
+ } catch (Exception ignored) {
+ }
+
+ // fallback to using Java API
+ if (version == null) {
+ Package aPackage = clazz.getPackage();
+ if (aPackage != null) {
+ version = getVersion(aPackage);
+ }
+ }
+
+ if (version == null) {
+ // we could not compute the version so use a blank
+ throw new IllegalStateException("Unable to determine runtime version");
+ }
+
+ return version;
+ }
+
+ public static String getVersion(Package pkg) {
+ String version = pkg.getImplementationVersion();
+ if (version == null) {
+ version = pkg.getSpecificationVersion();
+ }
+
+ return version;
+ }
+
+ public static void getVersion(Class<?> clazz, String path, Consumer<String> consumer) {
+ consumer.accept(
+ MavenSupport.getVersion(clazz, path));
+ }
+
+ public static void getVersion(Class<?> clazz, String groupId, String artifactId, Consumer<String> consumer) {
+ getVersion(
+ clazz,
+ String.format("/META-INF/maven/%s/%s/pom.properties", groupId, artifactId),
+ consumer);
+ }
+
+ public static String getVersion(Class<?> clazz, String groupId, String artifactId) {
+ return MavenSupport.getVersion(
+ clazz,
+ String.format("/META-INF/maven/%s/%s/pom.properties", groupId, artifactId));
+ }
+
+ public static String bytesToHex(byte[] hash) {
+ StringBuilder hexString = new StringBuilder();
+ for (byte b : hash) {
+ String hex = Integer.toHexString(0xff & b);
+ if (hex.length() == 1) {
+ hexString.append('0');
+ }
+
+ hexString.append(hex);
+ }
+
+ return hexString.toString();
+ }
+
+ public static String sha1Hex(InputStream is) throws NoSuchAlgorithmException, IOException {
+ MessageDigest digest = MessageDigest.getInstance("SHA-1");
+
+ byte[] buffer = new byte[1024];
+ for (int read = is.read(buffer, 0, 1024); read > -1; read = is.read(buffer, 0, 1024)) {
+ digest.update(buffer, 0, read);
+ }
+
+ return bytesToHex(digest.digest());
+ }
+}
diff --git a/tooling/camel-k-maven-plugin/src/main/resources/app.properties b/tooling/camel-k-maven-plugin/src/main/resources/app.properties
new file mode 100644
index 0000000000..9c5f2cb26f
--- /dev/null
+++ b/tooling/camel-k-maven-plugin/src/main/resources/app.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.native-builder-image=${quarkus-native-builder-image}
diff --git a/tooling/camel-k-maven-plugin/src/main/resources/catalog-license.txt b/tooling/camel-k-maven-plugin/src/main/resources/catalog-license.txt
new file mode 100644
index 0000000000..658e8dc7ec
--- /dev/null
+++ b/tooling/camel-k-maven-plugin/src/main/resources/catalog-license.txt
@@ -0,0 +1,17 @@
+# ---------------------------------------------------------------------------
+# 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.
+# ---------------------------------------------------------------------------
+
diff --git a/tooling/pom.xml b/tooling/pom.xml
index 748afb2770..a91c08a80c 100644
--- a/tooling/pom.xml
+++ b/tooling/pom.xml
@@ -34,6 +34,8 @@
<modules>
<module>maven-plugin</module>
+ <module>camel-k-catalog-model</module>
+ <module>camel-k-maven-plugin</module>
<module>perf-regression</module>
<module>test-list</module>
</modules>
diff --git a/tooling/scripts/test-categories.yaml b/tooling/scripts/test-categories.yaml
index 4f255251f6..b7d99a8ca9 100644
--- a/tooling/scripts/test-categories.yaml
+++ b/tooling/scripts/test-categories.yaml
@@ -203,6 +203,7 @@ group-12:
- vertx-websocket
group-13:
- box
+ - camel-k-runtime
- fhir
- github
- google