You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2021/05/05 15:11:33 UTC
[camel] 01/05: CAMEL-16394: Route Template local beans. WIP
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch kamelet-local-registry
in repository https://gitbox.apache.org/repos/asf/camel.git
commit db8f3367f9e1883b3ddb87398520405b0420b597
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed May 5 16:18:07 2021 +0200
CAMEL-16394: Route Template local beans. WIP
---
.../org/apache/camel/RouteTemplateContext.java | 10 +++
.../java/org/apache/camel/impl/DefaultModel.java | 5 ++
.../camel/model/DefaultRouteTemplateContext.java | 7 ++
.../camel/model/RouteTemplateDefinition.java | 20 ++++++
.../camel/builder/RouteTemplateLocalBeanTest.java | 80 +++++++++++++++++++++-
5 files changed, 120 insertions(+), 2 deletions(-)
diff --git a/core/camel-api/src/main/java/org/apache/camel/RouteTemplateContext.java b/core/camel-api/src/main/java/org/apache/camel/RouteTemplateContext.java
index 3db1612..3e36a7e 100644
--- a/core/camel-api/src/main/java/org/apache/camel/RouteTemplateContext.java
+++ b/core/camel-api/src/main/java/org/apache/camel/RouteTemplateContext.java
@@ -91,6 +91,16 @@ public interface RouteTemplateContext {
Object getProperty(String name);
/**
+ * Gets the property with the given name
+ *
+ * @param name name of property
+ * @param type the type of the property
+ * @return the property value or <tt>null</tt> if no property exists
+ * @throws TypeConversionException is thrown if error during type conversion
+ */
+ <T> T getProperty(String name, Class<?> type);
+
+ /**
* Sets a parameter
*
* @param name the parameter name
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 e7bfc13..80ec4fb 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
@@ -246,6 +246,11 @@ public class DefaultModel implements Model {
throw new IllegalArgumentException("Cannot find RouteTemplate with id " + routeTemplateId);
}
+ // apply configurer if any present
+ if (target.getConfigurer() != null) {
+ target.getConfigurer().accept(routeTemplateContext);
+ }
+
final Map<String, Object> prop = new HashMap<>();
// include default values first from the template (and validate that we have inputs for all required parameters)
if (target.getTemplateParameters() != null) {
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/DefaultRouteTemplateContext.java b/core/camel-core-model/src/main/java/org/apache/camel/model/DefaultRouteTemplateContext.java
index a91da2c..5a9df3e 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/model/DefaultRouteTemplateContext.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/DefaultRouteTemplateContext.java
@@ -67,6 +67,13 @@ public final class DefaultRouteTemplateContext implements RouteTemplateContext {
}
@Override
+ @SuppressWarnings("unchecked")
+ public <T> T getProperty(String name, Class<?> type) {
+ Object value = parameters.get(name);
+ return (T) camelContext.getTypeConverter().tryConvertTo(type, value);
+ }
+
+ @Override
public void setParameter(String name, Object value) {
parameters.put(name, value);
}
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/RouteTemplateDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteTemplateDefinition.java
index cadb574..8fd4f84 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/model/RouteTemplateDefinition.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteTemplateDefinition.java
@@ -19,14 +19,17 @@ package org.apache.camel.model;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+import java.util.function.Consumer;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
import org.apache.camel.Endpoint;
+import org.apache.camel.RouteTemplateContext;
import org.apache.camel.builder.EndpointConsumerBuilder;
import org.apache.camel.spi.AsEndpointUri;
import org.apache.camel.spi.Metadata;
@@ -44,11 +47,17 @@ public class RouteTemplateDefinition extends OptionalIdentifiedDefinition {
private List<RouteTemplateParameterDefinition> templateParameters;
@XmlElement(name = "route", required = true)
private RouteDefinition route = new RouteDefinition();
+ @XmlTransient
+ private Consumer<RouteTemplateContext> configurer;
public List<RouteTemplateParameterDefinition> getTemplateParameters() {
return templateParameters;
}
+ public Consumer<RouteTemplateContext> getConfigurer() {
+ return configurer;
+ }
+
public void setTemplateParameters(List<RouteTemplateParameterDefinition> templateParameters) {
this.templateParameters = templateParameters;
}
@@ -151,6 +160,17 @@ public class RouteTemplateDefinition extends OptionalIdentifiedDefinition {
return this;
}
+ /**
+ * Sets a configurer which allows to do configuration while the route template is being used to create a route. This
+ * gives control over the creating process, such as binding local beans and doing other kind of customization.
+ *
+ * @param configurer the configurer with callback to invoke with the given route template context
+ */
+ public RouteTemplateDefinition configure(Consumer<RouteTemplateContext> configurer) {
+ this.configurer = configurer;
+ return this;
+ }
+
@Override
public String getShortName() {
return "routeTemplate";
diff --git a/core/camel-core/src/test/java/org/apache/camel/builder/RouteTemplateLocalBeanTest.java b/core/camel-core/src/test/java/org/apache/camel/builder/RouteTemplateLocalBeanTest.java
index 2e5e39a..6693ebf 100644
--- a/core/camel-core/src/test/java/org/apache/camel/builder/RouteTemplateLocalBeanTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/builder/RouteTemplateLocalBeanTest.java
@@ -21,6 +21,8 @@ import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.junit.jupiter.api.Test;
+import java.util.concurrent.atomic.AtomicInteger;
+
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
@@ -196,8 +198,9 @@ public class RouteTemplateLocalBeanTest extends ContextTestSupport {
.parameter("foo", "two")
.parameter("bar", "myBar")
.configure(rtc -> {
- rtc.bind("myBar", (Processor) ex -> ex.getMessage().setBody("Configure2 " + ex.getMessage().getBody()
- + " from " + rtc.getProperty("foo")));
+ rtc.bind("myBar", Processor.class,
+ (Processor) ex -> ex.getMessage().setBody("Configure2 " + ex.getMessage().getBody()
+ + " from " + rtc.getProperty("foo")));
})
.routeId("myRoute2")
.add();
@@ -215,6 +218,79 @@ public class RouteTemplateLocalBeanTest extends ContextTestSupport {
context.stop();
}
+ @Test
+ public void testLocalBeanInTemplate() throws Exception {
+ context.addRoutes(new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ routeTemplate("myTemplate").templateParameter("foo").templateParameter("bar")
+ .configure(rtc -> rtc.bind("myBar", (Processor) ex -> ex.getMessage().setBody("Builder " + ex.getMessage().getBody())))
+ .from("direct:{{foo}}")
+ .to("bean:{{bar}}");
+ }
+ });
+
+ context.start();
+
+ TemplatedRouteBuilder.builder(context, "myTemplate")
+ .parameter("foo", "one")
+ .parameter("bar", "myBar")
+ .routeId("myRoute")
+ .add();
+
+ assertEquals(1, context.getRoutes().size());
+
+ Object out = template.requestBody("direct:one", "World");
+ assertEquals("Builder World", out);
+
+ // should not be a global bean
+ assertNull(context.getRegistry().lookupByName("myBar"));
+
+ context.stop();
+ }
+
+ @Test
+ public void testLocalBeanInTemplateTwo() throws Exception {
+ final AtomicInteger counter = new AtomicInteger();
+
+ context.addRoutes(new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ routeTemplate("myTemplate").templateParameter("foo").templateParameter("bar")
+ .configure(rtc -> rtc.bind("myBar", (Processor) ex -> ex.getMessage().setBody("Builder" +
+ counter.incrementAndGet() + " " + ex.getMessage().getBody())))
+ .from("direct:{{foo}}")
+ .to("bean:{{bar}}");
+ }
+ });
+
+ context.start();
+
+ TemplatedRouteBuilder.builder(context, "myTemplate")
+ .parameter("foo", "one")
+ .parameter("bar", "myBar")
+ .routeId("myRoute")
+ .add();
+
+ TemplatedRouteBuilder.builder(context, "myTemplate")
+ .parameter("foo", "two")
+ .parameter("bar", "myBar")
+ .routeId("myRoute2")
+ .add();
+
+ assertEquals(2, context.getRoutes().size());
+
+ Object out = template.requestBody("direct:one", "World");
+ assertEquals("Builder1 World", out);
+ Object out2 = template.requestBody("direct:two", "Camel");
+ assertEquals("Builder2 Camel", out2);
+
+ // should not be a global bean
+ assertNull(context.getRegistry().lookupByName("myBar"));
+
+ context.stop();
+ }
+
private class BuilderProcessor implements Processor {
@Override