This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch summary in repository https://gitbox.apache.org/repos/asf/camel.git
commit 367735e1ebf09b61de5f6d305cd6cbf04b11cb79 Author: Claus Ibsen <[email protected]> AuthorDate: Mon Mar 21 17:07:22 2022 +0100 CAMEL-17831: camel-main - Auto configuration summary (show from where the option was taken) --- .../component/properties/PropertiesComponent.java | 33 ++- .../org/apache/camel/main/BaseMainSupport.java | 284 ++++++++++++--------- .../java/org/apache/camel/main/MainHelper.java | 47 +++- .../camel/main/MainSupportModelConfigurer.java | 15 +- .../camel/util/OrderedLocationProperties.java | 71 ++++++ .../org/apache/camel/util/OrderedProperties.java | 12 +- .../apache/camel/dsl/modeline/DependencyTrait.java | 3 +- .../org/apache/camel/dsl/modeline/EnvTrait.java | 3 +- .../apache/camel/dsl/modeline/ModelineParser.java | 6 +- .../org/apache/camel/dsl/modeline/NameTrait.java | 3 +- .../apache/camel/dsl/modeline/PropertyTrait.java | 51 +++- .../java/org/apache/camel/dsl/modeline/Trait.java | 10 +- 12 files changed, 373 insertions(+), 165 deletions(-) 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 471e191..f4fe606 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 @@ -44,6 +44,7 @@ import org.apache.camel.support.service.ServiceHelper; import org.apache.camel.support.service.ServiceSupport; import org.apache.camel.util.FilePathResolver; import org.apache.camel.util.ObjectHelper; +import org.apache.camel.util.OrderedLocationProperties; import org.apache.camel.util.OrderedProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -180,11 +181,11 @@ public class PropertiesComponent extends ServiceSupport // this method may be replaced by loadProperties(k -> true) but the underlying sources // may have some optimization for bulk load so let's keep it - Properties prop = new OrderedProperties(); + OrderedLocationProperties prop = new OrderedLocationProperties(); // use initial properties if (initialProperties != null) { - prop.putAll(initialProperties); + prop.putAll("initial", initialProperties); } if (!sources.isEmpty()) { @@ -196,7 +197,14 @@ public class PropertiesComponent extends ServiceSupport if (ps instanceof LoadablePropertiesSource) { LoadablePropertiesSource lps = (LoadablePropertiesSource) ps; Properties p = lps.loadProperties(); - prop.putAll(p); + if (p instanceof OrderedLocationProperties) { + prop.putAll((OrderedLocationProperties) p); + } else if (ps instanceof LocationPropertiesSource) { + String loc = ((LocationPropertiesSource) ps).getLocation().getPath(); + prop.putAll(loc, p); + } else { + prop.putAll(lps.getName(), p); + } } } } @@ -204,9 +212,9 @@ public class PropertiesComponent extends ServiceSupport // use override properties if (overrideProperties != null) { // make a copy to avoid affecting the original properties - Properties override = new OrderedProperties(); + OrderedLocationProperties override = new OrderedLocationProperties(); override.putAll(prop); - override.putAll(overrideProperties); + override.putAll("override", overrideProperties); prop = override; } @@ -215,13 +223,13 @@ public class PropertiesComponent extends ServiceSupport @Override public Properties loadProperties(Predicate<String> filter) { - Properties prop = new OrderedProperties(); + OrderedLocationProperties prop = new OrderedLocationProperties(); // use initial properties if (initialProperties != null) { for (String name : initialProperties.stringPropertyNames()) { if (filter.test(name)) { - prop.put(name, initialProperties.get(name)); + prop.put("initial", name, initialProperties.get(name)); } } } @@ -235,7 +243,14 @@ public class PropertiesComponent extends ServiceSupport if (ps instanceof LoadablePropertiesSource) { LoadablePropertiesSource lps = (LoadablePropertiesSource) ps; Properties p = lps.loadProperties(filter); - prop.putAll(p); + if (p instanceof OrderedLocationProperties) { + prop.putAll((OrderedLocationProperties) p); + } else if (ps instanceof LocationPropertiesSource) { + String loc = ((LocationPropertiesSource) ps).getLocation().getPath(); + prop.putAll(loc, p); + } else { + prop.putAll(lps.getName(), p); + } } } } @@ -244,7 +259,7 @@ public class PropertiesComponent extends ServiceSupport if (overrideProperties != null) { for (String name : overrideProperties.stringPropertyNames()) { if (filter.test(name)) { - prop.put(name, overrideProperties.get(name)); + prop.put("override", name, overrideProperties.get(name)); } } } diff --git a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java index 078eb7c..8c45d14 100644 --- a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java +++ b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java @@ -63,8 +63,8 @@ import org.apache.camel.support.service.BaseService; import org.apache.camel.support.startup.LoggingStartupStepRecorder; import org.apache.camel.util.FileUtil; import org.apache.camel.util.ObjectHelper; +import org.apache.camel.util.OrderedLocationProperties; import org.apache.camel.util.OrderedProperties; -import org.apache.camel.util.PropertiesHelper; import org.apache.camel.util.SensitiveUtils; import org.apache.camel.util.StringHelper; import org.apache.camel.vault.VaultConfiguration; @@ -92,7 +92,7 @@ public abstract class BaseMainSupport extends BaseService { protected final List<MainListener> listeners = new ArrayList<>(); protected volatile CamelContext camelContext; protected MainConfigurationProperties mainConfigurationProperties = new MainConfigurationProperties(); - protected Properties wildcardProperties = new OrderedProperties(); + protected OrderedLocationProperties wildcardProperties = new OrderedLocationProperties(); protected RoutesCollector routesCollector = new DefaultRoutesCollector(); protected String propertyPlaceholderLocations; protected String defaultPropertyPlaceholderLocation = DEFAULT_PROPERTY_PLACEHOLDER_LOCATION; @@ -377,7 +377,7 @@ public abstract class BaseMainSupport extends BaseService { protected void autoconfigure(CamelContext camelContext) throws Exception { // gathers the properties (key=value) that was auto-configured - final Map<String, String> autoConfiguredProperties = new LinkedHashMap<>(); + final OrderedLocationProperties autoConfiguredProperties = new OrderedLocationProperties(); // need to eager allow to auto-configure properties component if (mainConfigurationProperties.isAutoConfigurationEnabled()) { @@ -407,13 +407,31 @@ public abstract class BaseMainSupport extends BaseService { // log summary of configurations if (mainConfigurationProperties.isAutoConfigurationLogSummary() && !autoConfiguredProperties.isEmpty()) { LOG.info("Auto-configuration summary"); - autoConfiguredProperties.forEach((k, v) -> { - if (SensitiveUtils.containsSensitive(k)) { - LOG.info(" {}=xxxxxx", k); + for (var entry : autoConfiguredProperties.entrySet()) { + Object k = entry.getKey(); + Object v = entry.getValue(); + + String loc = autoConfiguredProperties.getLocation(k); + if (loc == null) { + loc = ""; + } + // remove scheme to make it shorter + if (loc.contains(":")) { + loc = StringHelper.after(loc, ":"); + } + if (loc.length() > 28) { + int pos = loc.length() - 28; + loc = loc.substring(pos); + } + loc = "[" + loc + "]"; + loc = String.format("%-30s", loc); + + if (SensitiveUtils.containsSensitive(k.toString())) { + LOG.info(" {} {}=xxxxxx", loc, k); } else { - LOG.info(" {}={}", k, v); + LOG.info(" {} {}={}", loc, k, v); } - }); + } } // we are now done with the main helper during bootstrap @@ -598,10 +616,11 @@ public abstract class BaseMainSupport extends BaseService { } } - protected void autoConfigurationFailFast(CamelContext camelContext, Map<String, String> autoConfiguredProperties) + protected void autoConfigurationFailFast(CamelContext camelContext, OrderedLocationProperties autoConfiguredProperties) throws Exception { // load properties - Properties prop = camelContext.getPropertiesComponent().loadProperties(name -> name.startsWith("camel.")); + OrderedLocationProperties prop = (OrderedLocationProperties) camelContext.getPropertiesComponent() + .loadProperties(name -> name.startsWith("camel.")); LOG.debug("Properties from Camel properties component:"); for (String key : prop.stringPropertyNames()) { LOG.debug(" {}={}", key, prop.getProperty(key)); @@ -614,7 +633,8 @@ public abstract class BaseMainSupport extends BaseService { if (envEnabled != null) { mainConfigurationProperties.setAutoConfigurationEnvironmentVariablesEnabled( CamelContextHelper.parseBoolean(camelContext, envEnabled.toString())); - autoConfiguredProperties.put("camel.main.auto-configuration-environment-variables-enabled", + String loc = prop.getLocation("camel.main.auto-configuration-environment-variables-enabled"); + autoConfiguredProperties.put(loc, "camel.main.auto-configuration-environment-variables-enabled", envEnabled.toString()); } } @@ -625,7 +645,8 @@ public abstract class BaseMainSupport extends BaseService { if (jvmEnabled != null) { mainConfigurationProperties.setAutoConfigurationSystemPropertiesEnabled( CamelContextHelper.parseBoolean(camelContext, jvmEnabled.toString())); - autoConfiguredProperties.put("camel.main.auto-configuration-system-properties-enabled", + String loc = prop.getLocation("camel.main.auto-configuration-system-properties-enabled"); + autoConfiguredProperties.put(loc, "camel.main.auto-configuration-system-properties-enabled", jvmEnabled.toString()); } } @@ -656,68 +677,77 @@ public abstract class BaseMainSupport extends BaseService { } // special for fail-fast as we need to know this early before we set all the other options + String loc = "ENV"; Object failFast = propENV != null ? propENV.remove("camel.main.autoconfigurationfailfast") : null; if (propJVM != null) { Object val = propJVM.remove("camel.main.autoconfigurationfailfast"); if (val != null) { + loc = "SYS"; failFast = val; } } if (failFast != null) { mainConfigurationProperties .setAutoConfigurationFailFast(CamelContextHelper.parseBoolean(camelContext, failFast.toString())); - autoConfiguredProperties.put("camel.main.auto-configuration-fail-fast", failFast.toString()); + autoConfiguredProperties.put(loc, "camel.main.auto-configuration-fail-fast", failFast.toString()); } else { + loc = prop.getLocation("camel.main.autoConfigurationFailFast"); failFast = prop.remove("camel.main.autoConfigurationFailFast"); if (failFast == null) { failFast = prop.remove("camel.main.auto-configuration-fail-fast"); + loc = prop.getLocation("camel.main.auto-configuration-fail-fast"); } if (failFast != null) { mainConfigurationProperties .setAutoConfigurationFailFast(CamelContextHelper.parseBoolean(camelContext, failFast.toString())); - autoConfiguredProperties.put("camel.main.auto-configuration-fail-fast", failFast.toString()); + autoConfiguredProperties.put(loc, "camel.main.auto-configuration-fail-fast", failFast.toString()); } } } protected void autoConfigurationRoutesIncludePattern( - CamelContext camelContext, Map<String, String> autoConfiguredProperties) { + CamelContext camelContext, OrderedLocationProperties autoConfiguredProperties) { Object pattern = getInitialProperties().getProperty("camel.main.routesIncludePattern"); if (pattern != null) { mainConfigurationProperties .setRoutesIncludePattern(CamelContextHelper.parseText(camelContext, pattern.toString())); - autoConfiguredProperties.put("camel.main.routes-include-pattern", pattern.toString()); + autoConfiguredProperties.put("initial", "camel.main.routes-include-pattern", pattern.toString()); } // load properties - Properties prop = camelContext.getPropertiesComponent().loadProperties(name -> name.startsWith("camel.")); + OrderedLocationProperties prop = (OrderedLocationProperties) camelContext.getPropertiesComponent() + .loadProperties(name -> name.startsWith("camel.")); LOG.debug("Properties from Camel properties component:"); for (String key : prop.stringPropertyNames()) { LOG.debug(" {}={}", key, prop.getProperty(key)); } // special for environment-variable-enabled as we need to know this early before we set all the other options + String loc = prop.getLocation("camel.main.routesIncludePattern"); pattern = prop.remove("camel.main.routesIncludePattern"); if (pattern == null) { pattern = prop.remove("camel.main.routes-include-pattern"); - if (pattern != null) { - mainConfigurationProperties.setRoutesIncludePattern( - CamelContextHelper.parseText(camelContext, pattern.toString())); - autoConfiguredProperties.put("camel.main.routes-include-pattern", - pattern.toString()); - } + loc = prop.getLocation("camel.main.routesIncludePattern"); + } + if (pattern != null) { + mainConfigurationProperties.setRoutesIncludePattern( + CamelContextHelper.parseText(camelContext, pattern.toString())); + autoConfiguredProperties.put(loc, "camel.main.routes-include-pattern", + pattern.toString()); } // special for system-properties-enabled as we need to know this early before we set all the other options + loc = prop.getLocation("camel.main.routesIncludePattern"); Object jvmEnabled = prop.remove("camel.main.routesIncludePattern"); if (jvmEnabled == null) { + loc = prop.getLocation("camel.main.routes-include-pattern"); jvmEnabled = prop.remove("camel.main.routes-include-pattern"); - if (jvmEnabled != null) { - mainConfigurationProperties.setRoutesIncludePattern( - CamelContextHelper.parseText(camelContext, jvmEnabled.toString())); - autoConfiguredProperties.put("camel.main.routes-include-pattern", - jvmEnabled.toString()); - } + } + if (jvmEnabled != null) { + mainConfigurationProperties.setRoutesIncludePattern( + CamelContextHelper.parseText(camelContext, jvmEnabled.toString())); + autoConfiguredProperties.put(loc, "camel.main.routes-include-pattern", + jvmEnabled.toString()); } // load properties from ENV (override existing) @@ -725,7 +755,7 @@ public abstract class BaseMainSupport extends BaseService { if (mainConfigurationProperties.isAutoConfigurationEnvironmentVariablesEnabled()) { propENV = helper.loadEnvironmentVariablesAsProperties(new String[] { "camel.main." }); if (!propENV.isEmpty()) { - prop.putAll(propENV); + prop.putAll("ENV", propENV); LOG.debug("Properties from OS environment variables:"); for (String key : propENV.stringPropertyNames()) { LOG.debug(" {}={}", key, propENV.getProperty(key)); @@ -737,7 +767,7 @@ public abstract class BaseMainSupport extends BaseService { if (mainConfigurationProperties.isAutoConfigurationSystemPropertiesEnabled()) { propJVM = helper.loadJvmSystemPropertiesAsProperties(new String[] { "camel.main." }); if (!propJVM.isEmpty()) { - prop.putAll(propJVM); + prop.putAll("SYS", propJVM); LOG.debug("Properties from JVM system properties:"); for (String key : propJVM.stringPropertyNames()) { LOG.debug(" {}={}", key, propJVM.getProperty(key)); @@ -746,26 +776,30 @@ public abstract class BaseMainSupport extends BaseService { } // special for fail-fast as we need to know this early before we set all the other options + loc = "ENV"; pattern = propENV != null ? propENV.remove("camel.main.routesincludepattern") : null; if (propJVM != null) { Object val = propJVM.remove("camel.main.routesincludepattern"); if (val != null) { + loc = "SYS"; pattern = val; } } if (pattern != null) { mainConfigurationProperties .setRoutesIncludePattern(CamelContextHelper.parseText(camelContext, pattern.toString())); - autoConfiguredProperties.put("camel.main.routes-include-pattern", pattern.toString()); + autoConfiguredProperties.put(loc, "camel.main.routes-include-pattern", pattern.toString()); } else { + loc = prop.getLocation("camel.main.routesIncludePattern"); pattern = prop.remove("camel.main.routesIncludePattern"); if (pattern == null) { + loc = prop.getLocation("camel.main.routes-include-pattern"); pattern = prop.remove("camel.main.routes-include-pattern"); } if (pattern != null) { mainConfigurationProperties .setRoutesIncludePattern(CamelContextHelper.parseText(camelContext, pattern.toString())); - autoConfiguredProperties.put("camel.main.routes-include-pattern", pattern.toString()); + autoConfiguredProperties.put(loc, "camel.main.routes-include-pattern", pattern.toString()); } } } @@ -775,7 +809,7 @@ public abstract class BaseMainSupport extends BaseService { */ protected void doConfigureCamelContextFromMainConfiguration( CamelContext camelContext, MainConfigurationProperties config, - Map<String, String> autoConfiguredProperties) + OrderedLocationProperties autoConfiguredProperties) throws Exception { if (config.getFileConfigurations() != null) { @@ -813,13 +847,14 @@ public abstract class BaseMainSupport extends BaseService { DefaultConfigurationConfigurer.afterConfigure(camelContext); // now configure context/hystrix/resilience4j/rest with additional properties - Properties prop = camelContext.getPropertiesComponent().loadProperties(name -> name.startsWith("camel.")); + OrderedLocationProperties prop = (OrderedLocationProperties) camelContext.getPropertiesComponent() + .loadProperties(name -> name.startsWith("camel.")); // load properties from ENV (override existing) if (mainConfigurationProperties.isAutoConfigurationEnvironmentVariablesEnabled()) { Properties propENV = helper.loadEnvironmentVariablesAsProperties(new String[] { "camel.component.properties." }); if (!propENV.isEmpty()) { - prop.putAll(propENV); + prop.putAll("ENV", propENV); LOG.debug("Properties from OS environment variables:"); for (String key : propENV.stringPropertyNames()) { LOG.debug(" {}={}", key, propENV.getProperty(key)); @@ -830,7 +865,7 @@ public abstract class BaseMainSupport extends BaseService { if (mainConfigurationProperties.isAutoConfigurationSystemPropertiesEnabled()) { Properties propJVM = helper.loadJvmSystemPropertiesAsProperties(new String[] { "camel.component.properties." }); if (!propJVM.isEmpty()) { - prop.putAll(propJVM); + prop.putAll("SYS", propJVM); LOG.debug("Properties from JVM system properties:"); for (String key : propJVM.stringPropertyNames()) { LOG.debug(" {}={}", key, propJVM.getProperty(key)); @@ -838,104 +873,106 @@ public abstract class BaseMainSupport extends BaseService { } } - Map<String, Object> contextProperties = new LinkedHashMap<>(); - Map<String, Object> hystrixProperties = new LinkedHashMap<>(); - Map<String, Object> resilience4jProperties = new LinkedHashMap<>(); - Map<String, Object> faultToleranceProperties = new LinkedHashMap<>(); - Map<String, Object> restProperties = new LinkedHashMap<>(); - Map<String, Object> vaultProperties = new LinkedHashMap<>(); - Map<String, Object> threadPoolProperties = new LinkedHashMap<>(); - Map<String, Object> healthProperties = new LinkedHashMap<>(); - Map<String, Object> lraProperties = new LinkedHashMap<>(); - Map<String, Object> routeTemplateProperties = new LinkedHashMap<>(); - Map<String, Object> beansProperties = new LinkedHashMap<>(); - Map<String, Object> devConsoleProperties = new LinkedHashMap<>(); - Map<String, String> globalOptions = new LinkedHashMap<>(); + OrderedLocationProperties contextProperties = new OrderedLocationProperties(); + OrderedLocationProperties hystrixProperties = new OrderedLocationProperties(); + OrderedLocationProperties resilience4jProperties = new OrderedLocationProperties(); + OrderedLocationProperties faultToleranceProperties = new OrderedLocationProperties(); + OrderedLocationProperties restProperties = new OrderedLocationProperties(); + OrderedLocationProperties vaultProperties = new OrderedLocationProperties(); + OrderedLocationProperties threadPoolProperties = new OrderedLocationProperties(); + OrderedLocationProperties healthProperties = new OrderedLocationProperties(); + OrderedLocationProperties lraProperties = new OrderedLocationProperties(); + OrderedLocationProperties routeTemplateProperties = new OrderedLocationProperties(); + OrderedLocationProperties beansProperties = new OrderedLocationProperties(); + OrderedLocationProperties devConsoleProperties = new OrderedLocationProperties(); + OrderedLocationProperties globalOptions = new OrderedLocationProperties(); for (String key : prop.stringPropertyNames()) { + String loc = prop.getLocation(key); if (key.startsWith("camel.context.")) { // grab the value String value = prop.getProperty(key); String option = key.substring(14); validateOptionAndValue(key, option, value); - contextProperties.put(optionKey(option), value); + contextProperties.put(loc, optionKey(option), value); } else if (key.startsWith("camel.hystrix.")) { // grab the value String value = prop.getProperty(key); String option = key.substring(14); validateOptionAndValue(key, option, value); - hystrixProperties.put(optionKey(option), value); + hystrixProperties.put(loc, optionKey(option), value); } else if (key.startsWith("camel.resilience4j.")) { // grab the value String value = prop.getProperty(key); String option = key.substring(19); validateOptionAndValue(key, option, value); - resilience4jProperties.put(optionKey(option), value); + resilience4jProperties.put(loc, optionKey(option), value); } else if (key.startsWith("camel.faulttolerance.")) { // grab the value String value = prop.getProperty(key); String option = key.substring(21); validateOptionAndValue(key, option, value); - faultToleranceProperties.put(optionKey(option), value); + faultToleranceProperties.put(loc, optionKey(option), value); } else if (key.startsWith("camel.rest.")) { // grab the value String value = prop.getProperty(key); String option = key.substring(11); validateOptionAndValue(key, option, value); - restProperties.put(optionKey(option), value); + restProperties.put(loc, optionKey(option), value); } else if (key.startsWith("camel.vault.")) { // grab the value String value = prop.getProperty(key); String option = key.substring(12); validateOptionAndValue(key, option, value); - vaultProperties.put(optionKey(option), value); + vaultProperties.put(loc, optionKey(option), value); } else if (key.startsWith("camel.threadpool.")) { // grab the value String value = prop.getProperty(key); String option = key.substring(17); validateOptionAndValue(key, option, value); - threadPoolProperties.put(optionKey(option), value); + threadPoolProperties.put(loc, optionKey(option), value); } else if (key.startsWith("camel.health.")) { // grab the value String value = prop.getProperty(key); String option = key.substring(13); validateOptionAndValue(key, option, value); - healthProperties.put(optionKey(option), value); + healthProperties.put(loc, optionKey(option), value); } else if (key.startsWith("camel.lra.")) { // grab the value String value = prop.getProperty(key); String option = key.substring(10); validateOptionAndValue(key, option, value); - lraProperties.put(optionKey(option), value); + lraProperties.put(loc, optionKey(option), value); } else if (key.startsWith("camel.route-template")) { // grab the value String value = prop.getProperty(key); String option = key.substring(20); validateOptionAndValue(key, option, value); - routeTemplateProperties.put(optionKey(option), value); + routeTemplateProperties.put(loc, optionKey(option), value); } else if (key.startsWith("camel.dev-console.")) { // grab the value String value = prop.getProperty(key); String option = key.substring(18); validateOptionAndValue(key, option, value); - devConsoleProperties.put(optionKey(option), value); + devConsoleProperties.put(loc, optionKey(option), value); } else if (key.startsWith("camel.beans.")) { // grab the value String value = prop.getProperty(key); String option = key.substring(12); validateOptionAndValue(key, option, value); - beansProperties.put(optionKey(option), value); + beansProperties.put(loc, optionKey(option), value); } else if (key.startsWith("camel.global-options.")) { // grab the value String value = prop.getProperty(key); String option = key.substring(21); validateOptionAndValue(key, option, value); - globalOptions.put(optionKey(option), value); + globalOptions.put(loc, optionKey(option), value); } } // global options first if (!globalOptions.isEmpty()) { - mainConfigurationProperties.setGlobalOptions(globalOptions); + // TOOD + // mainConfigurationProperties.setGlobalOptions(globalOptions.asMap()); } // create beans first as they may be used later if (!beansProperties.isEmpty()) { @@ -1056,33 +1093,37 @@ public abstract class BaseMainSupport extends BaseService { // and call after all properties are set DefaultConfigurationConfigurer.afterPropertiesSet(camelContext); + + // TODO: record for each used configuration its source } private void setRouteTemplateProperties( - CamelContext camelContext, Map<String, Object> routeTemplateProperties, - boolean failIfNotSet, Map<String, String> autoConfiguredProperties) + CamelContext camelContext, OrderedLocationProperties routeTemplateProperties, + boolean failIfNotSet, OrderedLocationProperties autoConfiguredProperties) throws Exception { // store the route template parameters as a source and register it on the camel context PropertiesRouteTemplateParametersSource source = new PropertiesRouteTemplateParametersSource(); - for (Map.Entry<String, Object> entry : routeTemplateProperties.entrySet()) { - String id = StringHelper.between(entry.getKey(), "[", "]"); - String key = StringHelper.after(entry.getKey(), "]."); + for (Map.Entry<Object, Object> entry : routeTemplateProperties.entrySet()) { + String key = entry.getKey().toString(); + String id = StringHelper.between(key, "[", "]"); + key = StringHelper.after(key, "]."); source.addParameter(id, key, entry.getValue()); } camelContext.getRegistry().bind("CamelMainRouteTemplateParametersSource", RouteTemplateParameterSource.class, source); // lets sort by keys - Map<String, Object> sorted = new TreeMap<>(routeTemplateProperties); + Map<String, Object> sorted = new TreeMap<>(routeTemplateProperties.asMap()); sorted.forEach((k, v) -> { - autoConfiguredProperties.put("camel.route-template" + k, v.toString()); + String loc = routeTemplateProperties.getLocation(k); + autoConfiguredProperties.put(loc, "camel.route-template" + k, v.toString()); }); routeTemplateProperties.clear(); } private void setHealthCheckProperties( - CamelContext camelContext, Map<String, Object> healthCheckProperties, - boolean failIfNotSet, Map<String, String> autoConfiguredProperties) + CamelContext camelContext, OrderedLocationProperties healthCheckProperties, + boolean failIfNotSet, OrderedLocationProperties autoConfiguredProperties) throws Exception { HealthConfigurationProperties health = mainConfigurationProperties.health(); @@ -1156,13 +1197,14 @@ public abstract class BaseMainSupport extends BaseService { } private void setLraCheckProperties( - CamelContext camelContext, Map<String, Object> lraProperties, - boolean failIfNotSet, Map<String, String> autoConfiguredProperties) + CamelContext camelContext, OrderedLocationProperties lraProperties, + boolean failIfNotSet, OrderedLocationProperties autoConfiguredProperties) throws Exception { Object obj = lraProperties.remove("enabled"); if (obj != null) { - autoConfiguredProperties.put("camel.lra.enabled", obj.toString()); + String loc = lraProperties.getLocation("enabled"); + autoConfiguredProperties.put(loc, "camel.lra.enabled", obj.toString()); } boolean enabled = obj != null ? CamelContextHelper.parseBoolean(camelContext, obj.toString()) : true; if (enabled) { @@ -1172,12 +1214,12 @@ public abstract class BaseMainSupport extends BaseService { } private void setDevConsoleProperties( - CamelContext camelContext, Map<String, Object> properties, - boolean failIfNotSet, Map<String, String> autoConfiguredProperties) + CamelContext camelContext, OrderedLocationProperties properties, + boolean failIfNotSet, OrderedLocationProperties autoConfiguredProperties) throws Exception { // make defensive copy as we mutate the map - Set<String> keys = new LinkedHashSet<>(properties.keySet()); + Set<String> keys = new LinkedHashSet(properties.keySet()); // set properties per console for (String key : keys) { String name = StringHelper.before(key, "."); @@ -1187,15 +1229,15 @@ public abstract class BaseMainSupport extends BaseService { "Cannot resolve DevConsole with id: " + name); } // configure all the properties on the console at once (to ensure they are configured in right order) - Map<String, Object> config = PropertiesHelper.extractProperties(properties, name + "."); + OrderedLocationProperties config = MainHelper.extractProperties(properties, name + "."); setPropertiesOnTarget(camelContext, console, config, "camel.dev-console." + name + ".", failIfNotSet, true, autoConfiguredProperties); } } private void setVaultProperties( - CamelContext camelContext, Map<String, Object> properties, - boolean failIfNotSet, Map<String, String> autoConfiguredProperties) + CamelContext camelContext, OrderedLocationProperties properties, + boolean failIfNotSet, OrderedLocationProperties autoConfiguredProperties) throws Exception { if (mainConfigurationProperties.hasVaultConfiguration()) { @@ -1204,7 +1246,7 @@ public abstract class BaseMainSupport extends BaseService { VaultConfiguration target = camelContext.getVaultConfiguration(); // make defensive copy as we mutate the map - Set<String> keys = new LinkedHashSet<>(properties.keySet()); + Set<String> keys = new LinkedHashSet(properties.keySet()); // set properties per different vault component for (String key : keys) { String name = StringHelper.before(key, "."); @@ -1215,23 +1257,24 @@ public abstract class BaseMainSupport extends BaseService { target = target.gcp(); } // configure all the properties on the vault at once (to ensure they are configured in right order) - Map<String, Object> config = PropertiesHelper.extractProperties(properties, name + "."); + OrderedLocationProperties config = MainHelper.extractProperties(properties, name + "."); setPropertiesOnTarget(camelContext, target, config, "camel.vault." + name + ".", failIfNotSet, true, autoConfiguredProperties); } } private void bindBeansToRegistry( - CamelContext camelContext, Map<String, Object> properties, + CamelContext camelContext, OrderedLocationProperties properties, String optionPrefix, boolean failIfNotSet, boolean logSummary, boolean ignoreCase, - Map<String, String> autoConfiguredProperties) + OrderedLocationProperties autoConfiguredProperties) throws Exception { // make defensive copy as we mutate the map - Set<String> keys = new LinkedHashSet<>(properties.keySet()); + Set<String> keys = new LinkedHashSet(properties.keySet()); // find names of beans final Set<String> beans - = properties.keySet().stream().map(k -> StringHelper.before(k, ".", k)).collect(Collectors.toSet()); + = properties.keySet().stream().map(k -> StringHelper.before(k.toString(), ".", k.toString())) + .collect(Collectors.toSet()); // create beans first for (String key : keys) { if (key.indexOf('.') == -1) { @@ -1259,33 +1302,35 @@ public abstract class BaseMainSupport extends BaseService { "Cannot resolve bean with name " + name); } // configure all the properties on the bean at once (to ensure they are configured in right order) - Map<String, Object> config = PropertiesHelper.extractProperties(properties, name + "."); + OrderedLocationProperties config = MainHelper.extractProperties(properties, name + "."); setPropertiesOnTarget(camelContext, bean, config, optionPrefix + name + ".", failIfNotSet, ignoreCase, autoConfiguredProperties); } } - protected void autoConfigurationPropertiesComponent(CamelContext camelContext, Map<String, String> autoConfiguredProperties) + protected void autoConfigurationPropertiesComponent( + CamelContext camelContext, OrderedLocationProperties autoConfiguredProperties) throws Exception { // load properties - Properties prop = camelContext.getPropertiesComponent().loadProperties(name -> name.startsWith("camel.")); + OrderedLocationProperties prop = (OrderedLocationProperties) camelContext.getPropertiesComponent() + .loadProperties(name -> name.startsWith("camel.")); // load properties from ENV (override existing) if (mainConfigurationProperties.isAutoConfigurationEnvironmentVariablesEnabled()) { Properties propENV = helper.loadEnvironmentVariablesAsProperties(new String[] { "camel.component.properties." }); if (!propENV.isEmpty()) { - prop.putAll(propENV); + prop.putAll("ENV", propENV); } } // load properties from JVM (override existing) if (mainConfigurationProperties.isAutoConfigurationSystemPropertiesEnabled()) { Properties propJVM = helper.loadJvmSystemPropertiesAsProperties(new String[] { "camel.component.properties." }); if (!propJVM.isEmpty()) { - prop.putAll(propJVM); + prop.putAll("SYS", propJVM); } } - Map<String, Object> properties = new LinkedHashMap<>(); + OrderedLocationProperties properties = new OrderedLocationProperties(); for (String key : prop.stringPropertyNames()) { if (key.startsWith("camel.component.properties.")) { @@ -1293,7 +1338,8 @@ public abstract class BaseMainSupport extends BaseService { String option = dot == -1 ? "" : key.substring(dot + 1); String value = prop.getProperty(key, ""); validateOptionAndValue(key, option, value); - properties.put(optionKey(option), value); + String loc = prop.getLocation(key); + properties.put(loc, optionKey(option), value); } } @@ -1314,10 +1360,11 @@ public abstract class BaseMainSupport extends BaseService { } protected void autoConfigurationMainConfiguration( - CamelContext camelContext, MainConfigurationProperties config, Map<String, String> autoConfiguredProperties) + CamelContext camelContext, MainConfigurationProperties config, OrderedLocationProperties autoConfiguredProperties) throws Exception { // load properties - Properties prop = camelContext.getPropertiesComponent().loadProperties(name -> name.startsWith("camel.")); + OrderedLocationProperties prop = (OrderedLocationProperties) camelContext.getPropertiesComponent() + .loadProperties(name -> name.startsWith("camel.")); // load properties from ENV (override existing) if (mainConfigurationProperties.isAutoConfigurationEnvironmentVariablesEnabled()) { @@ -1328,7 +1375,7 @@ public abstract class BaseMainSupport extends BaseService { propENV.remove(OVERRIDE_PROPERTIES_LOCATION.replace('-', '.')); propENV.remove(PROPERTY_PLACEHOLDER_LOCATION.replace('-', '.')); if (!propENV.isEmpty()) { - prop.putAll(propENV); + prop.putAll("ENV", propENV); } } // load properties from JVM (override existing) @@ -1342,11 +1389,11 @@ public abstract class BaseMainSupport extends BaseService { propJVM.remove(PROPERTY_PLACEHOLDER_LOCATION); propJVM.remove(StringHelper.dashToCamelCase(PROPERTY_PLACEHOLDER_LOCATION)); if (!propJVM.isEmpty()) { - prop.putAll(propJVM); + prop.putAll("SYS", propJVM); } } - Map<String, Object> properties = new LinkedHashMap<>(); + OrderedLocationProperties properties = new OrderedLocationProperties(); for (String key : prop.stringPropertyNames()) { if (key.startsWith("camel.main.")) { @@ -1354,7 +1401,8 @@ public abstract class BaseMainSupport extends BaseService { String value = prop.getProperty(key); String option = key.substring(11); validateOptionAndValue(key, option, value); - properties.put(optionKey(option), value); + String loc = prop.getLocation(key); + properties.put(loc, optionKey(option), value); } } @@ -1372,12 +1420,14 @@ public abstract class BaseMainSupport extends BaseService { } } - protected void autoConfigurationFromProperties(CamelContext camelContext, Map<String, String> autoConfiguredProperties) + protected void autoConfigurationFromProperties( + CamelContext camelContext, OrderedLocationProperties autoConfiguredProperties) throws Exception { - Properties prop = new OrderedProperties(); + OrderedLocationProperties prop = new OrderedLocationProperties(); // load properties from properties component (override existing) - Properties propPC = camelContext.getPropertiesComponent().loadProperties(name -> name.startsWith("camel.")); + OrderedLocationProperties propPC = (OrderedLocationProperties) camelContext.getPropertiesComponent() + .loadProperties(name -> name.startsWith("camel.")); prop.putAll(propPC); // load properties from ENV (override existing) @@ -1401,7 +1451,7 @@ public abstract class BaseMainSupport extends BaseService { } if (!propENV.isEmpty()) { - prop.putAll(propENV); + prop.putAll("ENV", propENV); } } // load properties from JVM (override existing) @@ -1409,16 +1459,17 @@ public abstract class BaseMainSupport extends BaseService { Properties propJVM = MainHelper.loadJvmSystemPropertiesAsProperties( new String[] { "camel.component.", "camel.dataformat.", "camel.language." }); if (!propJVM.isEmpty()) { - prop.putAll(propJVM); + prop.putAll("SYS", propJVM); } } - Map<PropertyOptionKey, Map<String, Object>> properties = new LinkedHashMap<>(); + Map<PropertyOptionKey, OrderedLocationProperties> properties = new LinkedHashMap<>(); // filter out wildcard properties for (String key : prop.stringPropertyNames()) { if (key.contains("*")) { - wildcardProperties.put(key, prop.getProperty(key)); + String loc = prop.getLocation(key); + wildcardProperties.put(loc, key, prop.getProperty(key)); } } // and remove wildcards @@ -1467,7 +1518,7 @@ public abstract class BaseMainSupport extends BaseService { total); } - for (Map.Entry<PropertyOptionKey, Map<String, Object>> entry : properties.entrySet()) { + for (Map.Entry<PropertyOptionKey, OrderedLocationProperties> entry : properties.entrySet()) { setPropertiesOnTarget( camelContext, entry.getKey().getInstance(), @@ -1480,9 +1531,9 @@ public abstract class BaseMainSupport extends BaseService { // log which options was not set if (!properties.isEmpty()) { - for (Map.Entry<PropertyOptionKey, Map<String, Object>> entry : properties.entrySet()) { + for (Map.Entry<PropertyOptionKey, OrderedLocationProperties> entry : properties.entrySet()) { PropertyOptionKey pok = entry.getKey(); - Map<String, Object> values = entry.getValue(); + OrderedLocationProperties values = entry.getValue(); values.forEach((k, v) -> { String stringValue = v != null ? v.toString() : null; LOG.warn("Property ({}={}) not auto-configured with name: {} on bean: {} with value: {}", @@ -1490,6 +1541,8 @@ public abstract class BaseMainSupport extends BaseService { }); } } + + // TODO: summary of location } protected void autowireWildcardProperties(CamelContext camelContext) { @@ -1513,8 +1566,8 @@ public abstract class BaseMainSupport extends BaseService { } protected void doAutowireWildcardProperties(String name, Component component) { - Map<PropertyOptionKey, Map<String, Object>> properties = new LinkedHashMap<>(); - Map<String, String> autoConfiguredProperties = new LinkedHashMap<>(); + Map<PropertyOptionKey, OrderedLocationProperties> properties = new LinkedHashMap<>(); + OrderedLocationProperties autoConfiguredProperties = new OrderedLocationProperties(); String match = ("camel.component." + name).toLowerCase(Locale.ENGLISH); for (String key : wildcardProperties.stringPropertyNames()) { @@ -1526,7 +1579,7 @@ public abstract class BaseMainSupport extends BaseService { } try { - for (Map.Entry<PropertyOptionKey, Map<String, Object>> entry : properties.entrySet()) { + for (Map.Entry<PropertyOptionKey, OrderedLocationProperties> entry : properties.entrySet()) { setPropertiesOnTarget( camelContext, entry.getKey().getInstance(), @@ -1540,7 +1593,8 @@ public abstract class BaseMainSupport extends BaseService { if (mainConfigurationProperties.isAutoConfigurationLogSummary() && !autoConfiguredProperties.isEmpty()) { LOG.info("Auto-configuration component {} summary", name); autoConfiguredProperties.forEach((k, v) -> { - if (SensitiveUtils.containsSensitive(k)) { + // TOOD: summary + if (SensitiveUtils.containsSensitive(k.toString())) { LOG.info(" {}=xxxxxx", k); } else { LOG.info(" {}={}", k, v); diff --git a/core/camel-main/src/main/java/org/apache/camel/main/MainHelper.java b/core/camel-main/src/main/java/org/apache/camel/main/MainHelper.java index 05b100d..5b073d9 100644 --- a/core/camel-main/src/main/java/org/apache/camel/main/MainHelper.java +++ b/core/camel-main/src/main/java/org/apache/camel/main/MainHelper.java @@ -23,7 +23,6 @@ import java.io.InputStreamReader; import java.io.LineNumberReader; import java.util.HashMap; import java.util.HashSet; -import java.util.LinkedHashMap; import java.util.Locale; import java.util.Map; import java.util.Optional; @@ -41,6 +40,7 @@ import org.apache.camel.support.PropertyBindingSupport; import org.apache.camel.support.service.ServiceHelper; import org.apache.camel.util.IOHelper; import org.apache.camel.util.ObjectHelper; +import org.apache.camel.util.OrderedLocationProperties; import org.apache.camel.util.OrderedProperties; import org.apache.camel.util.StringHelper; import org.apache.camel.util.TimeUtils; @@ -280,9 +280,9 @@ public final class MainHelper { } public static boolean setPropertiesOnTarget( - CamelContext context, Object target, Map<String, Object> properties, + CamelContext context, Object target, OrderedLocationProperties properties, String optionPrefix, boolean failIfNotSet, boolean ignoreCase, - Map<String, String> autoConfiguredProperties) { + OrderedLocationProperties autoConfiguredProperties) { ObjectHelper.notNull(context, "context"); ObjectHelper.notNull(target, "target"); @@ -305,16 +305,17 @@ public final class MainHelper { try { // keep a reference of the original keys - Map<String, Object> backup = new LinkedHashMap<>(properties); + OrderedLocationProperties backup = new OrderedLocationProperties(); + backup.putAll(properties); rc = PropertyBindingSupport.build() .withMandatory(failIfNotSet) .withRemoveParameters(true) .withConfigurer(configurer) .withIgnoreCase(ignoreCase) - .bind(context, target, properties); + .bind(context, target, properties.asMap()); - for (Map.Entry<String, Object> entry : backup.entrySet()) { + for (Map.Entry<Object, Object> entry : backup.entrySet()) { if (entry.getValue() != null && !properties.containsKey(entry.getKey())) { String prefix = optionPrefix; if (prefix != null && !prefix.endsWith(".")) { @@ -322,7 +323,9 @@ public final class MainHelper { } LOG.debug("Configured property: {}{}={} on bean: {}", prefix, entry.getKey(), entry.getValue(), target); - autoConfiguredProperties.put(prefix + entry.getKey(), entry.getValue().toString()); + String loc = backup.getLocation(entry.getKey()); + String key = prefix + entry.getKey(); + autoConfiguredProperties.put(loc, key, entry.getValue()); } } } catch (PropertyBindingException e) { @@ -353,7 +356,8 @@ public final class MainHelper { } public static void computeProperties( - String keyPrefix, String key, Properties prop, Map<PropertyOptionKey, Map<String, Object>> properties, + String keyPrefix, String key, OrderedLocationProperties prop, + Map<PropertyOptionKey, OrderedLocationProperties> properties, Function<String, Iterable<Object>> supplier) { if (key.startsWith(keyPrefix)) { // grab name @@ -398,10 +402,11 @@ public final class MainHelper { Iterable<Object> targets = supplier.apply(name); for (Object target : targets) { PropertyOptionKey pok = new PropertyOptionKey(target, prefix); - Map<String, Object> values = properties.computeIfAbsent(pok, k -> new LinkedHashMap<>()); + OrderedLocationProperties values = properties.computeIfAbsent(pok, k -> new OrderedLocationProperties()); + String loc = prop.getLocation(key); // we ignore case for property keys (so we should store them in canonical style - values.put(optionKey(option), value); + values.put(loc, optionKey(option), value); } } } @@ -487,4 +492,26 @@ public final class MainHelper { return version; } + public static OrderedLocationProperties extractProperties(OrderedLocationProperties properties, String optionPrefix) { + if (properties == null) { + return new OrderedLocationProperties(); + } + OrderedLocationProperties rc = new OrderedLocationProperties(); + + Set<Object> toRemove = new HashSet<>(); + for (var entry : properties.entrySet()) { + String key = entry.getKey().toString(); + String loc = properties.getLocation(key); + if (key.startsWith(optionPrefix)) { + Object value = properties.get(key); + key = key.substring(optionPrefix.length()); + rc.put(loc, key, value); + toRemove.add(entry.getKey()); + } + } + toRemove.forEach(properties::remove); + + return rc; + } + } diff --git a/core/camel-main/src/main/java/org/apache/camel/main/MainSupportModelConfigurer.java b/core/camel-main/src/main/java/org/apache/camel/main/MainSupportModelConfigurer.java index 0c5ce12..e5c1549 100644 --- a/core/camel-main/src/main/java/org/apache/camel/main/MainSupportModelConfigurer.java +++ b/core/camel-main/src/main/java/org/apache/camel/main/MainSupportModelConfigurer.java @@ -26,6 +26,7 @@ import org.apache.camel.model.HystrixConfigurationDefinition; import org.apache.camel.model.ModelCamelContext; import org.apache.camel.model.Resilience4jConfigurationDefinition; import org.apache.camel.spi.ThreadPoolProfile; +import org.apache.camel.util.OrderedLocationProperties; import org.apache.camel.util.PropertiesHelper; import org.apache.camel.util.StringHelper; import org.slf4j.Logger; @@ -46,10 +47,10 @@ public final class MainSupportModelConfigurer { static void configureModelCamelContext( CamelContext camelContext, MainConfigurationProperties mainConfigurationProperties, - Map<String, String> autoConfiguredProperties, - Map<String, Object> hystrixProperties, - Map<String, Object> resilience4jProperties, - Map<String, Object> faultToleranceProperties) + OrderedLocationProperties autoConfiguredProperties, + OrderedLocationProperties hystrixProperties, + OrderedLocationProperties resilience4jProperties, + OrderedLocationProperties faultToleranceProperties) throws Exception { ModelCamelContext model = camelContext.adapt(ModelCamelContext.class); @@ -101,14 +102,14 @@ public final class MainSupportModelConfigurer { static void setThreadPoolProperties( CamelContext camelContext, MainConfigurationProperties mainConfigurationProperties, - Map<String, Object> threadPoolProperties, - boolean failIfNotSet, Map<String, String> autoConfiguredProperties) + OrderedLocationProperties threadPoolProperties, + boolean failIfNotSet, OrderedLocationProperties autoConfiguredProperties) throws Exception { ThreadPoolConfigurationProperties tp = mainConfigurationProperties.threadPool(); // extract all config to know their parent ids so we can set the values afterwards - Map<String, Object> hcConfig = PropertiesHelper.extractProperties(threadPoolProperties, "config", false); + Map<String, Object> hcConfig = PropertiesHelper.extractProperties(threadPoolProperties.asMap(), "config", false); Map<String, ThreadPoolProfileConfigurationProperties> tpConfigs = new HashMap<>(); // build set of configuration objects for (Map.Entry<String, Object> entry : hcConfig.entrySet()) { diff --git a/core/camel-util/src/main/java/org/apache/camel/util/OrderedLocationProperties.java b/core/camel-util/src/main/java/org/apache/camel/util/OrderedLocationProperties.java new file mode 100644 index 0000000..c8e54dd --- /dev/null +++ b/core/camel-util/src/main/java/org/apache/camel/util/OrderedLocationProperties.java @@ -0,0 +1,71 @@ +/* + * 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.util; + +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +/** + * An {@link OrderedProperties} that also keeps track from which location the properties are sourced from. + * + * This can be used to track all the various sources for configuration that a Camel application uses (properties file, + * ENV variables, hardcoded in java, spring-boot, quarkus, camel-k modeline, camel-yaml-dsl etc. + */ +public class OrderedLocationProperties extends OrderedProperties { + + private final Map<Object, String> locations = new HashMap<>(); + + public void put(String location, Object key, Object value) { + locations.put(key, location); + put(key, value); + } + + public void putAll(OrderedLocationProperties other) { + for (var entry : other.entrySet()) { + put(other.getLocation(entry.getKey()), entry.getKey(), entry.getValue()); + } + } + + public void putAll(String location, Map<Object, Object> map) { + for (var entry : map.entrySet()) { + put(location, entry.getKey(), entry.getValue()); + } + } + + public void putAll(String location, Properties properties) { + for (var entry : properties.entrySet()) { + put(location, entry.getKey(), entry.getValue()); + } + } + + public String getLocation(Object key) { + return locations.get(key); + } + + @Override + public synchronized void clear() { + locations.clear(); + super.clear(); + } + + @Override + public synchronized Object remove(Object key) { + locations.remove(key); + return super.remove(key); + } +} diff --git a/core/camel-util/src/main/java/org/apache/camel/util/OrderedProperties.java b/core/camel-util/src/main/java/org/apache/camel/util/OrderedProperties.java index 72fd937..9095812 100644 --- a/core/camel-util/src/main/java/org/apache/camel/util/OrderedProperties.java +++ b/core/camel-util/src/main/java/org/apache/camel/util/OrderedProperties.java @@ -33,13 +33,17 @@ import java.util.Vector; * been designed to provide the needed functionality. The complex logic for loading properties has been kept from the * JDK {@link Properties} class. */ -public final class OrderedProperties extends Properties { +public class OrderedProperties extends Properties { - private final Map<String, String> map = new LinkedHashMap<>(); + private final Map<String, Object> map = new LinkedHashMap<>(); public OrderedProperties() { } + public Map<String, Object> asMap() { + return map; + } + @Override public synchronized Object put(Object key, Object value) { return map.put(key.toString(), value.toString()); @@ -74,12 +78,12 @@ public final class OrderedProperties extends Properties { @Override public String getProperty(String key) { - return map.get(key); + return (String) map.get(key); } @Override public String getProperty(String key, String defaultValue) { - return map.getOrDefault(key, defaultValue); + return (String) map.getOrDefault(key, defaultValue); } @Override diff --git a/dsl/camel-dsl-modeline/src/main/java/org/apache/camel/dsl/modeline/DependencyTrait.java b/dsl/camel-dsl-modeline/src/main/java/org/apache/camel/dsl/modeline/DependencyTrait.java index 8d84d60..637215b 100644 --- a/dsl/camel-dsl-modeline/src/main/java/org/apache/camel/dsl/modeline/DependencyTrait.java +++ b/dsl/camel-dsl-modeline/src/main/java/org/apache/camel/dsl/modeline/DependencyTrait.java @@ -19,6 +19,7 @@ package org.apache.camel.dsl.modeline; import org.apache.camel.CamelContext; import org.apache.camel.spi.CamelContextCustomizer; import org.apache.camel.spi.DependencyStrategy; +import org.apache.camel.spi.Resource; public class DependencyTrait implements Trait { @@ -28,7 +29,7 @@ public class DependencyTrait implements Trait { } @Override - public CamelContextCustomizer parseTrait(String trait) { + public CamelContextCustomizer parseTrait(Resource resource, String trait) { return new CamelContextCustomizer() { @Override public void configure(CamelContext camelContext) { diff --git a/dsl/camel-dsl-modeline/src/main/java/org/apache/camel/dsl/modeline/EnvTrait.java b/dsl/camel-dsl-modeline/src/main/java/org/apache/camel/dsl/modeline/EnvTrait.java index a8ac66b..cf7645d 100644 --- a/dsl/camel-dsl-modeline/src/main/java/org/apache/camel/dsl/modeline/EnvTrait.java +++ b/dsl/camel-dsl-modeline/src/main/java/org/apache/camel/dsl/modeline/EnvTrait.java @@ -18,6 +18,7 @@ package org.apache.camel.dsl.modeline; import org.apache.camel.CamelContext; import org.apache.camel.spi.CamelContextCustomizer; +import org.apache.camel.spi.Resource; import org.apache.camel.util.StringHelper; public class EnvTrait implements Trait { @@ -28,7 +29,7 @@ public class EnvTrait implements Trait { } @Override - public CamelContextCustomizer parseTrait(String trait) { + public CamelContextCustomizer parseTrait(Resource resource, String trait) { String key = StringHelper.before(trait, "=").trim(); String value = StringHelper.after(trait, "=").trim(); return new CamelContextCustomizer() { diff --git a/dsl/camel-dsl-modeline/src/main/java/org/apache/camel/dsl/modeline/ModelineParser.java b/dsl/camel-dsl-modeline/src/main/java/org/apache/camel/dsl/modeline/ModelineParser.java index cd1b8d7..3345400 100644 --- a/dsl/camel-dsl-modeline/src/main/java/org/apache/camel/dsl/modeline/ModelineParser.java +++ b/dsl/camel-dsl-modeline/src/main/java/org/apache/camel/dsl/modeline/ModelineParser.java @@ -59,7 +59,7 @@ public class ModelineParser { try (LineNumberReader reader = new LineNumberReader(resource.getReader())) { String line = reader.readLine(); while (line != null) { - List<CamelContextCustomizer> list = parse(line); + List<CamelContextCustomizer> list = parse(resource, line); answer.addAll(list); line = reader.readLine(); } @@ -68,7 +68,7 @@ public class ModelineParser { return answer; } - protected List<CamelContextCustomizer> parse(String line) { + protected List<CamelContextCustomizer> parse(Resource resource, String line) { if (!isModeline(line)) { return Collections.emptyList(); } @@ -86,7 +86,7 @@ public class ModelineParser { String value = StringHelper.after(part, "="); Trait trait = traits.get(name); if (trait != null) { - CamelContextCustomizer customizer = trait.parseTrait(value); + CamelContextCustomizer customizer = trait.parseTrait(resource, value); if (customizer != null) { answer.add(customizer); } diff --git a/dsl/camel-dsl-modeline/src/main/java/org/apache/camel/dsl/modeline/NameTrait.java b/dsl/camel-dsl-modeline/src/main/java/org/apache/camel/dsl/modeline/NameTrait.java index ae93e8d..d59adb7 100644 --- a/dsl/camel-dsl-modeline/src/main/java/org/apache/camel/dsl/modeline/NameTrait.java +++ b/dsl/camel-dsl-modeline/src/main/java/org/apache/camel/dsl/modeline/NameTrait.java @@ -19,6 +19,7 @@ package org.apache.camel.dsl.modeline; import org.apache.camel.CamelContext; import org.apache.camel.ExtendedCamelContext; import org.apache.camel.spi.CamelContextCustomizer; +import org.apache.camel.spi.Resource; public class NameTrait implements Trait { @@ -28,7 +29,7 @@ public class NameTrait implements Trait { } @Override - public CamelContextCustomizer parseTrait(String trait) { + public CamelContextCustomizer parseTrait(Resource resource, String trait) { return new CamelContextCustomizer() { @Override public void configure(CamelContext camelContext) { diff --git a/dsl/camel-dsl-modeline/src/main/java/org/apache/camel/dsl/modeline/PropertyTrait.java b/dsl/camel-dsl-modeline/src/main/java/org/apache/camel/dsl/modeline/PropertyTrait.java index 68f2f49..7a03db0 100644 --- a/dsl/camel-dsl-modeline/src/main/java/org/apache/camel/dsl/modeline/PropertyTrait.java +++ b/dsl/camel-dsl-modeline/src/main/java/org/apache/camel/dsl/modeline/PropertyTrait.java @@ -18,15 +18,17 @@ package org.apache.camel.dsl.modeline; import java.io.InputStream; import java.util.Properties; +import java.util.function.Predicate; import org.apache.camel.CamelContext; import org.apache.camel.CamelContextAware; import org.apache.camel.spi.CamelContextCustomizer; -import org.apache.camel.spi.PropertiesComponent; +import org.apache.camel.spi.LoadablePropertiesSource; import org.apache.camel.spi.PropertiesSource; +import org.apache.camel.spi.Resource; import org.apache.camel.spi.annotations.JdkService; import org.apache.camel.support.ResourceHelper; -import org.apache.camel.util.OrderedProperties; +import org.apache.camel.util.OrderedLocationProperties; import org.apache.camel.util.StringHelper; /** @@ -34,11 +36,10 @@ import org.apache.camel.util.StringHelper; * property values. */ @JdkService("properties-source-factory") -public class PropertyTrait implements Trait, PropertiesSource, CamelContextAware { +public class PropertyTrait implements Trait, LoadablePropertiesSource, CamelContextAware { - private final Properties properties = new OrderedProperties(); + private final OrderedLocationProperties properties = new OrderedLocationProperties(); private CamelContext camelContext; - private PropertiesComponent pc; @Override public CamelContext getCamelContext() { @@ -61,11 +62,11 @@ public class PropertyTrait implements Trait, PropertiesSource, CamelContextAware } @Override - public CamelContextCustomizer parseTrait(String trait) { + public CamelContextCustomizer parseTrait(Resource resource, String trait) { if (trait.contains("=")) { String key = StringHelper.before(trait, "=").trim(); String value = StringHelper.after(trait, "=").trim(); - setProperty(key, value); + setProperty(resource, key, value); } else { if (ResourceHelper.hasScheme(trait)) { // it is a properties file so load resource @@ -76,7 +77,7 @@ public class PropertyTrait implements Trait, PropertiesSource, CamelContextAware String v = prop.getProperty(k); String key = k.trim(); String value = v.trim(); - setProperty(key, value); + setProperty(resource, key, value); } } catch (Exception e) { // ignore @@ -86,12 +87,42 @@ public class PropertyTrait implements Trait, PropertiesSource, CamelContextAware return null; } - protected void setProperty(String key, String value) { - properties.setProperty(key, value); + protected void setProperty(Resource resource, String key, String value) { + String loc = resource.getLocation(); + properties.put(loc, key, value); + + /* if (!camelContext.isStarted()) { // if we are bootstrapping then also set as initial property, so it can be used there as well + // TODO: source location from resource + // TODO: loadable properties source + String loc = resource.getLocation(); camelContext.getPropertiesComponent().addInitialProperty(key, value); } + */ + } + + @Override + public Properties loadProperties() { + return properties; + } + + @Override + public Properties loadProperties(Predicate<String> filter) { + OrderedLocationProperties answer = new OrderedLocationProperties(); + + for (String name : properties.stringPropertyNames()) { + if (filter.test(name)) { + answer.put(properties.getLocation(name), name, properties.get(name)); + } + } + + return answer; + } + + @Override + public void reloadProperties(String location) { + // noop } @Override diff --git a/dsl/camel-dsl-modeline/src/main/java/org/apache/camel/dsl/modeline/Trait.java b/dsl/camel-dsl-modeline/src/main/java/org/apache/camel/dsl/modeline/Trait.java index 77f893c..93473fc 100644 --- a/dsl/camel-dsl-modeline/src/main/java/org/apache/camel/dsl/modeline/Trait.java +++ b/dsl/camel-dsl-modeline/src/main/java/org/apache/camel/dsl/modeline/Trait.java @@ -17,6 +17,7 @@ package org.apache.camel.dsl.modeline; import org.apache.camel.spi.CamelContextCustomizer; +import org.apache.camel.spi.Resource; /** * modeline trait @@ -27,10 +28,11 @@ public interface Trait { /** * Parses the trait - * - * @param trait the trait - * @return a customizer if the trait is accepted, otherwise null is returned + * + * @param resource the source + * @param trait the trait + * @return a customizer if the trait is accepted, otherwise null is returned */ - CamelContextCustomizer parseTrait(String trait); + CamelContextCustomizer parseTrait(Resource resource, String trait); }
