This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch camel-3.18.x in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/camel-3.18.x by this push: new aba1bb40d87 [CAMEL-18737]: camel-kamelet parameter substitution does not work in bean instantiation when constructor is used (#8812) aba1bb40d87 is described below commit aba1bb40d87e6b1378992cfca6412daead5d4767 Author: Luigi De Masi <5583341+luigidem...@users.noreply.github.com> AuthorDate: Fri Dec 2 10:27:13 2022 +0100 [CAMEL-18737]: camel-kamelet parameter substitution does not work in bean instantiation when constructor is used (#8812) --- ...KameletBeanWithParametrizedConstructorTest.java | 72 ++++++++++++++++++++++ .../KameletBeanWithParametrizedFactoryTest.java | 53 ++++++++++++++++ .../org/apache/camel/component/kamelet/MyBean.java | 37 +++++++++++ .../java/org/apache/camel/impl/DefaultModel.java | 6 +- 4 files changed, 166 insertions(+), 2 deletions(-) diff --git a/components/camel-kamelet/src/test/java/org/apache/camel/component/kamelet/KameletBeanWithParametrizedConstructorTest.java b/components/camel-kamelet/src/test/java/org/apache/camel/component/kamelet/KameletBeanWithParametrizedConstructorTest.java new file mode 100644 index 00000000000..6d07f56abf1 --- /dev/null +++ b/components/camel-kamelet/src/test/java/org/apache/camel/component/kamelet/KameletBeanWithParametrizedConstructorTest.java @@ -0,0 +1,72 @@ +/* + * 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.component.kamelet; + +import org.apache.camel.RoutesBuilder; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.test.junit5.CamelTestSupport; +import org.junit.jupiter.api.Test; + +public class KameletBeanWithParametrizedConstructorTest extends CamelTestSupport { + + protected final String name = "Ada"; + + protected final String message = "Welcome"; + + protected final String out = "mock:out"; + + protected final String in = "direct:start"; + + @Test + public void testKamelet() throws Exception { + + getMockEndpoint("mock:out").expectedBodiesReceived("Hi " + name + "! " + message); + + template.sendBody(in, "Hello"); + + MockEndpoint.assertIsSatisfied(context); + } + + @Override + protected RoutesBuilder createRouteBuilder() { + return new RouteBuilder() { + @Override + public void configure() { + routeTemplate("salute") + .templateParameter("name") + .templateParameter("message") + .templateBean("myBean", "#class:org.apache.camel.component.kamelet.MyBean({{message}}, {{name}})") + .from("kamelet:source") + .to("bean:{{myBean}}?method=salute"); + + routeTemplate("myTemplate") + .templateParameter("uri") + .templateParameter("in") + .templateParameter("out") + .from("{{in}}") + .to("{{uri}}") + .to("{{out}}"); + + templatedRoute("myTemplate") + .parameter("in", in) + .parameter("uri", "kamelet:salute/test?name=" + name + "&message=" + message) + .parameter("out", out); + } + }; + } +} diff --git a/components/camel-kamelet/src/test/java/org/apache/camel/component/kamelet/KameletBeanWithParametrizedFactoryTest.java b/components/camel-kamelet/src/test/java/org/apache/camel/component/kamelet/KameletBeanWithParametrizedFactoryTest.java new file mode 100644 index 00000000000..75fe5007034 --- /dev/null +++ b/components/camel-kamelet/src/test/java/org/apache/camel/component/kamelet/KameletBeanWithParametrizedFactoryTest.java @@ -0,0 +1,53 @@ +/* + * 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.component.kamelet; + +import org.apache.camel.RoutesBuilder; +import org.apache.camel.builder.RouteBuilder; + +public class KameletBeanWithParametrizedFactoryTest extends KameletBeanWithParametrizedConstructorTest { + + @Override + protected RoutesBuilder createRouteBuilder() { + return new RouteBuilder() { + @Override + public void configure() { + routeTemplate("salute") + .templateParameter("name") + .templateParameter("message") + .templateBean("myBean", + "#class:org.apache.camel.component.kamelet.MyBean#getInstance({{message}}, {{name}})") + .from("kamelet:source") + .to("bean:{{myBean}}?method=salute"); + + routeTemplate("myTemplate") + .templateParameter("uri") + .templateParameter("in") + .templateParameter("out") + .from("{{in}}") + .to("{{uri}}") + .to("{{out}}"); + + templatedRoute("myTemplate") + .parameter("in", in) + .parameter("uri", "kamelet:salute/test?name=" + name + "&message=" + message) + .parameter("out", out); + } + }; + } + +} diff --git a/components/camel-kamelet/src/test/java/org/apache/camel/component/kamelet/MyBean.java b/components/camel-kamelet/src/test/java/org/apache/camel/component/kamelet/MyBean.java new file mode 100644 index 00000000000..809785bfe30 --- /dev/null +++ b/components/camel-kamelet/src/test/java/org/apache/camel/component/kamelet/MyBean.java @@ -0,0 +1,37 @@ +/* + * 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.component.kamelet; + +public class MyBean { + + private String message; + + private String name; + + public MyBean(String message, String name) { + this.message = message; + this.name = name; + } + + public static MyBean getInstance(String message, String name) { + return new MyBean(message, name); + } + + public String salute() { + return "Hi " + name + "! " + message; + } +} 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 e1dba69e1aa..422c6bf18fe 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 @@ -563,12 +563,14 @@ public class DefaultModel implements Model { final String fm = factoryMethod; final String fp = parameters; routeTemplateContext.bind(beanFactory.getName(), Object.class, Suppliers.memorize(() -> { + // resolve placeholders in parameters + String params = camelContext.resolvePropertyPlaceholders(fp); try { Object local; if (fm != null) { if (fp != null) { // special to support factory method parameters - local = PropertyBindingSupport.newInstanceFactoryParameters(camelContext, clazz, fm, fp); + local = PropertyBindingSupport.newInstanceFactoryParameters(camelContext, clazz, fm, params); } else { local = camelContext.getInjector().newInstance(clazz, fm); } @@ -578,7 +580,7 @@ public class DefaultModel implements Model { } } else { // special to support constructor parameters - local = PropertyBindingSupport.newInstanceConstructorParameters(camelContext, clazz, fp); + local = PropertyBindingSupport.newInstanceConstructorParameters(camelContext, clazz, params); } if (!props.isEmpty()) { setPropertiesOnTarget(camelContext, local, props);