This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel.git
commit 577a4f173e128e7ffd24884b0c20e2d27fc895dd Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Sun Jun 7 22:10:46 2020 +0200 CAMEL-15155: camel-core - PropertyBindingSupport - Add # syntax to refer to property placeholder by id --- .../remote/FromFilePasswordPropertyRefTest.java | 61 ++++++++++++++++++++++ .../component/properties/PropertiesComponent.java | 9 +++- .../camel/support/PropertyBindingSupportTest.java | 37 +++++++++++++ .../camel/support/PropertyBindingSupport.java | 36 ++++++++++++- 4 files changed, 139 insertions(+), 4 deletions(-) diff --git a/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/FromFilePasswordPropertyRefTest.java b/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/FromFilePasswordPropertyRefTest.java new file mode 100644 index 0000000..58101be --- /dev/null +++ b/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/FromFilePasswordPropertyRefTest.java @@ -0,0 +1,61 @@ +/* + * 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.file.remote; + +import java.util.Properties; + +import org.apache.camel.CamelContext; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.junit.jupiter.api.Test; + +public class FromFilePasswordPropertyRefTest extends FtpServerTestSupport { + + protected String getFtpUrl() { + return "ftp://localhost:" + getPort() + "/tmp3/camel?username=us@r&password=#property:myPass&initialDelay=3000"; + } + + @Override + protected CamelContext createCamelContext() throws Exception { + CamelContext context = super.createCamelContext(); + + Properties prop = new Properties(); + prop.setProperty("myPass", "t%st"); + context.getPropertiesComponent().setInitialProperties(prop); + + return context; + } + + @Test + public void testFromFileToFtp() throws Exception { + MockEndpoint mock = getMockEndpoint("mock:result"); + mock.expectedMessageCount(2); + + assertMockEndpointsSatisfied(); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + public void configure() throws Exception { + from(getFtpUrl()).to("mock:result"); + + from("file:src/main/data?noop=true&delay=3000").to(getFtpUrl()); + } + }; + } +} diff --git a/core/camel-base/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java b/core/camel-base/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java index 36d66f8..1d3151f 100644 --- a/core/camel-base/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java +++ b/core/camel-base/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java @@ -158,8 +158,13 @@ public class PropertiesComponent extends ServiceSupport implements org.apache.ca @Override public Optional<String> resolveProperty(String key) { - String value = parseUri(key, propertiesLookup); - return Optional.of(value); + try { + String value = parseUri(key, propertiesLookup); + return Optional.of(value); + } catch (IllegalArgumentException e) { + // property not found + return Optional.empty(); + } } @Override diff --git a/core/camel-core/src/test/java/org/apache/camel/support/PropertyBindingSupportTest.java b/core/camel-core/src/test/java/org/apache/camel/support/PropertyBindingSupportTest.java index 8b96ed1..b115104 100644 --- a/core/camel-core/src/test/java/org/apache/camel/support/PropertyBindingSupportTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/support/PropertyBindingSupportTest.java @@ -24,6 +24,7 @@ import org.apache.camel.CamelContext; import org.apache.camel.ContextTestSupport; import org.apache.camel.PropertyBindingException; import org.apache.camel.spi.Injector; +import org.apache.camel.spi.PropertiesComponent; import org.junit.Test; /** @@ -73,6 +74,42 @@ public class PropertyBindingSupportTest extends ContextTestSupport { } @Test + public void testProperty() throws Exception { + PropertiesComponent pc = context.getPropertiesComponent(); + Properties prop = new Properties(); + prop.setProperty("customerName", "James"); + prop.setProperty("customerAge", "33"); + prop.setProperty("workKey", "customerWork"); + prop.setProperty("customerWork", "Acme"); + pc.setInitialProperties(prop); + + Foo foo = new Foo(); + + PropertyBindingSupport.build().bind(context, foo, "name", "#property:customerName"); + PropertyBindingSupport.build().bind(context, foo, "bar.age", "#property:customerAge"); + PropertyBindingSupport.build().bind(context, foo, "bar.gold-customer", "true"); + PropertyBindingSupport.build().bind(context, foo, "bar.rider", "true"); + PropertyBindingSupport.build().bind(context, foo, "bar.work.id", "456"); + PropertyBindingSupport.build().bind(context, foo, "bar.work.name", "#property:{{workKey}}"); + + assertEquals("James", foo.getName()); + assertEquals(33, foo.getBar().getAge()); + assertTrue(foo.getBar().isRider()); + assertTrue(foo.getBar().isGoldCustomer()); + assertEquals(456, foo.getBar().getWork().getId()); + assertEquals("Acme", foo.getBar().getWork().getName()); + + try { + PropertyBindingSupport.build().bind(context, foo, "name", "#property:unknown"); + fail("Should have thrown exception"); + } catch (PropertyBindingException e) { + assertEquals("name", e.getPropertyName()); + assertEquals("#property:unknown", e.getValue()); + assertEquals("Property with key unknown not found by properties component", e.getCause().getMessage()); + } + } + + @Test public void testWithFluentBuilder() throws Exception { Foo foo = new Foo(); diff --git a/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java b/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java index ca08ab0..f99d662 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java @@ -28,11 +28,13 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Optional; import java.util.Set; import org.apache.camel.CamelContext; import org.apache.camel.Component; import org.apache.camel.ExtendedCamelContext; +import org.apache.camel.NoSuchPropertyException; import org.apache.camel.PropertyBindingException; import org.apache.camel.spi.PropertyConfigurer; import org.apache.camel.spi.PropertyConfigurerGetter; @@ -51,6 +53,7 @@ import static org.apache.camel.util.ObjectHelper.isNotEmpty; * <li>map</li> - Properties can lookup in Map's using map syntax, eg foo[bar] where foo is the name of the property that is a Map instance, and bar is the name of the key.</li> * <li>list</li> - Properties can refer or add to in List's using list syntax, eg foo[0] where foo is the name of the property that is a * List instance, and 0 is the index. To refer to the last element, then use last as key.</li> + * <li>reference by property placeholder id - Values can refer to a property placeholder key with #property:myKey</li> * <li>reference by bean id - Values can refer to other beans in the registry by prefixing with with # or #bean: eg #myBean or #bean:myBean</li> * <li>reference by type - Values can refer to singleton beans by their type in the registry by prefixing with #type: syntax, eg #type:com.foo.MyClassType</li> * <li>autowire by type - Values can refer to singleton beans by auto wiring by setting the value to #autowired</li> @@ -639,7 +642,8 @@ public final class PropertyBindingSupport { private static Object resolveValue(CamelContext context, Object target, String name, Object value, boolean ignoreCase, boolean fluentBuilder, boolean allowPrivateSetter) throws Exception { if (value instanceof String) { - if (value.toString().equals("#autowired")) { + String str = value.toString(); + if (str.equals("#autowired")) { // we should get the type from the setter Method method = findBestSetterMethod(context, target.getClass(), name, fluentBuilder, allowPrivateSetter, ignoreCase); if (method != null) { @@ -655,6 +659,16 @@ public final class PropertyBindingSupport { } else { throw new IllegalStateException("Cannot find setter method with name: " + name + " on class: " + target.getClass().getName() + " to use for autowiring"); } + } else if (str.startsWith("#property:")) { + String key = str.substring(10); + // the key may have property placeholder so resolve those first + key = context.resolvePropertyPlaceholders(key); + Optional<String> resolved = context.getPropertiesComponent().resolveProperty(key); + if (resolved.isPresent()) { + value = resolved.get(); + } else { + throw new IllegalArgumentException("Property with key " + key + " not found by properties component"); + } } else { value = resolveBean(context, name, value); } @@ -856,7 +870,25 @@ public final class PropertyBindingSupport { * @return <tt>true</tt> if its a reference parameter */ private static boolean isReferenceParameter(String parameter) { - return parameter != null && parameter.trim().startsWith("#"); + if (parameter == null) { + return false; + } + parameter = parameter.trim(); + if (!parameter.startsWith("#")) { + return false; + } + + // non reference parameters are + // #bean: #class: #type: #property: #autowired + if (parameter.equals("#autowired") + || parameter.startsWith("#bean:") + || parameter.startsWith("#class:") + || parameter.startsWith("#type") + || parameter.startsWith("#property")) { + return false; + } + + return true; } private static Object newInstanceConstructorParameters(CamelContext camelContext, Class<?> type, String parameters) throws Exception {