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 73e645f CAMEL-13683: camel-main - configuring properties report better error if missing JARs on classpathand other mistakes. 73e645f is described below commit 73e645f876281fca67f021e695def10af7855912 Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Thu Jun 27 11:52:50 2019 +0200 CAMEL-13683: camel-main - configuring properties report better error if missing JARs on classpathand other mistakes. --- .../org/apache/camel/PropertyBindingException.java | 50 ++++++++++-- .../java/org/apache/camel/main/MainSupport.java | 89 ++++++++++++++-------- .../camel/support/PropertyBindingSupport.java | 20 +++-- 3 files changed, 114 insertions(+), 45 deletions(-) diff --git a/core/camel-api/src/main/java/org/apache/camel/PropertyBindingException.java b/core/camel-api/src/main/java/org/apache/camel/PropertyBindingException.java index fdc9005..377b718 100644 --- a/core/camel-api/src/main/java/org/apache/camel/PropertyBindingException.java +++ b/core/camel-api/src/main/java/org/apache/camel/PropertyBindingException.java @@ -23,23 +23,43 @@ public class PropertyBindingException extends RuntimeCamelException { private final Object target; private final String propertyName; + private final Object value; + private String optionPrefix; + private String optionKey; - public PropertyBindingException(Object target, String propertyName) { - super("No such property: " + propertyName + " on bean: " + target); + public PropertyBindingException(Object target, String propertyName, Object value) { this.target = target; this.propertyName = propertyName; + this.value = value; } - public PropertyBindingException(Object target, String propertyName, Exception e) { - super("Error binding property: " + propertyName + " on bean: " + target, e); + public PropertyBindingException(Object target, String propertyName, Object value, Exception e) { + initCause(e); this.target = target; this.propertyName = propertyName; + this.value = value; } public PropertyBindingException(Object target, Exception e) { - super("Error binding properties on bean: " + target, e); + initCause(e); this.target = target; this.propertyName = null; + this.value = null; + } + + @Override + public String getMessage() { + String stringValue = value != null ? value.toString() : ""; + String key = propertyName; + if (optionPrefix != null && optionKey != null) { + key = optionPrefix + "." + optionKey; + } + if (key != null) { + return "Error binding property (" + key + "=" + stringValue + ") with name: " + propertyName + + " on bean: " + target + " with value: " + stringValue; + } else { + return "Error binding properties on bean: " + target; + } } public Object getTarget() { @@ -49,4 +69,24 @@ public class PropertyBindingException extends RuntimeCamelException { public String getPropertyName() { return propertyName; } + + public Object getValue() { + return value; + } + + public String getOptionPrefix() { + return optionPrefix; + } + + public void setOptionPrefix(String optionPrefix) { + this.optionPrefix = optionPrefix; + } + + public String getOptionKey() { + return optionKey; + } + + public void setOptionKey(String optionKey) { + this.optionKey = optionKey; + } } 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 ead13d0..af3787f 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 @@ -40,6 +40,7 @@ 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.builder.RouteBuilder; import org.apache.camel.model.HystrixConfigurationDefinition; import org.apache.camel.model.Model; @@ -877,7 +878,8 @@ public abstract class MainSupport extends ServiceSupport { } if (!contextProperties.isEmpty()) { LOG.info("Auto configuring CamelContext from loaded properties: {}", contextProperties.size()); - setPropertiesOnTarget(camelContext, camelContext, contextProperties, mainConfigurationProperties.isAutoConfigurationFailFast(), true); + setPropertiesOnTarget(camelContext, camelContext, contextProperties, null, "camel.context.", + mainConfigurationProperties.isAutoConfigurationFailFast(), true); } if (!hystrixProperties.isEmpty()) { LOG.info("Auto configuring Hystrix EIP from loaded properties: {}", hystrixProperties.size()); @@ -887,7 +889,8 @@ public abstract class MainSupport extends ServiceSupport { hystrix = new HystrixConfigurationDefinition(); model.setHystrixConfiguration(hystrix); } - setPropertiesOnTarget(camelContext, hystrix, hystrixProperties, mainConfigurationProperties.isAutoConfigurationFailFast(), true); + setPropertiesOnTarget(camelContext, hystrix, hystrixProperties, null, "camel.hsytrix.", + mainConfigurationProperties.isAutoConfigurationFailFast(), true); } if (!restProperties.isEmpty()) { LOG.info("Auto configuring Rest DSL from loaded properties: {}", restProperties.size()); @@ -897,7 +900,8 @@ public abstract class MainSupport extends ServiceSupport { rest = new RestConfiguration(); model.setRestConfiguration(rest); } - setPropertiesOnTarget(camelContext, rest, restProperties, mainConfigurationProperties.isAutoConfigurationFailFast(), true); + setPropertiesOnTarget(camelContext, rest, restProperties, null, "camel.rest.", + mainConfigurationProperties.isAutoConfigurationFailFast(), true); } // log which options was not set @@ -946,7 +950,7 @@ public abstract class MainSupport extends ServiceSupport { if (!properties.isEmpty()) { LOG.info("Auto configuring properties component from loaded properties: {}", properties.size()); - setPropertiesOnTarget(camelContext, camelContext.getPropertiesComponent(), properties, mainConfigurationProperties.isAutoConfigurationFailFast(), true); + setPropertiesOnTarget(camelContext, camelContext.getPropertiesComponent(), properties, null, "camel.component.properties.", mainConfigurationProperties.isAutoConfigurationFailFast(), true); } // log which options was not set @@ -981,7 +985,8 @@ public abstract class MainSupport extends ServiceSupport { if (!properties.isEmpty()) { LOG.info("Auto configuring main from loaded properties: {}", properties.size()); - setPropertiesOnTarget(camelContext, config, properties, mainConfigurationProperties.isAutoConfigurationFailFast(), true); + setPropertiesOnTarget(camelContext, config, properties, null,"camel.main.", + mainConfigurationProperties.isAutoConfigurationFailFast(), true); } // log which options was not set @@ -1042,8 +1047,9 @@ public abstract class MainSupport extends ServiceSupport { } String option = dot == -1 ? "" : key.substring(dot + 1); String value = prop.getProperty(key, ""); + String prefix = dot == -1 ? "" : key.substring(0, dot); validateOptionAndValue(key, option, value); - PropertyOptionKey pok = new PropertyOptionKey(key, component); + PropertyOptionKey pok = new PropertyOptionKey(key, component, prefix); Map<String, Object> values = properties.getOrDefault(pok, new LinkedHashMap<>()); // we ignore case for property keys (so we should store them in canonical style values.put(optionKey(option), value); @@ -1060,8 +1066,9 @@ public abstract class MainSupport extends ServiceSupport { } String option = dot == -1 ? "" : key.substring(dot + 1); String value = prop.getProperty(key, ""); + String prefix = dot == -1 ? "" : key.substring(0, dot); validateOptionAndValue(key, option, value); - PropertyOptionKey pok = new PropertyOptionKey(key, dataformat); + PropertyOptionKey pok = new PropertyOptionKey(key, dataformat, prefix); Map<String, Object> values = properties.getOrDefault(pok, new LinkedHashMap<>()); values.put(optionKey(option), value); properties.put(pok, values); @@ -1079,8 +1086,9 @@ public abstract class MainSupport extends ServiceSupport { } String option = dot == -1 ? "" : key.substring(dot + 1); String value = prop.getProperty(key, ""); + String prefix = dot == -1 ? "" : key.substring(0, dot); validateOptionAndValue(key, option, value); - PropertyOptionKey pok = new PropertyOptionKey(key, language); + PropertyOptionKey pok = new PropertyOptionKey(key, language, prefix); Map<String, Object> values = properties.getOrDefault(pok, new LinkedHashMap<>()); values.put(optionKey(option), value); properties.put(pok, values); @@ -1092,10 +1100,11 @@ public abstract class MainSupport extends ServiceSupport { LOG.info("Auto configuring {} components/dataformat/languages from loaded properties: {}", properties.size(), total); } - // TODO: Better error if setting some property fails for (PropertyOptionKey pok : properties.keySet()) { Map<String, Object> values = properties.get(pok); - setPropertiesOnTarget(camelContext, pok.getInstance(), values, mainConfigurationProperties.isAutoConfigurationFailFast(), true); + String optionKey = pok.getKey().substring(pok.getOptionPrefix().length() + 1); + setPropertiesOnTarget(camelContext, pok.getInstance(), values, optionKey, pok.getOptionPrefix(), + mainConfigurationProperties.isAutoConfigurationFailFast(), true); } // log which options was not set @@ -1103,7 +1112,8 @@ public abstract class MainSupport extends ServiceSupport { for (PropertyOptionKey pok : properties.keySet()) { Map<String, Object> values = properties.get(pok); values.forEach((k, v) -> { - LOG.warn("Property not auto configured: {}={} on object: {}", pok.getKey(), v, pok.getInstance()); + String stringValue = v != null ? v.toString() : null; + LOG.warn("Property ({}={}) not auto configured with name: {} on bean: {} with value: {}", pok.getKey(), stringValue, k, pok.getInstance(), stringValue); }); } } @@ -1178,10 +1188,12 @@ public abstract class MainSupport extends ServiceSupport { setRouteBuilderClasses(existing); } - private static boolean setPropertiesOnTarget(CamelContext context, Object target, Map<String, Object> properties, boolean failIfNotSet, boolean ignoreCase) throws Exception { + private static boolean setPropertiesOnTarget(CamelContext context, Object target, Map<String, Object> properties, + String optionKey, String optionPrefix, boolean failIfNotSet, boolean ignoreCase) throws Exception { ObjectHelper.notNull(context, "context"); ObjectHelper.notNull(target, "target"); ObjectHelper.notNull(properties, "properties"); + boolean rc = false; Iterator it = properties.entrySet().iterator(); @@ -1189,27 +1201,34 @@ public abstract class MainSupport extends ServiceSupport { Map.Entry<String, Object> entry = (Map.Entry) it.next(); String name = entry.getKey(); Object value = entry.getValue(); - String stringValue = value != null ? value.toString() : null; + String key = name; + if (optionPrefix != null && optionKey != null) { + key = optionPrefix + "." + optionKey; + } - LOG.debug("Setting property {} on {} with value {}", name, target, stringValue); - if (failIfNotSet) { - PropertyBindingSupport.bindMandatoryProperty(context, target, name, stringValue, ignoreCase); - it.remove(); - rc = true; - } else { - try { - boolean hit = PropertyBindingSupport.bindProperty(context, target, name, stringValue, ignoreCase); - if (hit) { - it.remove(); - rc = true; - } - } catch (Exception e) { - if (failIfNotSet) { - throw e; - } else { - LOG.debug(e.getMessage() + ". This exception is ignored.", e); - } + LOG.debug("Setting property ({}) with name: {} on bean: {} with value: {}", key, name, target, stringValue); + try { + boolean hit; + if (failIfNotSet) { + PropertyBindingSupport.bindMandatoryProperty(context, target, name, stringValue, ignoreCase); + hit = true; + } else { + hit = PropertyBindingSupport.bindProperty(context, target, name, stringValue, ignoreCase); + } + if (hit) { + it.remove(); + rc = true; + } + } catch (PropertyBindingException e) { + if (failIfNotSet) { + // enrich the error with better details + e.setOptionPrefix(optionPrefix); + e.setOptionKey(optionKey); + throw e; + } else { + LOG.debug("Error setting property (" + key + ") with name: " + name + ") on bean: " + target + + " with value: " + stringValue + ". This exception is ignored as failIfNotSet=false.", e); } } } @@ -1221,10 +1240,12 @@ public abstract class MainSupport extends ServiceSupport { private final String key; private final Object instance; + private final String optionPrefix; - private PropertyOptionKey(String key, Object instance) { + private PropertyOptionKey(String key, Object instance, String optionPrefix) { this.key = key; this.instance = instance; + this.optionPrefix = optionPrefix; } public String getKey() { @@ -1235,6 +1256,10 @@ public abstract class MainSupport extends ServiceSupport { return instance; } + public String getOptionPrefix() { + return optionPrefix; + } + @Override public boolean equals(Object o) { if (this == o) { diff --git a/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java b/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java index 2236e27..d74932c 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/PropertyBindingSupport.java @@ -401,8 +401,9 @@ public final class PropertyBindingSupport { * @param name name of property * @param value value of property * @return true if property was bound, false otherwise + * @throws PropertyBindingException is thrown if error binding property */ - public static boolean bindProperty(CamelContext camelContext, Object target, String name, Object value) { + public static boolean bindProperty(CamelContext camelContext, Object target, String name, Object value) throws PropertyBindingException { return bindProperty(camelContext, target, name, value, false); } @@ -415,14 +416,15 @@ public final class PropertyBindingSupport { * @param value value of property * @param ignoreCase whether to ignore case for property keys * @return true if property was bound, false otherwise + * @throws PropertyBindingException is thrown if error binding property */ - public static boolean bindProperty(CamelContext camelContext, Object target, String name, Object value, boolean ignoreCase) { + public static boolean bindProperty(CamelContext camelContext, Object target, String name, Object value, boolean ignoreCase) throws PropertyBindingException { try { if (target != null && name != null) { return setProperty(camelContext, target, name, value, false, ignoreCase, true, true, true, true, true, true); } } catch (Exception e) { - throw new PropertyBindingException(target, name, e); + throw new PropertyBindingException(target, name, value, e); } return false; @@ -436,7 +438,7 @@ public final class PropertyBindingSupport { return setProperty(camelContext, target, name, value, false, ignoreCase, nesting, deepNesting, fluentBuilder, allowPrivateSetter, reference, placeholder); } } catch (Exception e) { - throw new PropertyBindingException(target, name, e); + throw new PropertyBindingException(target, name, value, e); } return false; @@ -449,8 +451,9 @@ public final class PropertyBindingSupport { * @param target the target object * @param name name of property * @param value value of property + * @throws PropertyBindingException is thrown if error binding property, or the property was not bound */ - public static void bindMandatoryProperty(CamelContext camelContext, Object target, String name, Object value) { + public static void bindMandatoryProperty(CamelContext camelContext, Object target, String name, Object value) throws PropertyBindingException { bindMandatoryProperty(camelContext, target, name, value, false); } @@ -462,17 +465,18 @@ public final class PropertyBindingSupport { * @param name name of property * @param value value of property * @param ignoreCase whether to ignore case for property keys + * @throws PropertyBindingException is thrown if error binding property, or the property was not bound */ - public static void bindMandatoryProperty(CamelContext camelContext, Object target, String name, Object value, boolean ignoreCase) { + public static void bindMandatoryProperty(CamelContext camelContext, Object target, String name, Object value, boolean ignoreCase) throws PropertyBindingException{ boolean bound; if (target != null && name != null) { try { bound = setProperty(camelContext, target, name, value, true, ignoreCase, true, true, true, true, true, true); } catch (Exception e) { - throw new PropertyBindingException(target, name, e); + throw new PropertyBindingException(target, name, value, e); } if (!bound) { - throw new PropertyBindingException(target, name); + throw new PropertyBindingException(target, name, value); } } }