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"));
+ }
+}