25 25 26 26 import org.apache.camel.Endpoint; 27 27 import org.apache.camel.impl.DefaultComponent; 28 -import org.apache.camel.util.FilePathResolver; 28 +import org.apache.camel.util.SystemAndEnvPropertyResolver; 29 29 import org.apache.camel.util.LRUSoftCache; 30 30 import org.apache.camel.util.ObjectHelper; 31 31 import org.slf4j.Logger; @@ -120,7 +120,7 @@ public String parseUri(String uri) throws Exception { 120 120 public String parseUri(String uri, String... paths) throws Exception { 121 121 Properties prop = null; 122 122 if (paths != null) { 123 - // location may contain JVM system property or OS environment variables 123 + // location may contain JVM system properties or OS environment variables 124 124 // so we need to parse those 125 125 String[] locations = parseLocations(paths); 126 126 @@ -135,11 +135,24 @@ public String parseUri(String uri, String... paths) throws Exception { 135 135 } 136 136 } 137 137 138 + // propertyPrefix and propertySuffix may contain JVM system properties or OS environment variables 139 + // so we need to parse those 140 + String parsedPropertyPrefix = propertyPrefix; 141 + if (ObjectHelper.isNotEmpty(propertyPrefix)) { 142 + parsedPropertyPrefix = parsePropertyPrefix(propertyPrefix); 143 + } 144 + String parsedPropertySuffix = propertySuffix; 145 + if (ObjectHelper.isNotEmpty(propertySuffix)) { 146 + parsedPropertySuffix = parsePropertySuffix(propertySuffix); 147 + } 148 + 138 149 // use override properties 139 - if (prop != null && overrideProperties != null) { 140 - // make a copy to avoid affecting the original properties 150 + if (overrideProperties != null) { 141 151 Properties override = new Properties(); 142 - override.putAll(prop); 152 + if (null != prop) { 153 + // make a copy to avoid affecting the original properties 154 + override.putAll(prop); 155 + } 143 156 override.putAll(overrideProperties); 144 157 prop = override; 145 158 } @@ -156,7 +169,7 @@ public String parseUri(String uri, String... paths) throws Exception { 156 169 157 170 if (propertiesParser instanceof AugmentedPropertyNameAwarePropertiesParser) { 158 171 return ((AugmentedPropertyNameAwarePropertiesParser) propertiesParser).parseUri(uri, prop, prefixToken, suffixToken, 159 - propertyPrefix, propertySuffix, fallbackToUnaugmentedProperty); 172 + parsedPropertyPrefix, parsedPropertySuffix, fallbackToUnaugmentedProperty); 160 173 } else { 161 174 return propertiesParser.parseUri(uri, prop, prefixToken, suffixToken); 162 175 } @@ -289,7 +302,7 @@ protected void doStop() throws Exception { 289 302 LOG.trace("Parsing location: {} ", location); 290 303 291 304 try { 292 - location = FilePathResolver.resolvePath(location); 305 + location = SystemAndEnvPropertyResolver.resolveString(location); 293 306 LOG.debug("Parsed location: {} ", location); 294 307 if (ObjectHelper.isNotEmpty(location)) { 295 308 answer.add(location); @@ -307,6 +320,46 @@ protected void doStop() throws Exception { 307 320 return answer.toArray(new String[answer.size()]); 308 321 } 309 322 323 + private String parsePropertyPrefix(String propertyPrefix) { 324 + String answer = propertyPrefix; 325 + 326 + LOG.trace("Parsing propertyPrefix: {} ", propertyPrefix); 327 + 328 + try { 329 + String parsedPropertyPrefix = SystemAndEnvPropertyResolver.resolveString(propertyPrefix); 330 + LOG.debug("Parsed propertyPrefix: {} ", parsedPropertyPrefix); 331 + if (ObjectHelper.isNotEmpty(parsedPropertyPrefix)) { 332 + answer = parsedPropertyPrefix; 333 + } else { 334 + LOG.warn("PropertyPrefix resolves to empty string: {} -> {}. Using the unparsed form", propertyPrefix, parsedPropertyPrefix); 335 + } 336 + } catch (IllegalArgumentException e) { 337 + throw e; 338 + } 339 + 340 + return answer; 341 + } 342 + 343 + private String parsePropertySuffix(String propertySuffix) { 344 + String answer = propertySuffix; 345 + 346 + LOG.trace("Parsing propertySuffix: {} ", propertySuffix); 347 + 348 + try { 349 + String parsedPropertySuffix = SystemAndEnvPropertyResolver.resolveString(propertySuffix); 350 + LOG.debug("Parsed propertySuffix: {} ", parsedPropertySuffix); 351 + if (ObjectHelper.isNotEmpty(parsedPropertySuffix)) { 352 + answer = parsedPropertySuffix; 353 + } else { 354 + LOG.warn("PropertySuffix resolves to empty string: {} -> {}. Using the unparsed form", propertySuffix, parsedPropertySuffix); 355 + } 356 + } catch (IllegalArgumentException e) { 357 + throw e; 358 + } 359 + 360 + return answer; 361 + } 362 + 310 363 /** 311 364 * Key used in the locations cache 312 365 */ camel-core/src/main/java/org/apache/camel/impl/DefaultStreamCachingStrategy.java @@ -28,7 +28,7 @@ 28 28 import org.apache.camel.Exchange; 29 29 import org.apache.camel.StreamCache; 30 30 import org.apache.camel.spi.StreamCachingStrategy; 31 -import org.apache.camel.util.FilePathResolver; 31 +import org.apache.camel.util.SystemAndEnvPropertyResolver; 32 32 import org.apache.camel.util.FileUtil; 33 33 import org.apache.camel.util.IOHelper; 34 34 import org.slf4j.Logger; @@ -223,7 +223,7 @@ protected String customResolveManagementName(String pattern) { 223 223 String uuid = UUID.randomUUID().toString(); 224 224 pattern = pattern.replaceFirst("#uuid#", uuid); 225 225 } 226 - return FilePathResolver.resolvePath(pattern); 226 + return SystemAndEnvPropertyResolver.resolveString(pattern); 227 227 } 228 228 229 229 @Override 28 .../java/org/apache/camel/util/FilePathResolver.java → ...ache/camel/util/SystemAndEnvPropertyResolver.java @@ -20,19 +20,19 @@ 20 20 import java.util.regex.Pattern; 21 21 22 22 /** 23 - * A resolver for file paths that supports resolving with system and environment properties. 23 + * A resolver for strings that supports resolving with system and environment properties. 24 24 */ 25 -public final class FilePathResolver { 25 +public final class SystemAndEnvPropertyResolver { 26 26 27 27 // must be non greedy patterns 28 28 private static final Pattern ENV_PATTERN = Pattern.compile("\\$\\{env:(.*?)\\}", Pattern.DOTALL); 29 29 private static final Pattern SYS_PATTERN = Pattern.compile("\\$\\{(.*?)\\}", Pattern.DOTALL); 30 30 31 - private FilePathResolver() { 31 + private SystemAndEnvPropertyResolver() { 32 32 } 33 33 34 34 /** 35 - * Resolves the path. 35 + * Resolves the string. 36 36 *

37 37 * The pattern is: 38 38 *

42 42 * For example: ${env.KARAF_HOME}/data/logs 43 43 * 44 - * @param path the path 45 - * @return the resolved path 44 + * @param s the string 45 + * @return the resolved string 46 46 * @throws IllegalArgumentException is thrown if system property / environment not found 47 47 */ 48 - public static String resolvePath(String path) throws IllegalArgumentException { 49 - Matcher matcher = ENV_PATTERN.matcher(path); 48 + public static String resolveString(String s) throws IllegalArgumentException { 49 + Matcher matcher = ENV_PATTERN.matcher(s); 50 50 while (matcher.find()) { 51 51 String key = matcher.group(1); 52 52 String value = System.getenv(key); @@ -55,12 +55,12 @@ public static String resolvePath(String path) throws IllegalArgumentException { 55 55 } 56 56 // must quote the replacement to have it work as literal replacement 57 57 value = Matcher.quoteReplacement(value); 58 - path = matcher.replaceFirst(value); 58 + s = matcher.replaceFirst(value); 59 59 // must match again as location is changed 60 - matcher = ENV_PATTERN.matcher(path); 60 + matcher = ENV_PATTERN.matcher(s); 61 61 } 62 62 63 - matcher = SYS_PATTERN.matcher(path); 63 + matcher = SYS_PATTERN.matcher(s); 64 64 while (matcher.find()) { 65 65 String key = matcher.group(1); 66 66 String value = System.getProperty(key); @@ -69,12 +69,12 @@ public static String resolvePath(String path) throws IllegalArgumentException { 69 69 } 70 70 // must quote the replacement to have it work as literal replacement 71 71 value = Matcher.quoteReplacement(value); 72 - path = matcher.replaceFirst(value); 72 + s = matcher.replaceFirst(value); 73 73 // must match again as location is changed 74 - matcher = SYS_PATTERN.matcher(path); 74 + matcher = SYS_PATTERN.matcher(s); 75 75 } 76 76 77 - return path; 77 + return s; 78 78 } 79 79 80 80 } core/src/test/java/org/apache/camel/component/properties/PropertiesComponentOverridePropertiesTest.java @@ -32,32 +32,38 @@ public boolean isUseRouteBuilder() { 32 32 return false; 33 33 } 34 34 35 - public void testPropertiesComponentEndpoint() throws Exception { 35 + public void testOverridingProperties() throws Exception { 36 + PropertiesComponent pc = new PropertiesComponent(); 37 + pc.setLocation("classpath:org/apache/camel/component/properties/myproperties.properties"); 38 + context.addComponent("properties", pc); 39 + 40 + Properties extra = new Properties(); 41 + extra.put("cool.result", "extra"); 42 + extra.put("hey", "mock:hey"); 43 + pc.setOverrideProperties(extra); 44 + 36 45 context.addRoutes(new RouteBuilder() { 37 46 @Override 38 47 public void configure() throws Exception { 39 48 from("direct:start") 40 - .to("{{hey}}") 41 - .to("mock:{{cool.result}}"); 49 + .to("{{hey}}") // new from override: mock:hey 50 + .to("mock:{{cool.result}}") // override mock:result -> mock:extra 51 + .to("{{cool.end}}"); // no override 42 52 } 43 53 }); 44 54 context.start(); 45 55 46 56 getMockEndpoint("mock:extra").expectedMessageCount(1); 47 57 getMockEndpoint("mock:hey").expectedMessageCount(1); 48 - getMockEndpoint("mock:result").expectedMessageCount(0); 58 + getMockEndpoint("mock:result").expectedMessageCount(1); 49 59 50 60 template.sendBody("direct:start", "Hello World"); 51 61 52 62 assertMockEndpointsSatisfied(); 53 63 } 54 64 55 - @Override 56 - protected CamelContext createCamelContext() throws Exception { 57 - CamelContext context = super.createCamelContext(); 58 - 65 + public void testOverridesOnly() throws Exception { 59 66 PropertiesComponent pc = new PropertiesComponent(); 60 - pc.setLocation("classpath:org/apache/camel/component/properties/myproperties.properties"); 61 67 context.addComponent("properties", pc); 62 68 63 69 Properties extra = new Properties(); @@ -65,7 +71,22 @@ protected CamelContext createCamelContext() throws Exception { 65 71 extra.put("hey", "mock:hey"); 66 72 pc.setOverrideProperties(extra); 67 73 68 - return context; 69 - } 74 + context.addRoutes(new RouteBuilder() { 75 + @Override 76 + public void configure() throws Exception { 77 + from("direct:start") 78 + .to("{{hey}}") // new from override: mock:hey 79 + .to("mock:{{cool.result}}"); // new from override: mock:extra 80 + } 81 + }); 82 + context.start(); 83 + 84 + getMockEndpoint("mock:extra").expectedMessageCount(1); 85 + getMockEndpoint("mock:hey").expectedMessageCount(1); 86 + getMockEndpoint("mock:result").expectedMessageCount(0); 70 87 88 + template.sendBody("direct:start", "Hello World"); 89 + 90 + assertMockEndpointsSatisfied(); 91 + } 71 92 } ...a/org/apache/camel/util/FilePathResolverTest.java → .../camel/util/SystemAndEnvPropertyResolverTest.java @@ -18,15 +18,15 @@ 18 18 19 19 import junit.framework.TestCase; 20 20 21 -public class FilePathResolverTest extends TestCase { 21 +public class SystemAndEnvPropertyResolverTest extends TestCase { 22 22 23 - public void testFilePathResolver() throws Exception { 24 - assertEquals("/foo/bar", FilePathResolver.resolvePath("/foo/bar")); 23 + public void testSystemAndEnvPropertyResolver() throws Exception { 24 + assertEquals("/foo/bar", SystemAndEnvPropertyResolver.resolveString("/foo/bar")); 25 25 26 26 String tmp = System.getProperty("java.io.tmpdir"); 27 - assertEquals(tmp + "foo", FilePathResolver.resolvePath("${java.io.tmpdir}foo")); 27 + assertEquals(tmp + "foo", SystemAndEnvPropertyResolver.resolveString("${java.io.tmpdir}foo")); 28 28 29 29 System.setProperty("beer", "Carlsberg"); 30 - assertEquals(tmp + "foo/Carlsberg", FilePathResolver.resolvePath("${java.io.tmpdir}foo/${beer}")); 30 + assertEquals(tmp + "foo/Carlsberg", SystemAndEnvPropertyResolver.resolveString("${java.io.tmpdir}foo/${beer}")); 31 31 } 32 32 }