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
The following commit(s) were added to refs/heads/master by this push: new ef510b0 Improve BaseMainSupport (#4388) ef510b0 is described below commit ef510b0d3781ec8acd92ff35d316720be6a276d3 Author: Luca Burgazzoli <lburgazz...@users.noreply.github.com> AuthorDate: Thu Oct 8 06:46:41 2020 +0200 Improve BaseMainSupport (#4388) * main: move ProducerTemplate handling from BaseMainSupport to MainSupport * main: add support for setting initial/override properties from Map * main: move createCamelContext from BaseMainSupport to MainSupport * main: move static utility methods to MainHelper to declutter BaseMainSupport --- .../org/apache/camel/main/BaseMainSupport.java | 283 ++------------------- .../java/org/apache/camel/main/MainHelper.java | 218 ++++++++++++++++ .../java/org/apache/camel/main/MainSupport.java | 32 ++- .../org/apache/camel/main/PropertyOptionKey.java | 57 +++++ .../camel/main/MainPropertyPlaceholderTest.java | 20 ++ 5 files changed, 346 insertions(+), 264 deletions(-) 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 ffc5350..dff69bd 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 @@ -34,15 +34,12 @@ import java.util.Optional; import java.util.Properties; import java.util.Set; import java.util.TreeMap; -import java.util.function.Function; import java.util.stream.Collectors; import org.apache.camel.CamelContext; import org.apache.camel.Component; import org.apache.camel.ExtendedCamelContext; import org.apache.camel.NoSuchLanguageException; -import org.apache.camel.ProducerTemplate; -import org.apache.camel.PropertyBindingException; import org.apache.camel.RoutesBuilder; import org.apache.camel.RuntimeCamelException; import org.apache.camel.builder.ThreadPoolProfileBuilder; @@ -61,8 +58,6 @@ import org.apache.camel.spi.CamelBeanPostProcessor; import org.apache.camel.spi.DataFormat; import org.apache.camel.spi.Language; import org.apache.camel.spi.PropertiesComponent; -import org.apache.camel.spi.PropertyConfigurer; -import org.apache.camel.spi.PropertyConfigurerGetter; import org.apache.camel.spi.RouteTemplateParameterSource; import org.apache.camel.spi.ThreadPoolProfile; import org.apache.camel.support.CamelContextHelper; @@ -70,7 +65,6 @@ import org.apache.camel.support.LifecycleStrategySupport; import org.apache.camel.support.PropertyBindingSupport; import org.apache.camel.support.ResourceHelper; import org.apache.camel.support.service.BaseService; -import org.apache.camel.support.service.ServiceHelper; import org.apache.camel.util.FileUtil; import org.apache.camel.util.IOHelper; import org.apache.camel.util.ObjectHelper; @@ -80,8 +74,12 @@ import org.apache.camel.util.StringHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static org.apache.camel.main.MainHelper.computeProperties; import static org.apache.camel.main.MainHelper.loadEnvironmentVariablesAsProperties; import static org.apache.camel.main.MainHelper.lookupPropertyFromSysOrEnv; +import static org.apache.camel.main.MainHelper.optionKey; +import static org.apache.camel.main.MainHelper.setPropertiesOnTarget; +import static org.apache.camel.main.MainHelper.validateOptionAndValue; import static org.apache.camel.support.ObjectHelper.invokeMethod; import static org.apache.camel.util.ReflectionHelper.findMethod; import static org.apache.camel.util.StringHelper.matches; @@ -101,7 +99,6 @@ public abstract class BaseMainSupport extends BaseService { = "passphrase|password|secretkey|accesstoken|clientsecret|authorizationtoken|sasljaasconfig"; protected volatile CamelContext camelContext; - protected volatile ProducerTemplate camelTemplate; protected final List<MainListener> listeners = new ArrayList<>(); protected final MainConfigurationProperties mainConfigurationProperties = new MainConfigurationProperties(); @@ -112,127 +109,11 @@ public abstract class BaseMainSupport extends BaseService { protected Properties initialProperties; protected Properties overrideProperties; - protected static String optionKey(String key) { - // as we ignore case for property names we should use keys in same case and without dashes - key = StringHelper.dashToCamelCase(key); - return key; + protected BaseMainSupport() { } - protected static boolean setPropertiesOnTarget(CamelContext context, Object target, Object source) throws Exception { - ObjectHelper.notNull(context, "context"); - ObjectHelper.notNull(target, "target"); - - boolean rc = false; - - PropertyConfigurer targetConfigurer = null; - if (target instanceof Component) { - // the component needs to be initialized to have the configurer ready - ServiceHelper.initService(target); - targetConfigurer = ((Component) target).getComponentPropertyConfigurer(); - } - if (targetConfigurer == null) { - String name = target.getClass().getName(); - // see if there is a configurer for it - targetConfigurer = context.adapt(ExtendedCamelContext.class) - .getConfigurerResolver().resolvePropertyConfigurer(name, context); - } - - PropertyConfigurer sourceConfigurer = null; - if (source instanceof Component) { - // the component needs to be initialized to have the configurer ready - ServiceHelper.initService(source); - sourceConfigurer = ((Component) source).getComponentPropertyConfigurer(); - } - if (sourceConfigurer == null) { - String name = source.getClass().getName(); - // see if there is a configurer for it - sourceConfigurer = context.adapt(ExtendedCamelContext.class) - .getConfigurerResolver().resolvePropertyConfigurer(name, context); - } - - if (targetConfigurer != null && sourceConfigurer instanceof PropertyConfigurerGetter) { - PropertyConfigurerGetter getter = (PropertyConfigurerGetter) sourceConfigurer; - for (String key : getter.getAllOptions(source).keySet()) { - Object value = getter.getOptionValue(source, key, true); - if (value != null) { - rc |= targetConfigurer.configure(context, target, key, value, true); - } - } - } - return rc; - } - - protected static boolean setPropertiesOnTarget( - CamelContext context, Object target, Map<String, Object> properties, - String optionPrefix, boolean failIfNotSet, boolean ignoreCase, - Map<String, String> autoConfiguredProperties) - throws Exception { - ObjectHelper.notNull(context, "context"); - ObjectHelper.notNull(target, "target"); - ObjectHelper.notNull(properties, "properties"); - - boolean rc = false; - PropertyConfigurer configurer = null; - if (target instanceof Component) { - // the component needs to be initialized to have the configurer ready - ServiceHelper.initService(target); - configurer = ((Component) target).getComponentPropertyConfigurer(); - } - - if (configurer == null) { - String name = target.getClass().getName(); - // see if there is a configurer for it - configurer = context.adapt(ExtendedCamelContext.class) - .getConfigurerResolver().resolvePropertyConfigurer(name, context); - } - - try { - // keep a reference of the original keys - Map<String, Object> backup = new LinkedHashMap<>(properties); - - rc = PropertyBindingSupport.build() - .withMandatory(failIfNotSet) - .withRemoveParameters(true) - .withConfigurer(configurer) - .withIgnoreCase(ignoreCase) - .bind(context, target, properties); - - for (Map.Entry<String, Object> entry : backup.entrySet()) { - if (entry.getValue() != null && !properties.containsKey(entry.getKey())) { - String prefix = optionPrefix; - if (prefix != null && !prefix.endsWith(".")) { - prefix = "." + prefix; - } - - LOG.debug("Configured property: {}{}={} on bean: {}", prefix, entry.getKey(), entry.getValue(), target); - autoConfiguredProperties.put(prefix + entry.getKey(), entry.getValue().toString()); - } - } - } catch (PropertyBindingException e) { - String key = e.getOptionKey(); - if (key == null) { - String prefix = e.getOptionPrefix(); - if (prefix != null && !prefix.endsWith(".")) { - prefix = "." + prefix; - } - - key = prefix != null - ? prefix + "." + e.getPropertyName() - : e.getPropertyName(); - } - - if (failIfNotSet) { - // enrich the error with more precise details with option prefix and key - throw new PropertyBindingException( - e.getTarget(), e.getPropertyName(), e.getValue(), optionPrefix, key, e.getCause()); - } else { - LOG.debug("Error configuring property (" + key + ") with name: " + e.getPropertyName() + ") on bean: " + target - + " with value: " + e.getValue() + ". This exception is ignored as failIfNotSet=false.", - e); - } - } - - return rc; + protected BaseMainSupport(CamelContext camelContext) { + this.camelContext = camelContext; } /** @@ -297,7 +178,7 @@ public abstract class BaseMainSupport extends BaseService { * {@link org.apache.camel.BindToRegistry} annotation style. * <p/> * This option is default enabled. - * + * * @deprecated use {@link #configure()} */ @Deprecated @@ -317,6 +198,14 @@ public abstract class BaseMainSupport extends BaseService { } /** + * Sets initial properties for the properties component, which will be used before any locations are resolved. + */ + public void setInitialProperties(Map<String, Object> initialProperties) { + this.initialProperties = new OrderedProperties(); + this.initialProperties.putAll(initialProperties); + } + + /** * Adds a property (initial) for the properties component, which will be used before any locations are resolved. * * @param key the property key @@ -354,6 +243,14 @@ public abstract class BaseMainSupport extends BaseService { } /** + * Sets a special list of override properties that take precedence and will use first, if a property exist. + */ + public void setOverrideProperties(Map<String, Object> initialProperties) { + this.overrideProperties = new OrderedProperties(); + this.overrideProperties.putAll(initialProperties); + } + + /** * Adds an override property that take precedence and will use first, if a property exist. * * @param key the property key @@ -396,25 +293,6 @@ public abstract class BaseMainSupport extends BaseService { return answer; } - public ProducerTemplate getCamelTemplate() throws Exception { - if (camelTemplate == null) { - camelTemplate = findOrCreateCamelTemplate(); - } - return camelTemplate; - } - - protected abstract ProducerTemplate findOrCreateCamelTemplate(); - - protected abstract CamelContext createCamelContext(); - - protected void initCamelContext() throws Exception { - camelContext = createCamelContext(); - if (camelContext == null) { - throw new IllegalStateException("Created CamelContext is null"); - } - postProcessCamelContext(camelContext); - } - protected void loadRouteBuilders(CamelContext camelContext) throws Exception { // lets use Camel's bean post processor on any existing route builder classes // so the instance has some support for dependency injection @@ -1500,117 +1378,4 @@ public abstract class BaseMainSupport extends BaseService { } } - protected static void validateOptionAndValue(String key, String option, String value) { - if (ObjectHelper.isEmpty(option)) { - throw new IllegalArgumentException("Error configuring property: " + key + " because option is empty"); - } - if (ObjectHelper.isEmpty(value)) { - throw new IllegalArgumentException("Error configuring property: " + key + " because value is empty"); - } - } - - private static final class PropertyOptionKey { - private final Object instance; - private final String optionPrefix; - - private PropertyOptionKey(Object instance, String optionPrefix) { - this.instance = ObjectHelper.notNull(instance, "instance"); - this.optionPrefix = ObjectHelper.notNull(optionPrefix, "optionPrefix"); - } - - public Object getInstance() { - return instance; - } - - public String getOptionPrefix() { - return optionPrefix; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof PropertyOptionKey)) { - return false; - } - PropertyOptionKey key = (PropertyOptionKey) o; - return Objects.equals(instance, key.instance) - && Objects.equals(optionPrefix, key.optionPrefix); - } - - @Override - public int hashCode() { - return Objects.hash(instance, optionPrefix); - } - } - - protected static void computeProperties( - String keyPrefix, String key, Properties prop, Map<PropertyOptionKey, Map<String, Object>> properties, - Function<String, Iterable<Object>> supplier) { - if (key.startsWith(keyPrefix)) { - // grab name - final int dot = key.indexOf('.', keyPrefix.length()); - final String name = dot == -1 ? key.substring(keyPrefix.length()) : key.substring(keyPrefix.length(), dot); - - // enabled is a virtual property - if ("enabled".equals(name)) { - return; - } - // skip properties as its already keyPrefix earlier - if ("properties".equals(name)) { - return; - } - - // determine if the service is enabled or not by taking into account two options: - // - // 1. ${keyPrefix}.enabled = true|false - // 2. ${keyPrefix}.${name}.enabled = true|false - // - // The option [2] has the higher priority so as example: - // - // camel.component.enabled = false - // camel.component.seda.enabled = true - // - // enables auto configuration of the seda component only - if (!isServiceEnabled(keyPrefix, name, prop)) { - return; - } - - String prefix = dot == -1 ? "" : key.substring(0, dot + 1); - String option = dot == -1 ? "" : key.substring(dot + 1); - String value = prop.getProperty(key, ""); - - // enabled is a virtual property - if ("enabled".equalsIgnoreCase(option)) { - return; - } - - validateOptionAndValue(key, option, value); - - 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<>()); - - // we ignore case for property keys (so we should store them in canonical style - values.put(optionKey(option), value); - } - } - } - - protected static boolean isServiceEnabled(String prefix, String name, Properties properties) { - ObjectHelper.notNull(prefix, "prefix"); - ObjectHelper.notNull(name, "name"); - ObjectHelper.notNull(properties, "properties"); - - if (!prefix.endsWith(".")) { - prefix = prefix + "."; - } - - final String group = properties.getProperty(prefix + "enabled", "true"); - final String item = properties.getProperty(prefix + name + ".enabled", group); - - return Boolean.parseBoolean(item); - } } 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 a8ff18e..7c1fe8f 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 @@ -16,13 +16,30 @@ */ package org.apache.camel.main; +import java.util.LinkedHashMap; import java.util.Locale; +import java.util.Map; import java.util.Optional; import java.util.Properties; +import java.util.function.Function; +import org.apache.camel.CamelContext; +import org.apache.camel.Component; +import org.apache.camel.ExtendedCamelContext; +import org.apache.camel.PropertyBindingException; +import org.apache.camel.spi.PropertyConfigurer; +import org.apache.camel.spi.PropertyConfigurerGetter; +import org.apache.camel.support.PropertyBindingSupport; +import org.apache.camel.support.service.ServiceHelper; +import org.apache.camel.util.ObjectHelper; import org.apache.camel.util.OrderedProperties; +import org.apache.camel.util.StringHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public final class MainHelper { + private static final Logger LOG = LoggerFactory.getLogger(MainHelper.class); + private MainHelper() { } @@ -60,4 +77,205 @@ public final class MainHelper { return answer; } + public static String optionKey(String key) { + // as we ignore case for property names we should use keys in same case and without dashes + key = StringHelper.dashToCamelCase(key); + return key; + } + + public static boolean setPropertiesOnTarget(CamelContext context, Object target, Object source) throws Exception { + ObjectHelper.notNull(context, "context"); + ObjectHelper.notNull(target, "target"); + + boolean rc = false; + + PropertyConfigurer targetConfigurer = null; + if (target instanceof Component) { + // the component needs to be initialized to have the configurer ready + ServiceHelper.initService(target); + targetConfigurer = ((Component) target).getComponentPropertyConfigurer(); + } + if (targetConfigurer == null) { + String name = target.getClass().getName(); + // see if there is a configurer for it + targetConfigurer = context.adapt(ExtendedCamelContext.class) + .getConfigurerResolver().resolvePropertyConfigurer(name, context); + } + + PropertyConfigurer sourceConfigurer = null; + if (source instanceof Component) { + // the component needs to be initialized to have the configurer ready + ServiceHelper.initService(source); + sourceConfigurer = ((Component) source).getComponentPropertyConfigurer(); + } + if (sourceConfigurer == null) { + String name = source.getClass().getName(); + // see if there is a configurer for it + sourceConfigurer = context.adapt(ExtendedCamelContext.class) + .getConfigurerResolver().resolvePropertyConfigurer(name, context); + } + + if (targetConfigurer != null && sourceConfigurer instanceof PropertyConfigurerGetter) { + PropertyConfigurerGetter getter = (PropertyConfigurerGetter) sourceConfigurer; + for (String key : getter.getAllOptions(source).keySet()) { + Object value = getter.getOptionValue(source, key, true); + if (value != null) { + rc |= targetConfigurer.configure(context, target, key, value, true); + } + } + } + return rc; + } + + public static boolean setPropertiesOnTarget( + CamelContext context, Object target, Map<String, Object> properties, + String optionPrefix, boolean failIfNotSet, boolean ignoreCase, + Map<String, String> autoConfiguredProperties) { + + ObjectHelper.notNull(context, "context"); + ObjectHelper.notNull(target, "target"); + ObjectHelper.notNull(properties, "properties"); + + boolean rc = false; + PropertyConfigurer configurer = null; + if (target instanceof Component) { + // the component needs to be initialized to have the configurer ready + ServiceHelper.initService(target); + configurer = ((Component) target).getComponentPropertyConfigurer(); + } + + if (configurer == null) { + String name = target.getClass().getName(); + // see if there is a configurer for it + configurer = context.adapt(ExtendedCamelContext.class) + .getConfigurerResolver().resolvePropertyConfigurer(name, context); + } + + try { + // keep a reference of the original keys + Map<String, Object> backup = new LinkedHashMap<>(properties); + + rc = PropertyBindingSupport.build() + .withMandatory(failIfNotSet) + .withRemoveParameters(true) + .withConfigurer(configurer) + .withIgnoreCase(ignoreCase) + .bind(context, target, properties); + + for (Map.Entry<String, Object> entry : backup.entrySet()) { + if (entry.getValue() != null && !properties.containsKey(entry.getKey())) { + String prefix = optionPrefix; + if (prefix != null && !prefix.endsWith(".")) { + prefix = "." + prefix; + } + + LOG.debug("Configured property: {}{}={} on bean: {}", prefix, entry.getKey(), entry.getValue(), target); + autoConfiguredProperties.put(prefix + entry.getKey(), entry.getValue().toString()); + } + } + } catch (PropertyBindingException e) { + String key = e.getOptionKey(); + if (key == null) { + String prefix = e.getOptionPrefix(); + if (prefix != null && !prefix.endsWith(".")) { + prefix = "." + prefix; + } + + key = prefix != null + ? prefix + "." + e.getPropertyName() + : e.getPropertyName(); + } + + if (failIfNotSet) { + // enrich the error with more precise details with option prefix and key + throw new PropertyBindingException( + e.getTarget(), e.getPropertyName(), e.getValue(), optionPrefix, key, e.getCause()); + } else { + LOG.debug("Error configuring property (" + key + ") with name: " + e.getPropertyName() + ") on bean: " + target + + " with value: " + e.getValue() + ". This exception is ignored as failIfNotSet=false.", + e); + } + } + + return rc; + } + + public static void computeProperties( + String keyPrefix, String key, Properties prop, Map<PropertyOptionKey, Map<String, Object>> properties, + Function<String, Iterable<Object>> supplier) { + if (key.startsWith(keyPrefix)) { + // grab name + final int dot = key.indexOf('.', keyPrefix.length()); + final String name = dot == -1 ? key.substring(keyPrefix.length()) : key.substring(keyPrefix.length(), dot); + + // enabled is a virtual property + if ("enabled".equals(name)) { + return; + } + // skip properties as its already keyPrefix earlier + if ("properties".equals(name)) { + return; + } + + // determine if the service is enabled or not by taking into account two options: + // + // 1. ${keyPrefix}.enabled = true|false + // 2. ${keyPrefix}.${name}.enabled = true|false + // + // The option [2] has the higher priority so as example: + // + // camel.component.enabled = false + // camel.component.seda.enabled = true + // + // enables auto configuration of the seda component only + if (!isServiceEnabled(keyPrefix, name, prop)) { + return; + } + + String prefix = dot == -1 ? "" : key.substring(0, dot + 1); + String option = dot == -1 ? "" : key.substring(dot + 1); + String value = prop.getProperty(key, ""); + + // enabled is a virtual property + if ("enabled".equalsIgnoreCase(option)) { + return; + } + + validateOptionAndValue(key, option, value); + + 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<>()); + + // we ignore case for property keys (so we should store them in canonical style + values.put(optionKey(option), value); + } + } + } + + public static boolean isServiceEnabled(String prefix, String name, Properties properties) { + ObjectHelper.notNull(prefix, "prefix"); + ObjectHelper.notNull(name, "name"); + ObjectHelper.notNull(properties, "properties"); + + if (!prefix.endsWith(".")) { + prefix = prefix + "."; + } + + final String group = properties.getProperty(prefix + "enabled", "true"); + final String item = properties.getProperty(prefix + name + ".enabled", group); + + return Boolean.parseBoolean(item); + } + + public static void validateOptionAndValue(String key, String option, String value) { + if (ObjectHelper.isEmpty(option)) { + throw new IllegalArgumentException("Error configuring property: " + key + " because option is empty"); + } + if (ObjectHelper.isEmpty(value)) { + throw new IllegalArgumentException("Error configuring property: " + key + " because value is empty"); + } + } + } diff --git a/core/camel-main/src/main/java/org/apache/camel/main/MainSupport.java b/core/camel-main/src/main/java/org/apache/camel/main/MainSupport.java index 1dbe651..3176f8d 100644 --- a/core/camel-main/src/main/java/org/apache/camel/main/MainSupport.java +++ b/core/camel-main/src/main/java/org/apache/camel/main/MainSupport.java @@ -20,6 +20,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import org.apache.camel.CamelContext; +import org.apache.camel.ProducerTemplate; import org.apache.camel.spi.EventNotifier; import org.apache.camel.support.service.ServiceHelper; import org.slf4j.Logger; @@ -38,6 +39,8 @@ public abstract class MainSupport extends BaseMainSupport { protected final AtomicInteger exitCode = new AtomicInteger(UNINITIALIZED_EXIT_CODE); protected MainShutdownStrategy shutdownStrategy; + protected volatile ProducerTemplate camelTemplate; + protected MainSupport(Class<?>... configurationClasses) { this(); configure().addConfigurationClass(configurationClasses); @@ -152,7 +155,7 @@ public abstract class MainSupport extends BaseMainSupport { /** * Sets the duration (in seconds) to run the application until it should be terminated. Defaults to -1. Any value <= * 0 will run forever. - * + * * @deprecated use {@link #configure()} */ @Deprecated @@ -169,7 +172,7 @@ public abstract class MainSupport extends BaseMainSupport { * Sets the maximum idle duration (in seconds) when running the application, and if there has been no message * processed after being idle for more than this duration then the application should be terminated. Defaults to -1. * Any value <= 0 will run forever. - * + * * @deprecated use {@link #configure()} */ @Deprecated @@ -185,7 +188,7 @@ public abstract class MainSupport extends BaseMainSupport { /** * Sets the duration to run the application to process at most max messages until it should be terminated. Defaults * to -1. Any value <= 0 will run forever. - * + * * @deprecated use {@link #configure()} */ @Deprecated @@ -195,7 +198,7 @@ public abstract class MainSupport extends BaseMainSupport { /** * Sets the exit code for the application if duration was hit - * + * * @deprecated use {@link #configure()} */ @Deprecated @@ -227,7 +230,7 @@ public abstract class MainSupport extends BaseMainSupport { /** * Set the {@link MainShutdownStrategy} used to properly shut-down the main instance. By default a * {@link DefaultMainShutdownStrategy} will be used. - * + * * @param shutdownStrategy the shutdown strategy */ public void setShutdownStrategy(MainShutdownStrategy shutdownStrategy) { @@ -297,4 +300,23 @@ public abstract class MainSupport extends BaseMainSupport { } } } + + protected abstract ProducerTemplate findOrCreateCamelTemplate(); + + protected abstract CamelContext createCamelContext(); + + public ProducerTemplate getCamelTemplate() throws Exception { + if (camelTemplate == null) { + camelTemplate = findOrCreateCamelTemplate(); + } + return camelTemplate; + } + + protected void initCamelContext() throws Exception { + camelContext = createCamelContext(); + if (camelContext == null) { + throw new IllegalStateException("Created CamelContext is null"); + } + postProcessCamelContext(camelContext); + } } diff --git a/core/camel-main/src/main/java/org/apache/camel/main/PropertyOptionKey.java b/core/camel-main/src/main/java/org/apache/camel/main/PropertyOptionKey.java new file mode 100644 index 0000000..c732c00 --- /dev/null +++ b/core/camel-main/src/main/java/org/apache/camel/main/PropertyOptionKey.java @@ -0,0 +1,57 @@ +/* + * 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.main; + +import java.util.Objects; + +import org.apache.camel.util.ObjectHelper; + +final class PropertyOptionKey { + private final Object instance; + private final String optionPrefix; + + PropertyOptionKey(Object instance, String optionPrefix) { + this.instance = ObjectHelper.notNull(instance, "instance"); + this.optionPrefix = ObjectHelper.notNull(optionPrefix, "optionPrefix"); + } + + public Object getInstance() { + return instance; + } + + public String getOptionPrefix() { + return optionPrefix; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof PropertyOptionKey)) { + return false; + } + PropertyOptionKey key = (PropertyOptionKey) o; + return Objects.equals(instance, key.instance) + && Objects.equals(optionPrefix, key.optionPrefix); + } + + @Override + public int hashCode() { + return Objects.hash(instance, optionPrefix); + } +} diff --git a/core/camel-main/src/test/java/org/apache/camel/main/MainPropertyPlaceholderTest.java b/core/camel-main/src/test/java/org/apache/camel/main/MainPropertyPlaceholderTest.java index a3c9c7b..41e3d56 100644 --- a/core/camel-main/src/test/java/org/apache/camel/main/MainPropertyPlaceholderTest.java +++ b/core/camel-main/src/test/java/org/apache/camel/main/MainPropertyPlaceholderTest.java @@ -18,6 +18,7 @@ package org.apache.camel.main; import org.junit.jupiter.api.Test; +import static org.apache.camel.util.CollectionHelper.mapOf; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; @@ -59,4 +60,23 @@ public class MainPropertyPlaceholderTest { main.stop(); } } + + @Test + public void testPropertiesWithMap() { + Main main = new Main(); + try { + main.setInitialProperties( + mapOf("1", "val-init", "2", "val-init")); + main.setOverrideProperties( + mapOf("1", "val-override", "3", "val-override")); + + main.start(); + + assertEquals("val-override", main.getCamelContext().resolvePropertyPlaceholders("{{1}}")); + assertEquals("val-init", main.getCamelContext().resolvePropertyPlaceholders("{{2}}")); + assertEquals("val-override", main.getCamelContext().resolvePropertyPlaceholders("{{3}}")); + } finally { + main.stop(); + } + } }