Author: davsclaus Date: Sun Feb 27 11:21:53 2011 New Revision: 1075028 URL: http://svn.apache.org/viewvc?rev=1075028&view=rev Log: CAMEL-3721: Properties component now support jvm/os env placeholders in location option.
Added: camel/trunk/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentLocationWithJvmPropertyTest.java - copied, changed from r1075006, camel/trunk/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentTest.java camel/trunk/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentLocationWithTwoJvmPropertyTest.java Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java camel/trunk/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentTest.java Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java?rev=1075028&r1=1075027&r2=1075028&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java Sun Feb 27 11:21:53 2011 @@ -18,6 +18,8 @@ package org.apache.camel.component.prope import java.util.Map; import java.util.Properties; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.apache.camel.Endpoint; import org.apache.camel.impl.DefaultComponent; @@ -36,6 +38,10 @@ public class PropertiesComponent extends public static final String PREFIX_TOKEN = "{{"; public static final String SUFFIX_TOKEN = "}}"; + // must be non greedy patterns + private static final Pattern ENV_PATTERN = Pattern.compile("\\$\\{env:(.*?)\\}", Pattern.DOTALL); + private static final Pattern SYS_PATTERN = Pattern.compile("\\$\\{(.*?)\\}", Pattern.DOTALL); + private static final transient Logger LOG = LoggerFactory.getLogger(PropertiesComponent.class); private final Map<String[], Properties> cacheMap = new LRUCache<String[], Properties>(1000); private PropertiesResolver propertiesResolver = new DefaultPropertiesResolver(); @@ -46,8 +52,12 @@ public class PropertiesComponent extends public PropertiesComponent() { } + public PropertiesComponent(String location) { + setLocation(location); + } + public PropertiesComponent(String... locations) { - this.locations = locations; + setLocations(locations); } @Override @@ -62,7 +72,6 @@ public class PropertiesComponent extends } paths = locations.split(","); } - String endpointUri = parseUri(remaining, paths); if (LOG.isDebugEnabled()) { LOG.debug("Endpoint uri parsed as: " + endpointUri); @@ -77,12 +86,16 @@ public class PropertiesComponent extends public String parseUri(String uri, String... paths) throws Exception { ObjectHelper.notNull(paths, "paths"); + // location may contain JVM system property or OS environment variables + // so we need to parse those + String[] locations = parseLocations(paths); + // check cache first - Properties prop = cache ? cacheMap.get(paths) : null; + Properties prop = cache ? cacheMap.get(locations) : null; if (prop == null) { - prop = propertiesResolver.resolveProperties(getCamelContext(), paths); + prop = propertiesResolver.resolveProperties(getCamelContext(), locations); if (cache) { - cacheMap.put(paths, prop); + cacheMap.put(locations, prop); } } @@ -142,4 +155,42 @@ public class PropertiesComponent extends super.doStop(); } + private String[] parseLocations(String[] locations) { + String[] answer = new String[locations.length]; + + for (int i = 0; i < locations.length; i++) { + String location = locations[i]; + LOG.trace("Parsing location: {} ", location); + + Matcher matcher = ENV_PATTERN.matcher(location); + while (matcher.find()) { + String key = matcher.group(1); + String value = System.getenv(key); + if (ObjectHelper.isEmpty(value)) { + throw new IllegalArgumentException("Cannot find system environment with key: " + key); + } + location = matcher.replaceFirst(value); + // must match again as location is changed + matcher = ENV_PATTERN.matcher(location); + } + + matcher = SYS_PATTERN.matcher(location); + while (matcher.find()) { + String key = matcher.group(1); + String value = System.getProperty(key); + if (ObjectHelper.isEmpty(value)) { + throw new IllegalArgumentException("Cannot find JVM system property with key: " + key); + } + location = matcher.replaceFirst(value); + // must match again as location is changed + matcher = SYS_PATTERN.matcher(location); + } + + LOG.debug("Parsed location: {} ", location); + answer[i] = location; + } + + return answer; + } + } Copied: camel/trunk/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentLocationWithJvmPropertyTest.java (from r1075006, camel/trunk/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentTest.java) URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentLocationWithJvmPropertyTest.java?p2=camel/trunk/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentLocationWithJvmPropertyTest.java&p1=camel/trunk/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentTest.java&r1=1075006&r2=1075028&rev=1075028&view=diff ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentTest.java (original) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentLocationWithJvmPropertyTest.java Sun Feb 27 11:21:53 2011 @@ -18,29 +18,14 @@ package org.apache.camel.component.prope import org.apache.camel.CamelContext; import org.apache.camel.ContextTestSupport; -import org.apache.camel.FailedToCreateRouteException; -import org.apache.camel.ResolveEndpointFailedException; import org.apache.camel.builder.RouteBuilder; /** * @version */ -public class PropertiesComponentTest extends ContextTestSupport { - - @Override - public boolean isUseRouteBuilder() { - return false; - } - - public void testPropertiesComponent() throws Exception { - context.addRoutes(new RouteBuilder() { - @Override - public void configure() throws Exception { - from("direct:start").to("properties:{{cool.end}}"); - } - }); - context.start(); +public class PropertiesComponentLocationWithJvmPropertyTest extends ContextTestSupport { + public void testProperty() throws Exception { getMockEndpoint("mock:result").expectedMessageCount(1); template.sendBody("direct:start", "Hello World"); @@ -48,169 +33,29 @@ public class PropertiesComponentTest ext assertMockEndpointsSatisfied(); } - public void testPropertiesComponentResult() throws Exception { - context.addRoutes(new RouteBuilder() { - @Override - public void configure() throws Exception { - from("direct:start").to("properties:mock:{{cool.result}}"); - } - }); - context.start(); - - getMockEndpoint("mock:result").expectedMessageCount(1); - - template.sendBody("direct:start", "Hello World"); - - assertMockEndpointsSatisfied(); - } - - public void testPropertiesComponentMockMock() throws Exception { - context.addRoutes(new RouteBuilder() { - @Override - public void configure() throws Exception { - from("direct:start").to("properties:{{cool.mock}}:{{cool.mock}}"); - } - }); - context.start(); - - getMockEndpoint("mock:mock").expectedMessageCount(1); - - template.sendBody("direct:start", "Hello World"); - - assertMockEndpointsSatisfied(); - } - - public void testPropertiesComponentConcat() throws Exception { - context.addRoutes(new RouteBuilder() { - @Override - public void configure() throws Exception { - from("direct:start").to("properties:cool.concat"); - } - }); - context.start(); - - getMockEndpoint("mock:result").expectedMessageCount(1); - - template.sendBody("direct:start", "Hello World"); - - assertMockEndpointsSatisfied(); - } - - public void testPropertiesComponentLocationOverride() throws Exception { - context.addRoutes(new RouteBuilder() { - @Override - public void configure() throws Exception { - from("direct:start").to("properties:{{bar.end}}?locations=org/apache/camel/component/properties/bar.properties"); - } - }); - context.start(); - - getMockEndpoint("mock:bar").expectedMessageCount(1); - - template.sendBody("direct:start", "Hello World"); - - assertMockEndpointsSatisfied(); - } - - public void testPropertiesComponentLocationsOverride() throws Exception { - context.addRoutes(new RouteBuilder() { - @Override - public void configure() throws Exception { - from("direct:start").to("properties:bar.end?locations=org/apache/camel/component/properties/bar.properties"); - from("direct:cheese").to("properties:cheese.end?locations=org/apache/camel/component/properties/bar.properties," - + "classpath:org/apache/camel/component/properties/cheese.properties"); - } - }); - context.start(); - - getMockEndpoint("mock:bar").expectedMessageCount(1); - getMockEndpoint("mock:cheese").expectedMessageCount(1); - - template.sendBody("direct:start", "Hello World"); - template.sendBody("direct:cheese", "Hello Cheese"); - - assertMockEndpointsSatisfied(); - } - - public void testPropertiesComponentInvalidKey() throws Exception { - context.addRoutes(new RouteBuilder() { - @Override - public void configure() throws Exception { - from("direct:start").to("properties:{{foo.unknown}}"); - } - }); - try { - context.start(); - fail("Should throw exception"); - } catch (FailedToCreateRouteException e) { - ResolveEndpointFailedException cause = assertIsInstanceOf(ResolveEndpointFailedException.class, e.getCause()); - IllegalArgumentException iae = assertIsInstanceOf(IllegalArgumentException.class, cause.getCause()); - assertEquals("Property with key [foo.unknown] not found in properties from text: {{foo.unknown}}", iae.getMessage()); - } - } - - public void testPropertiesComponentCircularReference() throws Exception { - context.addRoutes(new RouteBuilder() { - @Override - public void configure() throws Exception { - from("direct:start").to("properties:cool.a"); - } - }); - try { - context.start(); - fail("Should throw exception"); - } catch (FailedToCreateRouteException e) { - ResolveEndpointFailedException cause = assertIsInstanceOf(ResolveEndpointFailedException.class, e.getCause()); - IllegalArgumentException iae = assertIsInstanceOf(IllegalArgumentException.class, cause.getCause()); - assertEquals("Circular reference detected with key [cool.a] from text: {{cool.a}}", iae.getMessage()); - } - } - - public void testPropertiesComponentCacheDefault() throws Exception { - context.addRoutes(new RouteBuilder() { - @Override - public void configure() throws Exception { - // properties component can also have {{ }} around but its not needed - from("direct:start").to("properties:{{cool.end}}"); - from("direct:foo").to("properties:mock:{{cool.result}}"); - } - }); - context.start(); - - getMockEndpoint("mock:result").expectedMessageCount(2); - - template.sendBody("direct:start", "Hello World"); - template.sendBody("direct:foo", "Hello Foo"); - - assertMockEndpointsSatisfied(); - } - - public void testPropertiesComponentCacheDisabled() throws Exception { - PropertiesComponent pc = context.getComponent("properties", PropertiesComponent.class); - pc.setCache(false); - - context.addRoutes(new RouteBuilder() { + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { @Override public void configure() throws Exception { from("direct:start").to("properties:cool.end"); - from("direct:foo").to("properties:mock:{{cool.result}}"); } - }); - context.start(); - - getMockEndpoint("mock:result").expectedMessageCount(2); - - template.sendBody("direct:start", "Hello World"); - template.sendBody("direct:foo", "Hello Foo"); - - assertMockEndpointsSatisfied(); + }; } @Override protected CamelContext createCamelContext() throws Exception { CamelContext context = super.createCamelContext(); - context.addComponent("properties", new PropertiesComponent("classpath:org/apache/camel/component/properties/myproperties.properties")); + + System.setProperty("propFile", "myproperties.properties"); + context.addComponent("properties", new PropertiesComponent("classpath:org/apache/camel/component/properties/${propFile}")); + return context; } + @Override + protected void tearDown() throws Exception { + super.tearDown(); + System.clearProperty("propFile"); + } } Added: camel/trunk/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentLocationWithTwoJvmPropertyTest.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentLocationWithTwoJvmPropertyTest.java?rev=1075028&view=auto ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentLocationWithTwoJvmPropertyTest.java (added) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentLocationWithTwoJvmPropertyTest.java Sun Feb 27 11:21:53 2011 @@ -0,0 +1,42 @@ +/** + * 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.properties; + +import org.apache.camel.CamelContext; + +/** + * @version + */ +public class PropertiesComponentLocationWithTwoJvmPropertyTest extends PropertiesComponentLocationWithJvmPropertyTest { + + @Override + protected CamelContext createCamelContext() throws Exception { + CamelContext context = super.createCamelContext(); + + System.setProperty("propPath", "org/apache/camel/component/properties"); + PropertiesComponent pc = context.getComponent("properties", PropertiesComponent.class); + pc.setLocation("classpath:${propPath}/${propFile}"); + + return context; + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + System.clearProperty("propPath"); + } +} Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentTest.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentTest.java?rev=1075028&r1=1075027&r2=1075028&view=diff ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentTest.java (original) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentTest.java Sun Feb 27 11:21:53 2011 @@ -206,6 +206,22 @@ public class PropertiesComponentTest ext assertMockEndpointsSatisfied(); } + public void testJvmSystemPropertyNotFound() throws Exception { + try { + context.addRoutes(new RouteBuilder() { + @Override + public void configure() throws Exception { + from("direct:start").to("properties:xxx?locations=foo/${xxx}"); + } + }); + context.start(); + fail("Should thrown an exception"); + } catch (FailedToCreateRouteException e) { + IllegalArgumentException cause = assertIsInstanceOf(IllegalArgumentException.class, e.getCause().getCause()); + assertEquals("Cannot find JVM system property with key: xxx", cause.getMessage()); + } + } + @Override protected CamelContext createCamelContext() throws Exception { CamelContext context = super.createCamelContext();