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


The following commit(s) were added to refs/heads/main by this push:
     new a4f21cea2614 CAMEL-24746: camel-kamelet-main - 
KameletOptimisedComponentResolver recognizes kamelets already in the model
a4f21cea2614 is described below

commit a4f21cea2614959d6ba898b6ed1b109cde297d69
Author: Bartosz Popiela <[email protected]>
AuthorDate: Tue Sep 22 08:37:59 2026 +0200

    CAMEL-24746: camel-kamelet-main - KameletOptimisedComponentResolver 
recognizes kamelets already in the model
    
    KameletOptimisedComponentResolver resolved every kamelet: URI by loading
    the route template from the KameletComponent location and downloading its
    dependencies. Kamelets registered as beans via @BindToRegistry (or any
    route template added programmatically) already live in the model's
    routeTemplateDefinitions, so this lookup failed for them.
    
    Skip the location-based loading when the model already holds a route
    template with that name. The constructor now takes a ModelCamelContext,
    which the sole caller (KameletMain) already provides.
    
    Closes #26446
    
    Co-authored-by: Guillaume Nodet - AI Bot <[email protected]>
    Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
---
 .../KameletOptimisedComponentResolver.java         |  9 +--
 .../KameletOptimisedComponentResolverTest.java     | 68 ++++++++++++++++++++++
 2 files changed, 73 insertions(+), 4 deletions(-)

diff --git 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/KameletOptimisedComponentResolver.java
 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/KameletOptimisedComponentResolver.java
index 7b2e6654530d..8c14cdbf4038 100644
--- 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/KameletOptimisedComponentResolver.java
+++ 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/KameletOptimisedComponentResolver.java
@@ -16,11 +16,11 @@
  */
 package org.apache.camel.main.download;
 
-import org.apache.camel.CamelContext;
 import org.apache.camel.Component;
 import org.apache.camel.component.kamelet.KameletComponent;
 import org.apache.camel.impl.engine.DefaultOptimisedComponentResolver;
 import org.apache.camel.language.simple.SimpleLanguage;
+import org.apache.camel.model.ModelCamelContext;
 import org.apache.camel.support.ExchangeHelper;
 import org.apache.camel.support.RouteTemplateHelper;
 
@@ -30,9 +30,9 @@ import org.apache.camel.support.RouteTemplateHelper;
  */
 public class KameletOptimisedComponentResolver extends 
DefaultOptimisedComponentResolver {
 
-    private final CamelContext camelContext;
+    private final ModelCamelContext camelContext;
 
-    public KameletOptimisedComponentResolver(CamelContext camelContext) {
+    public KameletOptimisedComponentResolver(ModelCamelContext camelContext) {
         super(camelContext);
         this.camelContext = camelContext;
     }
@@ -45,7 +45,8 @@ public class KameletOptimisedComponentResolver extends 
DefaultOptimisedComponent
         if ("kamelet".equals(scheme)) {
             String name = ExchangeHelper.resolveContextPath(uri);
             // must be a static name (so we can load the template and resolve 
nested dependencies)
-            if (!SimpleLanguage.hasSimpleFunction(name) && answer instanceof 
KameletComponent kc) {
+            if (!SimpleLanguage.hasSimpleFunction(name) && 
camelContext.getRouteTemplateDefinition(name) == null
+                    && answer instanceof KameletComponent kc) {
                 // need to resolve dependencies from kamelet also
                 String loc = kc.getLocation();
                 DependencyDownloaderKamelet listener = 
camelContext.hasService(DependencyDownloaderKamelet.class);
diff --git 
a/dsl/camel-kamelet-main/src/test/java/org/apache/camel/main/download/KameletOptimisedComponentResolverTest.java
 
b/dsl/camel-kamelet-main/src/test/java/org/apache/camel/main/download/KameletOptimisedComponentResolverTest.java
new file mode 100644
index 000000000000..ab4224445ab3
--- /dev/null
+++ 
b/dsl/camel-kamelet-main/src/test/java/org/apache/camel/main/download/KameletOptimisedComponentResolverTest.java
@@ -0,0 +1,68 @@
+/*
+ * 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.main.download;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.kamelet.KameletComponent;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+public class KameletOptimisedComponentResolverTest {
+
+    private DefaultCamelContext context;
+    private KameletOptimisedComponentResolver resolver;
+
+    @BeforeEach
+    void setUp() {
+        context = new DefaultCamelContext();
+        resolver = new KameletOptimisedComponentResolver(context);
+    }
+
+    @AfterEach
+    void tearDown() {
+        context.stop();
+    }
+
+    @Test
+    // Note: @BindToRegistry kamelets are also registered via 
Model.routeTemplateDefinitions
+    // (through AnnotationDependencyInjection → addRoutes → prepareModel → 
populateRouteTemplates),
+    // so this RouteBuilder-based registration exercises the same guard as the 
declared regression.
+    void shouldNotLoadTemplateFromLocationWhenTemplateInModel() throws 
Exception {
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() {
+                routeTemplate("myBeanKamelet")
+                        .from("direct:in")
+                        .to("mock:out");
+            }
+        });
+
+        var answer = resolver.resolveComponent("kamelet:myBeanKamelet");
+
+        assertInstanceOf(KameletComponent.class, answer);
+    }
+
+    @Test
+    void shouldLoadTemplateFromLocationWhenTemplateNotInModel() {
+        assertThrows(RuntimeException.class, () -> 
resolver.resolveComponent("kamelet:unknownKamelet"));
+    }
+}

Reply via email to