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);
             }
         }
     }

Reply via email to