You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by lb...@apache.org on 2020/09/14 11:13:08 UTC

[camel-k-runtime] 01/11: kamelets: create a camel-kamelet component #375

This is an automated email from the ASF dual-hosted git repository.

lburgazzoli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-k-runtime.git

commit 4684d104ffc49d6d9dea96376b3cf0746a6a1ee8
Author: lburgazzoli <lb...@gmail.com>
AuthorDate: Sun Jul 19 15:16:36 2020 +0200

    kamelets: create a camel-kamelet component #375
---
 .../apache/camel/k/main/ApplicationRuntime.java    |  31 ++--
 camel-k-runtime-bom/pom.xml                        |   5 +
 camel-kamelet/pom.xml                              | 137 +++++++++++++++++
 .../kamelet/KameletComponentConfigurer.java        |  55 +++++++
 .../kamelet/KameletEndpointConfigurer.java         |  68 +++++++++
 .../services/org/apache/camel/component/kamelet    |   2 +
 .../org/apache/camel/configurer/kamelet-component  |   2 +
 .../org/apache/camel/configurer/kamelet-endpoint   |   2 +
 .../apache/camel/component/kamelet/kamelet.json    |  38 +++++
 .../apache/camel/component/kamelet/Kamelet.java    |  30 ++++
 .../camel/component/kamelet/KameletComponent.java  | 107 +++++++++++++
 .../camel/component/kamelet/KameletEndpoint.java   | 169 +++++++++++++++++++++
 .../camel/component/kamelet/KameletTest.java       |  74 +++++++++
 camel-kamelet/src/test/resources/log4j2-test.xml   |  37 +++++
 pom.xml                                            |  34 ++++-
 15 files changed, 774 insertions(+), 17 deletions(-)

diff --git a/camel-k-main/camel-k-runtime-main/src/main/java/org/apache/camel/k/main/ApplicationRuntime.java b/camel-k-main/camel-k-runtime-main/src/main/java/org/apache/camel/k/main/ApplicationRuntime.java
index 02551d8..93855b2 100644
--- a/camel-k-main/camel-k-runtime-main/src/main/java/org/apache/camel/k/main/ApplicationRuntime.java
+++ b/camel-k-main/camel-k-runtime-main/src/main/java/org/apache/camel/k/main/ApplicationRuntime.java
@@ -34,6 +34,7 @@ import org.apache.camel.k.support.PropertiesSupport;
 import org.apache.camel.main.BaseMainSupport;
 import org.apache.camel.main.MainSupport;
 import org.apache.camel.main.RoutesCollector;
+import org.apache.camel.model.RouteTemplatesDefinition;
 import org.apache.camel.model.RoutesDefinition;
 import org.apache.camel.model.rest.RestsDefinition;
 import org.apache.camel.spi.HasId;
@@ -203,14 +204,13 @@ public final class ApplicationRuntime implements Runtime {
         @Override
         protected void doStart() throws Exception {
             super.doStart();
-            if (getCamelContext() != null) {
-                try {
-                    // if we were veto started then mark as completed
-                    getCamelContext().start();
-                } finally {
-                    if (getCamelContext().isVetoStarted()) {
-                        completed();
-                    }
+
+            try {
+                // if we were veto started then mark as completed
+                getCamelContext().start();
+            } finally {
+                if (getCamelContext().isVetoStarted()) {
+                    completed();
                 }
             }
         }
@@ -218,18 +218,12 @@ public final class ApplicationRuntime implements Runtime {
         @Override
         protected void doStop() throws Exception {
             super.doStop();
-            if (getCamelContext() != null) {
-                getCamelContext().stop();
-            }
+            getCamelContext().stop();
         }
 
         @Override
         protected ProducerTemplate findOrCreateCamelTemplate() {
-            if (getCamelContext() != null) {
-                return getCamelContext().createProducerTemplate();
-            } else {
-                return null;
-            }
+            return getCamelContext().createProducerTemplate();
         }
     }
 
@@ -245,6 +239,11 @@ public final class ApplicationRuntime implements Runtime {
         }
 
         @Override
+        public List<RouteTemplatesDefinition> collectXmlRouteTemplatesFromDirectory(CamelContext camelContext, String directory) throws Exception {
+            return Collections.emptyList();
+        }
+
+        @Override
         public List<RestsDefinition> collectXmlRestsFromDirectory(CamelContext camelContext, String directory) throws Exception {
             return Collections.emptyList();
         }
diff --git a/camel-k-runtime-bom/pom.xml b/camel-k-runtime-bom/pom.xml
index bc2220a..b27eb44 100644
--- a/camel-k-runtime-bom/pom.xml
+++ b/camel-k-runtime-bom/pom.xml
@@ -136,6 +136,11 @@
             </dependency>
             <dependency>
                 <groupId>org.apache.camel.k</groupId>
+                <artifactId>camel-kamelet</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.camel.k</groupId>
                 <artifactId>camel-k-maven-plugin</artifactId>
                 <version>${project.version}</version>
             </dependency>
diff --git a/camel-kamelet/pom.xml b/camel-kamelet/pom.xml
new file mode 100644
index 0000000..33e09c3
--- /dev/null
+++ b/camel-kamelet/pom.xml
@@ -0,0 +1,137 @@
+<?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.k</groupId>
+        <artifactId>camel-k-runtime-parent</artifactId>
+        <version>1.5.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>camel-kamelet</artifactId>
+
+    <dependencies>
+
+        <!-- ****************************** -->
+        <!--                                -->
+        <!-- RUNTIME                        -->
+        <!--                                -->
+        <!-- ****************************** -->
+
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>${slf4j.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-core-engine</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-direct</artifactId>
+        </dependency>
+
+        <!-- ****************************** -->
+        <!--                                -->
+        <!-- TESTS                          -->
+        <!--                                -->
+        <!-- ****************************** -->
+
+        <dependency>
+            <groupId>org.apache.camel.k</groupId>
+            <artifactId>camel-k-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-core-languages</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-timer</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-log</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-component-maven-plugin</artifactId>
+                <version>${camel.version}</version>
+                <executions>
+                    <execution>
+                        <id>generate</id>
+                        <goals>
+                            <goal>generate</goal>
+                        </goals>
+                        <phase>process-classes</phase>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>build-helper-maven-plugin</artifactId>
+                <version>${build-helper-maven-plugin.version}</version>
+                <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>
+        </plugins>
+    </build>
+
+</project>
diff --git a/camel-kamelet/src/generated/java/org/apache/camel/component/kamelet/KameletComponentConfigurer.java b/camel-kamelet/src/generated/java/org/apache/camel/component/kamelet/KameletComponentConfigurer.java
new file mode 100644
index 0000000..a0a384d
--- /dev/null
+++ b/camel-kamelet/src/generated/java/org/apache/camel/component/kamelet/KameletComponentConfigurer.java
@@ -0,0 +1,55 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.kamelet;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.support.component.PropertyConfigurerSupport;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class KameletComponentConfigurer extends PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        KameletComponent target = (KameletComponent) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "basicpropertybinding":
+        case "basicPropertyBinding": target.setBasicPropertyBinding(property(camelContext, boolean.class, value)); return true;
+        case "bridgeerrorhandler":
+        case "bridgeErrorHandler": target.setBridgeErrorHandler(property(camelContext, boolean.class, value)); return true;
+        case "lazystartproducer":
+        case "lazyStartProducer": target.setLazyStartProducer(property(camelContext, boolean.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Map<String, Object> getAllOptions(Object target) {
+        Map<String, Object> answer = new CaseInsensitiveMap();
+        answer.put("basicPropertyBinding", boolean.class);
+        answer.put("bridgeErrorHandler", boolean.class);
+        answer.put("lazyStartProducer", boolean.class);
+        return answer;
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        KameletComponent target = (KameletComponent) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "basicpropertybinding":
+        case "basicPropertyBinding": return target.isBasicPropertyBinding();
+        case "bridgeerrorhandler":
+        case "bridgeErrorHandler": return target.isBridgeErrorHandler();
+        case "lazystartproducer":
+        case "lazyStartProducer": return target.isLazyStartProducer();
+        default: return null;
+        }
+    }
+}
+
diff --git a/camel-kamelet/src/generated/java/org/apache/camel/component/kamelet/KameletEndpointConfigurer.java b/camel-kamelet/src/generated/java/org/apache/camel/component/kamelet/KameletEndpointConfigurer.java
new file mode 100644
index 0000000..bb99f63
--- /dev/null
+++ b/camel-kamelet/src/generated/java/org/apache/camel/component/kamelet/KameletEndpointConfigurer.java
@@ -0,0 +1,68 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.kamelet;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.support.component.PropertyConfigurerSupport;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class KameletEndpointConfigurer extends PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        KameletEndpoint target = (KameletEndpoint) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "basicpropertybinding":
+        case "basicPropertyBinding": target.setBasicPropertyBinding(property(camelContext, boolean.class, value)); return true;
+        case "bridgeerrorhandler":
+        case "bridgeErrorHandler": target.setBridgeErrorHandler(property(camelContext, boolean.class, value)); return true;
+        case "exceptionhandler":
+        case "exceptionHandler": target.setExceptionHandler(property(camelContext, org.apache.camel.spi.ExceptionHandler.class, value)); return true;
+        case "exchangepattern":
+        case "exchangePattern": target.setExchangePattern(property(camelContext, org.apache.camel.ExchangePattern.class, value)); return true;
+        case "lazystartproducer":
+        case "lazyStartProducer": target.setLazyStartProducer(property(camelContext, boolean.class, value)); return true;
+        case "synchronous": target.setSynchronous(property(camelContext, boolean.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Map<String, Object> getAllOptions(Object target) {
+        Map<String, Object> answer = new CaseInsensitiveMap();
+        answer.put("basicPropertyBinding", boolean.class);
+        answer.put("bridgeErrorHandler", boolean.class);
+        answer.put("exceptionHandler", org.apache.camel.spi.ExceptionHandler.class);
+        answer.put("exchangePattern", org.apache.camel.ExchangePattern.class);
+        answer.put("lazyStartProducer", boolean.class);
+        answer.put("synchronous", boolean.class);
+        return answer;
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        KameletEndpoint target = (KameletEndpoint) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "basicpropertybinding":
+        case "basicPropertyBinding": return target.isBasicPropertyBinding();
+        case "bridgeerrorhandler":
+        case "bridgeErrorHandler": return target.isBridgeErrorHandler();
+        case "exceptionhandler":
+        case "exceptionHandler": return target.getExceptionHandler();
+        case "exchangepattern":
+        case "exchangePattern": return target.getExchangePattern();
+        case "lazystartproducer":
+        case "lazyStartProducer": return target.isLazyStartProducer();
+        case "synchronous": return target.isSynchronous();
+        default: return null;
+        }
+    }
+}
+
diff --git a/camel-kamelet/src/generated/resources/META-INF/services/org/apache/camel/component/kamelet b/camel-kamelet/src/generated/resources/META-INF/services/org/apache/camel/component/kamelet
new file mode 100644
index 0000000..be8044e
--- /dev/null
+++ b/camel-kamelet/src/generated/resources/META-INF/services/org/apache/camel/component/kamelet
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.kamelet.KameletComponent
diff --git a/camel-kamelet/src/generated/resources/META-INF/services/org/apache/camel/configurer/kamelet-component b/camel-kamelet/src/generated/resources/META-INF/services/org/apache/camel/configurer/kamelet-component
new file mode 100644
index 0000000..88d3725
--- /dev/null
+++ b/camel-kamelet/src/generated/resources/META-INF/services/org/apache/camel/configurer/kamelet-component
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.kamelet.KameletComponentConfigurer
diff --git a/camel-kamelet/src/generated/resources/META-INF/services/org/apache/camel/configurer/kamelet-endpoint b/camel-kamelet/src/generated/resources/META-INF/services/org/apache/camel/configurer/kamelet-endpoint
new file mode 100644
index 0000000..17182a5
--- /dev/null
+++ b/camel-kamelet/src/generated/resources/META-INF/services/org/apache/camel/configurer/kamelet-endpoint
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.kamelet.KameletEndpointConfigurer
diff --git a/camel-kamelet/src/generated/resources/org/apache/camel/component/kamelet/kamelet.json b/camel-kamelet/src/generated/resources/org/apache/camel/component/kamelet/kamelet.json
new file mode 100644
index 0000000..93ef496
--- /dev/null
+++ b/camel-kamelet/src/generated/resources/org/apache/camel/component/kamelet/kamelet.json
@@ -0,0 +1,38 @@
+{
+  "component": {
+    "kind": "component",
+    "name": "kamelet",
+    "title": "Kamelet",
+    "description": "The Apache Software Foundation provides support for the Apache community of open-source software projects.\n    The Apache projects are characterized by a collaborative, consensus based development process, an open and\n    pragmatic software license, and a desire to create high quality software that leads the way in its field.\n    We consider ourselves not simply a group of projects sharing a server, but rather a community of developers\n    and users.",
+    "deprecated": false,
+    "firstVersion": "3.5.0",
+    "label": "camel-k",
+    "javaType": "org.apache.camel.component.kamelet.KameletComponent",
+    "supportLevel": "Preview",
+    "groupId": "org.apache.camel.k",
+    "artifactId": "camel-kamelet",
+    "version": "1.5.0-SNAPSHOT",
+    "scheme": "kamelet",
+    "extendsScheme": "",
+    "syntax": "kamelet:templateId\/routeId",
+    "async": false,
+    "consumerOnly": false,
+    "producerOnly": false,
+    "lenientProperties": false
+  },
+  "componentProperties": {
+    "bridgeErrorHandler": { "kind": "property", "displayName": "Bridge Error Handler", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a message and handled by [...]
+    "lazyStartProducer": { "kind": "property", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the r [...]
+    "basicPropertyBinding": { "kind": "property", "displayName": "Basic Property Binding", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "Whether the component should use basic property binding (Camel 2.x) or the newer property binding with additional capabilities" }
+  },
+  "properties": {
+    "templateId": { "kind": "path", "displayName": "Template Id", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "secret": false, "description": "The Route Template ID" },
+    "routeId": { "kind": "path", "displayName": "Route Id", "group": "common", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "secret": false, "description": "The Route ID. Default value notice: The ID will be auto-generated if not provided" },
+    "bridgeErrorHandler": { "kind": "parameter", "displayName": "Bridge Error Handler", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a message and handled b [...]
+    "exceptionHandler": { "kind": "parameter", "displayName": "Exception Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", "deprecated": false, "secret": false, "description": "To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By default the consumer will deal with [...]
+    "exchangePattern": { "kind": "parameter", "displayName": "Exchange Pattern", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut", "InOptionalOut" ], "deprecated": false, "secret": false, "description": "Sets the exchange pattern when the consumer creates an exchange." },
+    "lazyStartProducer": { "kind": "parameter", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the  [...]
+    "basicPropertyBinding": { "kind": "parameter", "displayName": "Basic Property Binding", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, "defaultValue": false, "description": "Whether the endpoint should use basic property binding (Camel 2.x) or the newer property binding with additional capabilities" },
+    "synchronous": { "kind": "parameter", "displayName": "Synchronous", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "secret": false, "defaultValue": "false", "description": "Sets whether synchronous processing should be strictly used, or Camel is allowed to use asynchronous processing (if supported)." }
+  }
+}
diff --git a/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/Kamelet.java b/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/Kamelet.java
new file mode 100644
index 0000000..043f44e
--- /dev/null
+++ b/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/Kamelet.java
@@ -0,0 +1,30 @@
+/*
+ * 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.component.kamelet;
+
+import java.util.function.Predicate;
+
+public final class Kamelet {
+    public static final String SCHEME = "kamelet";
+
+    private Kamelet() {
+    }
+
+    public static Predicate<String> startsWith(String prefix) {
+        return item -> item.startsWith(prefix);
+    }
+}
diff --git a/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/KameletComponent.java b/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/KameletComponent.java
new file mode 100644
index 0000000..f5c6f6e
--- /dev/null
+++ b/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/KameletComponent.java
@@ -0,0 +1,107 @@
+/*
+ * 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.component.kamelet;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Endpoint;
+import org.apache.camel.spi.annotations.Component;
+import org.apache.camel.support.DefaultComponent;
+import org.apache.camel.util.StringHelper;
+
+@Component(Kamelet.SCHEME)
+public class KameletComponent extends DefaultComponent {
+    public KameletComponent() {
+        this(null);
+    }
+
+    public KameletComponent(CamelContext context) {
+        super(context);
+    }
+
+    @Override
+    protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
+        final String templateId = extractTemplateId(remaining);
+        final String routeId = extractRouteId(remaining);
+
+        //
+        // The properties for the kamelets are determined by global properties
+        // and local endpoint parametes,
+        //
+        // Global parameters are loaded in the following order:
+        //
+        //   camel.kamelet." + templateId
+        //   camel.kamelet." + templateId + "." routeId
+        //
+        Map<String, Object> kameletProperties = extractKameletProperties(templateId, routeId);
+        kameletProperties.putAll(parameters);
+        kameletProperties.putIfAbsent("templateId", templateId);
+        kameletProperties.putIfAbsent("routeId", routeId);
+
+        // Remaining parameter should be related to the route and to avoid the
+        // parameters validation to fail, we need to clear the parameters map.
+        parameters.clear();
+
+        KameletEndpoint endpoint = new KameletEndpoint(uri, this, templateId, routeId, kameletProperties);
+
+        // No parameters are expected here.
+        setProperties(endpoint, parameters);
+
+        return endpoint;
+    }
+
+    private String extractTemplateId(String remaining) {
+        String answer = StringHelper.before(remaining, "/");
+        if (answer == null) {
+            answer = remaining;
+        }
+
+        return answer;
+    }
+
+    private String extractRouteId(String remaining) {
+        String answer = StringHelper.after(remaining, "/");
+        if (answer == null) {
+            answer = extractTemplateId(remaining) + "-" + getCamelContext().getUuidGenerator().generateUuid();
+        }
+
+        return answer;
+    }
+
+    @SuppressWarnings("unchecked")
+    private Map<String, Object> extractKameletProperties(String... elements) {
+        Map<String, Object> properties = new HashMap<>();
+        String prefix = "camel.kamelet.";
+
+        for (String element: elements) {
+            if (element == null) {
+                continue;
+            }
+
+            prefix = prefix + element + ".";
+
+            properties.putAll(
+                (Map)getCamelContext().getPropertiesComponent().loadProperties(Kamelet.startsWith(prefix))
+            );
+
+        }
+
+        return properties;
+    }
+}
diff --git a/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/KameletEndpoint.java b/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/KameletEndpoint.java
new file mode 100644
index 0000000..22cd543
--- /dev/null
+++ b/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/KameletEndpoint.java
@@ -0,0 +1,169 @@
+/*
+ * 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.component.kamelet;
+
+import java.util.Map;
+
+import org.apache.camel.Consumer;
+import org.apache.camel.Endpoint;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.Producer;
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.UriEndpoint;
+import org.apache.camel.spi.UriPath;
+import org.apache.camel.support.DefaultConsumer;
+import org.apache.camel.support.DefaultEndpoint;
+import org.apache.camel.support.DefaultProducer;
+import org.apache.camel.support.service.ServiceHelper;
+
+@UriEndpoint(
+    firstVersion = "3.5.0",
+    scheme = "kamelet",
+    syntax = "kamelet:templateId/routeId",
+    title = "Kamelet",
+    label = "camel-k")
+public class KameletEndpoint extends DefaultEndpoint {
+    @Metadata(required = true)
+    @UriPath(description = "The Route Template ID")
+    private final String templateId;
+
+    @Metadata(required = false)
+    @UriPath(description = "The Route ID", defaultValueNote = "The ID will be auto-generated if not provided")
+    private final String routeId;
+
+    private final Map<String, Object> kameletProperties;
+    private final String kameletUri;
+
+    public KameletEndpoint(
+            String uri,
+            KameletComponent component,
+            String templateId,
+            String routeId,
+            Map<String, Object> kameletProperties) {
+
+        super(uri, component);
+
+        this.templateId = templateId;
+        this.routeId = routeId;
+        this.kameletProperties = kameletProperties;
+        this.kameletUri = "direct:" + routeId;
+    }
+
+    public String getTemplateId() {
+        return templateId;
+    }
+
+    public String getRouteId() {
+        return routeId;
+    }
+
+    @Override
+    public Producer createProducer() throws Exception {
+        return new KameletProducer();
+    }
+
+    @Override
+    public Consumer createConsumer(Processor processor) throws Exception {
+        Consumer answer = new KemeletConsumer(processor);
+        configureConsumer(answer);
+
+        return answer;
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        try {
+            // Add a route to the camel context from the given template
+            // TODO: add validation (requires: https://issues.apache.org/jira/browse/CAMEL-15312)
+            getCamelContext().addRouteFromTemplate(routeId, templateId, kameletProperties);
+        } catch (Exception e) {
+            throw new IllegalArgumentException(e);
+        }
+
+        super.doStart();
+    }
+
+    // *********************************
+    //
+    // Helpers
+    //
+    // *********************************
+
+    private class KemeletConsumer extends DefaultConsumer {
+        private volatile Endpoint endpoint;
+        private volatile Consumer consumer;
+
+        public KemeletConsumer(Processor processor) {
+            super(KameletEndpoint.this, processor);
+        }
+
+        @Override
+        protected void doStart() throws Exception {
+            endpoint = getCamelContext().getEndpoint(kameletUri);
+            consumer = endpoint.createConsumer(getProcessor());
+
+            ServiceHelper.startService(endpoint);
+            ServiceHelper.startService(consumer);
+
+            super.doStart();
+        }
+
+        @Override
+        protected void doStop() throws Exception {
+            ServiceHelper.stopService(endpoint);
+            ServiceHelper.stopService(consumer);
+
+            super.doStop();
+        }
+    }
+
+    private class KameletProducer extends DefaultProducer {
+        private volatile Endpoint endpoint;
+        private volatile Producer producer;
+
+        public KameletProducer() {
+            super(KameletEndpoint.this);
+        }
+
+        @Override
+        public void process(Exchange exchange) throws Exception {
+            if (producer != null) {
+                producer.process(exchange);
+            }
+        }
+
+        @Override
+        protected void doStart() throws Exception {
+            endpoint = getCamelContext().getEndpoint(kameletUri);
+            producer = endpoint.createProducer();
+
+            ServiceHelper.startService(endpoint);
+            ServiceHelper.startService(producer);
+
+            super.doStart();
+        }
+
+        @Override
+        protected void doStop() throws Exception {
+            ServiceHelper.stopService(endpoint);
+            ServiceHelper.stopService(producer);
+
+            super.doStop();
+        }
+    }
+}
\ No newline at end of file
diff --git a/camel-kamelet/src/test/java/org/apache/camel/component/kamelet/KameletTest.java b/camel-kamelet/src/test/java/org/apache/camel/component/kamelet/KameletTest.java
new file mode 100644
index 0000000..8f95084
--- /dev/null
+++ b/camel-kamelet/src/test/java/org/apache/camel/component/kamelet/KameletTest.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.component.kamelet;
+
+import java.util.UUID;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.junit.jupiter.api.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class KameletTest {
+    private static final Logger LOGGER = LoggerFactory.getLogger(KameletTest.class);
+
+    @Test
+    public void test() throws Exception {
+        String body = UUID.randomUUID().toString();
+
+        CamelContext context = new DefaultCamelContext();
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                routeTemplate("setBody")
+                    .templateParameter("bodyValue")
+                    .from("direct:{{routeId}}")
+                    .setBody().constant("{{bodyValue}}");
+            }
+        });
+
+        /*
+        context.addRouteFromTemplate("setBody")
+            .routeId("test")
+            .parameter("routeId", "test")
+            .parameter("bodyValue", body)
+            .build();
+         */
+
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                // routes
+                from("direct:template")
+                    .to("kamelet:setBody/test?bodyValue=bv")
+                    .to("log:1");
+            }
+        });
+
+        context.start();
+
+        assertThat(
+            context.createFluentProducerTemplate().to("direct:template").withBody("test").request(String.class)
+        ).isEqualTo(body);
+
+        context.stop();
+    }
+}
diff --git a/camel-kamelet/src/test/resources/log4j2-test.xml b/camel-kamelet/src/test/resources/log4j2-test.xml
new file mode 100644
index 0000000..486a0f0
--- /dev/null
+++ b/camel-kamelet/src/test/resources/log4j2-test.xml
@@ -0,0 +1,37 @@
+<?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.
+
+-->
+<Configuration status="INFO">
+  <Appenders>
+    <Console name="STDOUT" target="SYSTEM_OUT">
+      <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS}|%-5level|%t|%c{1} - %msg%n"/>
+    </Console>
+    <Null name="NONE"/>
+  </Appenders>
+
+  <Loggers>
+    <Root level="INFO">
+      <!--
+      <AppenderRef ref="STDOUT"/>
+      -->
+      <AppenderRef ref="STDOUT"/>
+    </Root>
+  </Loggers>
+
+</Configuration>
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 3bf812f..d774404 100644
--- a/pom.xml
+++ b/pom.xml
@@ -38,7 +38,33 @@
         <maven.compiler.source>11</maven.compiler.source>
         <maven.compiler.target>11</maven.compiler.target>
 
-        <camel-version>3.4.2</camel-version>
+        <camel.version>3.4.2</camel.version>
+        <camel-quarkus.version>1.0.0</camel-quarkus.version>
+        <junit.version>5.6.2</junit.version>
+        <junit-pioneer.version>0.9.0</junit-pioneer.version>
+        <joor.version>0.9.13</joor.version>
+        <assertj.version>3.17.1</assertj.version>
+        <log4j2.version>2.13.3</log4j2.version>
+        <groovy.version>3.0.5</groovy.version>
+        <kotlin.version>1.4.0</kotlin.version>
+        <snakeyaml.version>1.26</snakeyaml.version>
+        <spock.version>2.0-M3-groovy-3.0</spock.version>
+        <jackson.version>2.10.5</jackson.version>
+        <jaxb-api.version>2.3.1</jaxb-api.version>
+        <jaxb-core.version>2.3.0.1</jaxb-core.version>
+        <immutables.version>2.8.8</immutables.version>
+        <semver4j.version>3.1.0</semver4j.version>
+        <vertx.version>3.9.2</vertx.version>
+        <graalvm.version>20.1.0</graalvm.version>
+        <quarkus.version>1.7.0.Final</quarkus.version>
+        <jandex.version>2.2.1.Final</jandex.version>
+        <javapoet.version>1.13.0</javapoet.version>
+        <rest-assured.version>4.3.1</rest-assured.version>
+        <hamcrest.version>2.2</hamcrest.version>
+        <jaeger.version>1.3.2</jaeger.version>
+        <json-schema-validator>2.2.14</json-schema-validator>
+
+        <camel-version>3.5.0-SNAPSHOT</camel-version>
 
         <!-- quarkus -->
         <camel-quarkus-version>1.0.0</camel-quarkus-version>
@@ -275,6 +301,7 @@
         <module>tooling</module>
 
         <module>camel-knative</module>
+        <module>camel-kamelet</module>
 
         <module>camel-k-runtime-core</module>
         <module>camel-k-main</module>
@@ -381,6 +408,11 @@
                 <artifactId>camel-knative-test</artifactId>
                 <version>${project.version}</version>
             </dependency>
+            <dependency>
+                <groupId>org.apache.camel.k</groupId>
+                <artifactId>camel-kamelet</artifactId>
+                <version>${project.version}</version>
+            </dependency>
 
             <!-- runtime -->
             <dependency>