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 7fe950d Kamelet local bean - Created local bean should memorize so
when using the bean multiple times its the same local bean
7fe950d is described below
commit 7fe950d4d257e38abdae63c096e9003e2cedc229
Author: Claus Ibsen <[email protected]>
AuthorDate: Fri May 14 08:45:48 2021 +0200
Kamelet local bean - Created local bean should memorize so when using the
bean multiple times its the same local bean
---
.../java/org/apache/camel/impl/DefaultModel.java | 19 ++++++---
.../camel/builder/RouteTemplateLocalBeanTest.java | 46 ++++++++++++++++++++++
2 files changed, 59 insertions(+), 6 deletions(-)
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 56196e7..b311748 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
@@ -66,6 +66,7 @@ import org.apache.camel.support.ScriptHelper;
import org.apache.camel.support.service.ServiceHelper;
import org.apache.camel.util.AntPathMatcher;
import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.function.Suppliers;
public class DefaultModel implements Model {
@@ -366,7 +367,9 @@ public class DefaultModel implements Model {
final ScriptingLanguage slan = lan instanceof
ScriptingLanguage ? (ScriptingLanguage) lan : null;
if (slan != null) {
// scripting language should be evaluated with route
template context as binding
- routeTemplateContext.bind(b.getName(), clazz, () -> {
+ // and memorize so the script is only evaluated once and
the local bean is the same
+ // if a route template refers to the local bean multiple
times
+ routeTemplateContext.bind(b.getName(), clazz,
Suppliers.memorize(() -> {
Map<String, Object> bindings = new HashMap<>();
// use rtx as the short-hand name, as context would
imply its CamelContext
bindings.put("rtc", routeTemplateContext);
@@ -375,10 +378,12 @@ public class DefaultModel implements Model {
setPropertiesOnTarget(camelContext, local, props);
}
return local;
- });
+ }));
} else {
// exchange based languages needs a dummy exchange to be
evaluated
- routeTemplateContext.bind(b.getName(), clazz, () -> {
+ // and memorize so the script is only evaluated once and
the local bean is the same
+ // if a route template refers to the local bean multiple
times
+ routeTemplateContext.bind(b.getName(), clazz,
Suppliers.memorize(() -> {
ExchangeFactory ef =
camelContext.adapt(ExtendedCamelContext.class).getExchangeFactory();
Exchange dummy = ef.create(false);
try {
@@ -396,20 +401,22 @@ public class DefaultModel implements Model {
} finally {
ef.release(dummy);
}
- });
+ }));
}
} else if (b.getBeanClass() != null || b.getType() != null &&
b.getType().startsWith("#class:")) {
Class<?> clazz = b.getBeanClass() != null
? b.getBeanClass() :
camelContext.getClassResolver().resolveMandatoryClass(b.getType().substring(7));
// we only have the bean class so we use that to create a new
bean via the injector
+ // and memorize so the bean is only created once and the local
bean is the same
+ // if a route template refers to the local bean multiple times
routeTemplateContext.bind(b.getName(), clazz,
- () -> {
+ Suppliers.memorize(() -> {
Object local =
camelContext.getInjector().newInstance(clazz);
if (!props.isEmpty()) {
setPropertiesOnTarget(camelContext, local,
props);
}
return local;
- });
+ }));
} else if (b.getType() != null &&
b.getType().startsWith("#type:")) {
Class<?> clazz =
camelContext.getClassResolver().resolveMandatoryClass(b.getType().substring(6));
Set<?> found =
getCamelContext().getRegistry().findByType(clazz);
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 83337fb0..7228b50 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
@@ -23,6 +23,7 @@ import org.apache.camel.ContextTestSupport;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.RouteTemplateContext;
+import org.apache.camel.component.mock.MockEndpoint;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -650,6 +651,47 @@ public class RouteTemplateLocalBeanTest extends
ContextTestSupport {
context.stop();
}
+ @Test
+ public void testLocalBeanMemorize() throws Exception {
+ context.addRoutes(new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+
routeTemplate("myTemplate").templateParameter("foo").templateParameter("bar").templateParameter("hi")
+ .templateBean("myBar").property("prefix",
"{{hi}}").typeClass(BuilderThreeProcessor.class).end()
+ .from("direct:{{foo}}")
+ // use unique endpoints to force referring the to bean
twice
+ .to("bean:{{bar}}")
+ .to("bean:{{bar}}?method=process")
+ .to("mock:result");
+ }
+ });
+
+ context.start();
+
+ TemplatedRouteBuilder.builder(context, "myTemplate")
+ .parameter("foo", "one")
+ .parameter("bar", "myBar")
+ .parameter("hi", "Davs")
+ .routeId("myRoute")
+ .add();
+
+ assertEquals(1, context.getRoutes().size());
+
+ MockEndpoint mock = getMockEndpoint("mock:result");
+ mock.expectedBodiesReceived("DavsBuilder3 DavsBuilder3 World");
+ mock.expectedHeaderReceived("counter", 2);
+
+ Object out = template.requestBody("direct:one", "World");
+ assertEquals("DavsBuilder3 DavsBuilder3 World", out);
+
+ assertMockEndpointsSatisfied();
+
+ // should not be a global bean
+ assertNull(context.getRegistry().lookupByName("myBar"));
+
+ context.stop();
+ }
+
public static class BuilderTwoProcessor implements Processor {
private String prefix = "";
@@ -670,6 +712,7 @@ public class RouteTemplateLocalBeanTest extends
ContextTestSupport {
public static class BuilderThreeProcessor implements Processor {
private String prefix = "";
+ private int counter;
public String getPrefix() {
return prefix;
@@ -681,8 +724,11 @@ public class RouteTemplateLocalBeanTest extends
ContextTestSupport {
@Override
public void process(Exchange exchange) throws Exception {
+ counter++;
exchange.getMessage().setBody(prefix + "Builder3 " +
exchange.getMessage().getBody());
+ exchange.getMessage().setHeader("counter", counter);
}
+
}
public Processor createBuilderProcessor() {