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

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 6d41186d520481e3c92d22da114f3a739e958649
Author: Claus Ibsen <[email protected]>
AuthorDate: Fri Jun 18 21:04:00 2021 +0200

    CAMEL-16650: camel-kamelet - Add option to configure location for kamelet 
template to load from resource.
---
 .../camel/catalog/docs/kamelet-component.adoc      |  2 +-
 .../kamelet/KameletComponentConfigurer.java        | 17 ++--
 .../apache/camel/component/kamelet/kamelet.json    |  2 +-
 .../src/main/docs/kamelet-component.adoc           |  2 +-
 .../camel/component/kamelet/KameletComponent.java  | 81 +++++-------------
 .../camel/spi/RouteTemplateLoaderListener.java     | 15 ++--
 .../dsl/KameletComponentBuilderFactory.java        | 12 +--
 .../java/org/apache/camel/impl/DefaultModel.java   | 46 ++--------
 .../apache/camel/support/RouteTemplateHelper.java  | 98 ++++++++++++++++++++++
 .../modules/ROOT/pages/kamelet-component.adoc      |  2 +-
 .../apache/camel/main/DependencyDownloader.java    |  8 +-
 11 files changed, 156 insertions(+), 129 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/kamelet-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/kamelet-component.adoc
index 69a3580..1f0767e 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/kamelet-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/kamelet-component.adoc
@@ -42,7 +42,7 @@ The Kamelet component supports 9 options, which are listed 
below.
 | *lazyStartProducer* (producer) | 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 route to fail being started. By deferring this startup 
to be lazy then the startup failure can be handled during routing messages via 
Camel's routing error handlers. Beware that when the first message is processed 
then creating and [...]
 | *timeout* (producer) | The timeout value to use if block is enabled. | 30000 
| long
 | *autowiredEnabled* (advanced) | Whether autowiring is enabled. This is used 
for automatic autowiring options (the option must be marked as autowired) by 
looking up in the registry to find if there is a single instance of matching 
type, which then gets configured on the component. This can be used for 
automatic configuring JDBC data sources, JMS connection factories, AWS Clients, 
etc. | true | boolean
-| *kameletResourceLoaderListener* (advanced) | To plugin a custom listener for 
when the Kamelet component is loading Kamelets from external resources. |  | 
KameletResourceLoaderListener
+| *routeTemplateLoaderListener* (advanced) | *Autowired* To plugin a custom 
listener for when the Kamelet component is loading Kamelets from external 
resources. |  | RouteTemplateLoaderListener
 |===
 // component options: END
 
diff --git 
a/components/camel-kamelet/src/generated/java/org/apache/camel/component/kamelet/KameletComponentConfigurer.java
 
b/components/camel-kamelet/src/generated/java/org/apache/camel/component/kamelet/KameletComponentConfigurer.java
index ab5be2f..f734ad0 100644
--- 
a/components/camel-kamelet/src/generated/java/org/apache/camel/component/kamelet/KameletComponentConfigurer.java
+++ 
b/components/camel-kamelet/src/generated/java/org/apache/camel/component/kamelet/KameletComponentConfigurer.java
@@ -26,13 +26,13 @@ public class KameletComponentConfigurer extends 
PropertyConfigurerSupport implem
         case "block": target.setBlock(property(camelContext, boolean.class, 
value)); return true;
         case "bridgeerrorhandler":
         case "bridgeErrorHandler": 
target.setBridgeErrorHandler(property(camelContext, boolean.class, value)); 
return true;
-        case "kameletresourceloaderlistener":
-        case "kameletResourceLoaderListener": 
target.setKameletResourceLoaderListener(property(camelContext, 
org.apache.camel.component.kamelet.KameletResourceLoaderListener.class, 
value)); return true;
         case "lazystartproducer":
         case "lazyStartProducer": 
target.setLazyStartProducer(property(camelContext, boolean.class, value)); 
return true;
         case "location": target.setLocation(property(camelContext, 
java.lang.String.class, value)); return true;
         case "routeproperties":
         case "routeProperties": 
target.setRouteProperties(property(camelContext, java.util.Map.class, value)); 
return true;
+        case "routetemplateloaderlistener":
+        case "routeTemplateLoaderListener": 
target.setRouteTemplateLoaderListener(property(camelContext, 
org.apache.camel.spi.RouteTemplateLoaderListener.class, value)); return true;
         case "templateproperties":
         case "templateProperties": 
target.setTemplateProperties(property(camelContext, java.util.Map.class, 
value)); return true;
         case "timeout": target.setTimeout(property(camelContext, long.class, 
value)); return true;
@@ -41,6 +41,11 @@ public class KameletComponentConfigurer extends 
PropertyConfigurerSupport implem
     }
 
     @Override
+    public String[] getAutowiredNames() {
+        return new String[]{"routeTemplateLoaderListener"};
+    }
+
+    @Override
     public Class<?> getOptionType(String name, boolean ignoreCase) {
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "autowiredenabled":
@@ -48,13 +53,13 @@ public class KameletComponentConfigurer extends 
PropertyConfigurerSupport implem
         case "block": return boolean.class;
         case "bridgeerrorhandler":
         case "bridgeErrorHandler": return boolean.class;
-        case "kameletresourceloaderlistener":
-        case "kameletResourceLoaderListener": return 
org.apache.camel.component.kamelet.KameletResourceLoaderListener.class;
         case "lazystartproducer":
         case "lazyStartProducer": return boolean.class;
         case "location": return java.lang.String.class;
         case "routeproperties":
         case "routeProperties": return java.util.Map.class;
+        case "routetemplateloaderlistener":
+        case "routeTemplateLoaderListener": return 
org.apache.camel.spi.RouteTemplateLoaderListener.class;
         case "templateproperties":
         case "templateProperties": return java.util.Map.class;
         case "timeout": return long.class;
@@ -71,13 +76,13 @@ public class KameletComponentConfigurer extends 
PropertyConfigurerSupport implem
         case "block": return target.isBlock();
         case "bridgeerrorhandler":
         case "bridgeErrorHandler": return target.isBridgeErrorHandler();
-        case "kameletresourceloaderlistener":
-        case "kameletResourceLoaderListener": return 
target.getKameletResourceLoaderListener();
         case "lazystartproducer":
         case "lazyStartProducer": return target.isLazyStartProducer();
         case "location": return target.getLocation();
         case "routeproperties":
         case "routeProperties": return target.getRouteProperties();
+        case "routetemplateloaderlistener":
+        case "routeTemplateLoaderListener": return 
target.getRouteTemplateLoaderListener();
         case "templateproperties":
         case "templateProperties": return target.getTemplateProperties();
         case "timeout": return target.getTimeout();
diff --git 
a/components/camel-kamelet/src/generated/resources/org/apache/camel/component/kamelet/kamelet.json
 
b/components/camel-kamelet/src/generated/resources/org/apache/camel/component/kamelet/kamelet.json
index 48b7c51..2ea411c 100644
--- 
a/components/camel-kamelet/src/generated/resources/org/apache/camel/component/kamelet/kamelet.json
+++ 
b/components/camel-kamelet/src/generated/resources/org/apache/camel/component/kamelet/kamelet.json
@@ -30,7 +30,7 @@
     "lazyStartProducer": { "kind": "property", "displayName": "Lazy Start 
Producer", "group": "producer", "label": "producer", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": 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 star [...]
     "timeout": { "kind": "property", "displayName": "Timeout", "group": 
"producer", "label": "producer", "required": false, "type": "integer", 
"javaType": "long", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": 30000, "description": "The timeout value to use if block is 
enabled." },
     "autowiredEnabled": { "kind": "property", "displayName": "Autowired 
Enabled", "group": "advanced", "label": "advanced", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether autowiring is 
enabled. This is used for automatic autowiring options (the option must be 
marked as autowired) by looking up in the registry to find if there is a single 
instance of matching type, which t [...]
-    "kameletResourceLoaderListener": { "kind": "property", "displayName": 
"Kamelet Resource Loader Listener", "group": "advanced", "label": "advanced", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.component.kamelet.KameletResourceLoaderListener", 
"deprecated": false, "autowired": false, "secret": false, "description": "To 
plugin a custom listener for when the Kamelet component is loading Kamelets 
from external resources." }
+    "routeTemplateLoaderListener": { "kind": "property", "displayName": "Route 
Template Loader Listener", "group": "advanced", "label": "advanced", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.spi.RouteTemplateLoaderListener", "deprecated": false, 
"autowired": true, "secret": false, "description": "To plugin a custom listener 
for when the Kamelet component is loading Kamelets from external resources." }
   },
   "properties": {
     "templateId": { "kind": "path", "displayName": "Template Id", "group": 
"common", "label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The Route Template ID" },
diff --git a/components/camel-kamelet/src/main/docs/kamelet-component.adoc 
b/components/camel-kamelet/src/main/docs/kamelet-component.adoc
index 69a3580..1f0767e 100644
--- a/components/camel-kamelet/src/main/docs/kamelet-component.adoc
+++ b/components/camel-kamelet/src/main/docs/kamelet-component.adoc
@@ -42,7 +42,7 @@ The Kamelet component supports 9 options, which are listed 
below.
 | *lazyStartProducer* (producer) | 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 route to fail being started. By deferring this startup 
to be lazy then the startup failure can be handled during routing messages via 
Camel's routing error handlers. Beware that when the first message is processed 
then creating and [...]
 | *timeout* (producer) | The timeout value to use if block is enabled. | 30000 
| long
 | *autowiredEnabled* (advanced) | Whether autowiring is enabled. This is used 
for automatic autowiring options (the option must be marked as autowired) by 
looking up in the registry to find if there is a single instance of matching 
type, which then gets configured on the component. This can be used for 
automatic configuring JDBC data sources, JMS connection factories, AWS Clients, 
etc. | true | boolean
-| *kameletResourceLoaderListener* (advanced) | To plugin a custom listener for 
when the Kamelet component is loading Kamelets from external resources. |  | 
KameletResourceLoaderListener
+| *routeTemplateLoaderListener* (advanced) | *Autowired* To plugin a custom 
listener for when the Kamelet component is loading Kamelets from external 
resources. |  | RouteTemplateLoaderListener
 |===
 // component options: END
 
diff --git 
a/components/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/KameletComponent.java
 
b/components/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/KameletComponent.java
index d5c67f1..4cb36ff 100644
--- 
a/components/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/KameletComponent.java
+++ 
b/components/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/KameletComponent.java
@@ -27,19 +27,18 @@ import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.Endpoint;
-import org.apache.camel.ExtendedCamelContext;
 import org.apache.camel.Processor;
 import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.VetoCamelContextStartException;
 import org.apache.camel.model.ModelCamelContext;
 import org.apache.camel.model.RouteDefinition;
 import org.apache.camel.spi.Metadata;
-import org.apache.camel.spi.Resource;
+import org.apache.camel.spi.RouteTemplateLoaderListener;
 import org.apache.camel.spi.annotations.Component;
 import org.apache.camel.support.DefaultComponent;
 import org.apache.camel.support.LifecycleStrategySupport;
+import org.apache.camel.support.RouteTemplateHelper;
 import org.apache.camel.support.service.ServiceHelper;
-import org.apache.camel.util.FileUtil;
 import org.apache.camel.util.StopWatch;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -62,8 +61,8 @@ public class KameletComponent extends DefaultComponent {
     // active kamelet EIPs
     private final Map<String, Processor> kameletEips = new 
ConcurrentHashMap<>();
 
-    @Metadata(label = "advanced")
-    private KameletResourceLoaderListener kameletResourceLoaderListener;
+    @Metadata(label = "advanced", autowired = true)
+    private RouteTemplateLoaderListener routeTemplateLoaderListener;
 
     // counter that is used for producers to keep track if any consumer was 
added/removed since they last checked
     // this is used for optimization to avoid each producer to get consumer 
for each message processed
@@ -289,15 +288,15 @@ public class KameletComponent extends DefaultComponent {
         this.location = location;
     }
 
-    public KameletResourceLoaderListener getKameletResourceLoaderListener() {
-        return kameletResourceLoaderListener;
+    public RouteTemplateLoaderListener getRouteTemplateLoaderListener() {
+        return routeTemplateLoaderListener;
     }
 
     /**
      * To plugin a custom listener for when the Kamelet component is loading 
Kamelets from external resources.
      */
-    public void setKameletResourceLoaderListener(KameletResourceLoaderListener 
kameletResourceLoaderListener) {
-        this.kameletResourceLoaderListener = kameletResourceLoaderListener;
+    public void setRouteTemplateLoaderListener(RouteTemplateLoaderListener 
routeTemplateLoaderListener) {
+        this.routeTemplateLoaderListener = routeTemplateLoaderListener;
     }
 
     int getStateCounter() {
@@ -386,7 +385,6 @@ public class KameletComponent extends DefaultComponent {
         }
 
         public void createRouteForEndpoint(KameletEndpoint endpoint) throws 
Exception {
-            final ExtendedCamelContext ecc = 
getCamelContext().adapt(ExtendedCamelContext.class);
             final ModelCamelContext context = 
getCamelContext().adapt(ModelCamelContext.class);
             final String templateId = endpoint.getTemplateId();
             final String routeId = endpoint.getRouteId();
@@ -394,64 +392,23 @@ public class KameletComponent extends DefaultComponent {
 
             if (context.getRouteTemplateDefinition(templateId) == null && loc 
!= null) {
                 LOGGER.debug("Loading route template={} from {}", templateId, 
loc);
-
-                boolean found = false;
-                for (String path : loc.split(",")) {
-                    String name = path;
-                    Resource res = null;
-                    // first try resource as-is if the path has an extension
-                    String ext = FileUtil.onlyExt(path);
-                    if (ext != null) {
-                        res = ecc.getResourceLoader().resolveResource(name);
-                    }
-                    if (res == null || !res.exists()) {
-                        if (!path.endsWith("/")) {
-                            path += "/";
-                        }
-                        name = path + templateId + ".kamelet.yaml";
-                        res = ecc.getResourceLoader().resolveResource(name);
-                    }
-                    if (res.exists()) {
-                        try {
-                            if (kameletResourceLoaderListener != null) {
-                                
kameletResourceLoaderListener.loadKamelets(res);
-                            }
-                        } catch (Exception e) {
-                            LOGGER.warn("KameletResourceLoaderListener error 
due to " + e.getMessage()
-                                        + ". This exception is ignored",
-                                    e);
-                        }
-                        ecc.getRoutesLoader().loadRoutes(res);
-                        found = true;
-                        break;
-                    }
-                }
-                if (!found) {
-                    // fallback to old behaviour
-                    String path = loc;
-                    if (!path.endsWith("/")) {
-                        path += "/";
-                    }
-                    String target = path + templateId + ".kamelet.yaml";
-                    try {
-                        ecc.getRoutesLoader().loadRoutes(
-                                
ecc.getResourceLoader().resolveResource(target));
-                    } catch (Exception e) {
-                        throw new KameletNotFoundException(templateId, target, 
e);
-                    }
-                }
+                
RouteTemplateHelper.loadRouteTemplateFromLocation(getCamelContext(), 
routeTemplateLoaderListener, templateId,
+                        loc);
             }
 
             LOGGER.debug("Creating route from template={} and id={}", 
templateId, routeId);
+            try {
+                String id = context.addRouteFromTemplate(routeId, templateId, 
endpoint.getKameletProperties());
+                RouteDefinition def = context.getRouteDefinition(id);
 
-            final String id = context.addRouteFromTemplate(routeId, 
templateId, endpoint.getKameletProperties());
-            final RouteDefinition def = context.getRouteDefinition(id);
+                if (!def.isPrepared()) {
+                    
context.startRouteDefinitions(Collections.singletonList(def));
+                }
 
-            if (!def.isPrepared()) {
-                context.startRouteDefinitions(Collections.singletonList(def));
+                LOGGER.debug("Route with id={} created from template={}", id, 
templateId);
+            } catch (Exception e) {
+                throw new KameletNotFoundException(templateId, loc, e);
             }
-
-            LOGGER.debug("Route with id={} created from template={}", id, 
templateId);
         }
 
         @Override
diff --git 
a/components/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/KameletResourceLoaderListener.java
 
b/core/camel-api/src/main/java/org/apache/camel/spi/RouteTemplateLoaderListener.java
similarity index 72%
rename from 
components/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/KameletResourceLoaderListener.java
rename to 
core/camel-api/src/main/java/org/apache/camel/spi/RouteTemplateLoaderListener.java
index 3692a52..d27beff 100644
--- 
a/components/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/KameletResourceLoaderListener.java
+++ 
b/core/camel-api/src/main/java/org/apache/camel/spi/RouteTemplateLoaderListener.java
@@ -14,23 +14,22 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.component.kamelet;
-
-import org.apache.camel.spi.Resource;
+package org.apache.camel.spi;
 
 /**
- * Listener when the Kamelet component is loaing Kamelet(s) from a {@link 
Resource}.
+ * Listener when route templates is loaded from a {@link Resource}.
  *
  * For example when Kamelets are loaded from YAML files from the classpath, or 
via github from the Apache Camel Kamelet
  * Catalog.
  */
 @FunctionalInterface
-public interface KameletResourceLoaderListener {
+public interface RouteTemplateLoaderListener {
 
     /**
-     * About to load kamelets from the given resource.
+     * About to load route template (kamelet) from the given resource.
      *
-     * @param resource the resource that has kamelets to be loaded
+     * @param resource the resource that has route templates to be loaded
      */
-    void loadKamelets(Resource resource);
+    void loadRouteTemplate(Resource resource);
+
 }
diff --git 
a/core/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/KameletComponentBuilderFactory.java
 
b/core/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/KameletComponentBuilderFactory.java
index f4c2d89..9a5b199 100644
--- 
a/core/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/KameletComponentBuilderFactory.java
+++ 
b/core/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/KameletComponentBuilderFactory.java
@@ -202,16 +202,16 @@ public interface KameletComponentBuilderFactory {
          * Kamelets from external resources.
          * 
          * The option is a:
-         * 
&lt;code&gt;org.apache.camel.component.kamelet.KameletResourceLoaderListener&lt;/code&gt;
 type.
+         * 
&lt;code&gt;org.apache.camel.spi.RouteTemplateLoaderListener&lt;/code&gt; type.
          * 
          * Group: advanced
          * 
-         * @param kameletResourceLoaderListener the value to set
+         * @param routeTemplateLoaderListener the value to set
          * @return the dsl builder
          */
-        default KameletComponentBuilder kameletResourceLoaderListener(
-                
org.apache.camel.component.kamelet.KameletResourceLoaderListener 
kameletResourceLoaderListener) {
-            doSetProperty("kameletResourceLoaderListener", 
kameletResourceLoaderListener);
+        default KameletComponentBuilder routeTemplateLoaderListener(
+                org.apache.camel.spi.RouteTemplateLoaderListener 
routeTemplateLoaderListener) {
+            doSetProperty("routeTemplateLoaderListener", 
routeTemplateLoaderListener);
             return this;
         }
     }
@@ -239,7 +239,7 @@ public interface KameletComponentBuilderFactory {
             case "lazyStartProducer": ((KameletComponent) 
component).setLazyStartProducer((boolean) value); return true;
             case "timeout": ((KameletComponent) component).setTimeout((long) 
value); return true;
             case "autowiredEnabled": ((KameletComponent) 
component).setAutowiredEnabled((boolean) value); return true;
-            case "kameletResourceLoaderListener": ((KameletComponent) 
component).setKameletResourceLoaderListener((org.apache.camel.component.kamelet.KameletResourceLoaderListener)
 value); return true;
+            case "routeTemplateLoaderListener": ((KameletComponent) 
component).setRouteTemplateLoaderListener((org.apache.camel.spi.RouteTemplateLoaderListener)
 value); return true;
             default: return false;
             }
         }
diff --git 
a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java 
b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java
index e62511d..453a205 100644
--- 
a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java
+++ 
b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java
@@ -60,14 +60,15 @@ import org.apache.camel.spi.ExchangeFactory;
 import org.apache.camel.spi.Language;
 import org.apache.camel.spi.ModelReifierFactory;
 import org.apache.camel.spi.PropertyConfigurer;
-import org.apache.camel.spi.Resource;
+import org.apache.camel.spi.RouteTemplateLoaderListener;
 import org.apache.camel.spi.RouteTemplateParameterSource;
 import org.apache.camel.spi.ScriptingLanguage;
+import org.apache.camel.support.CamelContextHelper;
 import org.apache.camel.support.PropertyBindingSupport;
+import org.apache.camel.support.RouteTemplateHelper;
 import org.apache.camel.support.ScriptHelper;
 import org.apache.camel.support.service.ServiceHelper;
 import org.apache.camel.util.AntPathMatcher;
-import org.apache.camel.util.FileUtil;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.function.Suppliers;
 
@@ -266,7 +267,10 @@ public class DefaultModel implements Model {
             // and look up again
             Object location = 
routeTemplateContext.getParameters().get(RouteTemplateParameterSource.LOCATION);
             if (location != null) {
-                loadRouteTemplateFromLocation(routeTemplateId, 
location.toString());
+                RouteTemplateLoaderListener listener
+                        = CamelContextHelper.findByType(getCamelContext(), 
RouteTemplateLoaderListener.class);
+                
RouteTemplateHelper.loadRouteTemplateFromLocation(getCamelContext(), listener, 
routeTemplateId,
+                        location.toString());
             }
             for (RouteTemplateDefinition def : routeTemplateDefinitions) {
                 if (routeTemplateId.equals(def.getId())) {
@@ -360,42 +364,6 @@ public class DefaultModel implements Model {
         return def.getId();
     }
 
-    private void loadRouteTemplateFromLocation(String templateId, String 
location) throws Exception {
-        ExtendedCamelContext ecc = 
getCamelContext().adapt(ExtendedCamelContext.class);
-        boolean found = false;
-        for (String path : location.split(",")) {
-            String name = path;
-            Resource res = null;
-            // first try resource as-is if the path has an extension
-            String ext = FileUtil.onlyExt(path);
-            if (ext != null) {
-                res = ecc.getResourceLoader().resolveResource(name);
-            }
-            if (res == null || !res.exists()) {
-                if (!path.endsWith("/")) {
-                    path += "/";
-                }
-                name = path + templateId + ".kamelet.yaml";
-                res = ecc.getResourceLoader().resolveResource(name);
-            }
-            if (res.exists()) {
-                ecc.getRoutesLoader().loadRoutes(res);
-                found = true;
-                break;
-            }
-        }
-        if (!found) {
-            // fallback to old behaviour
-            String path = location;
-            if (!path.endsWith("/")) {
-                path += "/";
-            }
-            String target = path + templateId + ".kamelet.yaml";
-            ecc.getRoutesLoader().loadRoutes(
-                    ecc.getResourceLoader().resolveResource(target));
-        }
-    }
-
     private void addTemplateBeans(RouteTemplateContext routeTemplateContext, 
RouteTemplateDefinition target) throws Exception {
         for (RouteTemplateBeanDefinition b : target.getTemplateBeans()) {
             final Map<String, Object> props = new HashMap<>();
diff --git 
a/core/camel-support/src/main/java/org/apache/camel/support/RouteTemplateHelper.java
 
b/core/camel-support/src/main/java/org/apache/camel/support/RouteTemplateHelper.java
new file mode 100644
index 0000000..3a7572f
--- /dev/null
+++ 
b/core/camel-support/src/main/java/org/apache/camel/support/RouteTemplateHelper.java
@@ -0,0 +1,98 @@
+/*
+ * 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.support;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.ExtendedCamelContext;
+import org.apache.camel.spi.Resource;
+import org.apache.camel.spi.RouteTemplateLoaderListener;
+import org.apache.camel.util.FileUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Helper for working with route templates.
+ */
+public final class RouteTemplateHelper {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(RouteTemplateHelper.class);
+
+    private RouteTemplateHelper() {
+    }
+
+    /**
+     * Loads the route template with the given template id from a given 
location. After the template is loaded, it is
+     * automatic added to the {@link CamelContext}.
+     *
+     * @param  camelContext the camel context
+     * @param  listener     optional listener for when a route template is 
being loaded
+     * @param  templateId   the template id
+     * @param  location     location of the route template to load as a 
resource such as from classpath or file system
+     * @throws Exception    is thrown if any kind of error loading the route 
template
+     */
+    public static void loadRouteTemplateFromLocation(
+            CamelContext camelContext, RouteTemplateLoaderListener listener,
+            String templateId, String location)
+            throws Exception {
+        if (location == null) {
+            throw new IllegalArgumentException("Location is empty");
+        }
+
+        ExtendedCamelContext ecc = 
camelContext.adapt(ExtendedCamelContext.class);
+        boolean found = false;
+        for (String path : location.split(",")) {
+            String name = path;
+            Resource res = null;
+            // first try resource as-is if the path has an extension
+            String ext = FileUtil.onlyExt(path);
+            if (ext != null) {
+                res = ecc.getResourceLoader().resolveResource(name);
+            }
+            if (res == null || !res.exists()) {
+                if (!path.endsWith("/")) {
+                    path += "/";
+                }
+                name = path + templateId + ".kamelet.yaml";
+                res = ecc.getResourceLoader().resolveResource(name);
+            }
+            if (res.exists()) {
+                try {
+                    if (listener != null) {
+                        listener.loadRouteTemplate(res);
+                    }
+                } catch (Exception e) {
+                    LOG.warn("RouteTemplateLoaderListener error due to " + 
e.getMessage()
+                             + ". This exception is ignored",
+                            e);
+                }
+                ecc.getRoutesLoader().loadRoutes(res);
+                found = true;
+                break;
+            }
+        }
+        if (!found) {
+            // fallback to old behaviour
+            String path = location;
+            if (!path.endsWith("/")) {
+                path += "/";
+            }
+            String target = path + templateId + ".kamelet.yaml";
+            ecc.getRoutesLoader().loadRoutes(
+                    ecc.getResourceLoader().resolveResource(target));
+        }
+    }
+}
diff --git a/docs/components/modules/ROOT/pages/kamelet-component.adoc 
b/docs/components/modules/ROOT/pages/kamelet-component.adoc
index 3ed6c39..a405b0e 100644
--- a/docs/components/modules/ROOT/pages/kamelet-component.adoc
+++ b/docs/components/modules/ROOT/pages/kamelet-component.adoc
@@ -44,7 +44,7 @@ The Kamelet component supports 9 options, which are listed 
below.
 | *lazyStartProducer* (producer) | 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 route to fail being started. By deferring this startup 
to be lazy then the startup failure can be handled during routing messages via 
Camel's routing error handlers. Beware that when the first message is processed 
then creating and [...]
 | *timeout* (producer) | The timeout value to use if block is enabled. | 30000 
| long
 | *autowiredEnabled* (advanced) | Whether autowiring is enabled. This is used 
for automatic autowiring options (the option must be marked as autowired) by 
looking up in the registry to find if there is a single instance of matching 
type, which then gets configured on the component. This can be used for 
automatic configuring JDBC data sources, JMS connection factories, AWS Clients, 
etc. | true | boolean
-| *kameletResourceLoaderListener* (advanced) | To plugin a custom listener for 
when the Kamelet component is loading Kamelets from external resources. |  | 
KameletResourceLoaderListener
+| *routeTemplateLoaderListener* (advanced) | *Autowired* To plugin a custom 
listener for when the Kamelet component is loading Kamelets from external 
resources. |  | RouteTemplateLoaderListener
 |===
 // component options: END
 
diff --git 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloader.java
 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloader.java
index e6fe851..7a65cbf 100644
--- 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloader.java
+++ 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/DependencyDownloader.java
@@ -20,15 +20,15 @@ import org.apache.camel.CamelContext;
 import org.apache.camel.CamelContextAware;
 import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.component.kamelet.KameletComponent;
-import org.apache.camel.component.kamelet.KameletResourceLoaderListener;
 import org.apache.camel.spi.Resource;
+import org.apache.camel.spi.RouteTemplateLoaderListener;
 import org.apache.camel.support.service.ServiceHelper;
 import org.apache.camel.support.service.ServiceSupport;
 
 /**
  * To automatic downloaded dependencies that Kamelets requires.
  */
-public final class DependencyDownloader extends ServiceSupport implements 
CamelContextAware, KameletResourceLoaderListener {
+public final class DependencyDownloader extends ServiceSupport implements 
CamelContextAware, RouteTemplateLoaderListener {
 
     private final KameletDependencyDownloader downloader = new 
KameletDependencyDownloader("yaml");
     private CamelContext camelContext;
@@ -46,7 +46,7 @@ public final class DependencyDownloader extends 
ServiceSupport implements CamelC
     @Override
     protected void doBuild() throws Exception {
         KameletComponent kc = camelContext.getComponent("kamelet", 
KameletComponent.class);
-        kc.setKameletResourceLoaderListener(this);
+        kc.setRouteTemplateLoaderListener(this);
 
         downloader.setCamelContext(camelContext);
         ServiceHelper.buildService(downloader);
@@ -68,7 +68,7 @@ public final class DependencyDownloader extends 
ServiceSupport implements CamelC
     }
 
     @Override
-    public void loadKamelets(Resource resource) {
+    public void loadRouteTemplate(Resource resource) {
         if (resource.getLocation().endsWith(".yaml")) {
             try {
                 downloader.doLoadRouteBuilder(resource);

Reply via email to