You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ac...@apache.org on 2019/12/10 07:40:27 UTC

[camel] branch camel-3.0.x updated: Revert "CAMEL-14268: Component auto configuration fails in Java 11"

This is an automated email from the ASF dual-hosted git repository.

acosentino pushed a commit to branch camel-3.0.x
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/camel-3.0.x by this push:
     new 66ebead  Revert "CAMEL-14268: Component auto configuration fails in Java 11"
66ebead is described below

commit 66ebeadc1fbfa44a18db7152667230bd1ee6e3db
Author: Andrea Cosentino <an...@gmail.com>
AuthorDate: Tue Dec 10 08:40:00 2019 +0100

    Revert "CAMEL-14268: Component auto configuration fails in Java 11"
    
    This reverts commit 3fa80434504118d3071ba259ffb012d3e0d720b5.
---
 .../org/apache/camel/main/BaseMainSupport.java     | 130 ++++++++++-----------
 .../camel/main/MainComponentConfigurationTest.java |  54 ---------
 .../camel/main/support/MyDummyComponent.java       |  67 -----------
 .../main/support/MyDummyComponentConfigurer.java   |  52 ---------
 .../camel/main/support/MyDummyConfiguration.java   |  52 ---------
 .../camel/support/PropertyBindingSupport.java      |  74 ++++++------
 6 files changed, 100 insertions(+), 329 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 7b5e8ea..991e6ab 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
@@ -21,6 +21,7 @@ import java.io.FileInputStream;
 import java.io.InputStream;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Locale;
@@ -121,13 +122,15 @@ public abstract class BaseMainSupport extends ServiceSupport {
     }
 
     protected static boolean setPropertiesOnTarget(CamelContext context, Object target, Map<String, Object> properties,
-                                                   String optionPrefix, boolean failIfNotSet, boolean ignoreCase,
+                                                   String optionKey, 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;
+        Iterator it = properties.entrySet().iterator();
+
         PropertyConfigurer configurer = null;
         if (target instanceof Component) {
             // the component needs to be initialized to have the configurer ready
@@ -135,47 +138,41 @@ public abstract class BaseMainSupport extends ServiceSupport {
             configurer = ((Component) target).getComponentPropertyConfigurer();
         }
 
-        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;
-                    }
+        while (it.hasNext()) {
+            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;
+            } else if (optionPrefix != null) {
+                key = optionPrefix + name;
+            }
 
-                    LOG.debug("Configured property: {}{}={} on bean: {}", prefix, entry.getKey(), entry.getValue(), target);
-                    autoConfiguredProperties.put(prefix + entry.getKey(), entry.getValue().toString());
+            LOG.debug("Configuring property: {}={} on bean: {}", key, stringValue, target);
+            try {
+                boolean hit;
+                if (failIfNotSet) {
+                    PropertyBindingSupport.build().withMandatory(true).withConfigurer(configurer).withIgnoreCase(ignoreCase).bind(context, target, name, stringValue);
+                    hit = true;
+                } else {
+                    hit = PropertyBindingSupport.build().withConfigurer(configurer).withIgnoreCase(true).bind(context, target, name, stringValue);
                 }
-            }
-        } catch (PropertyBindingException e) {
-            String key = e.getOptionKey();
-            if (key == null) {
-                String prefix = e.getOptionPrefix();
-                if (prefix != null && !prefix.endsWith(".")) {
-                    prefix = "." + prefix;
+                if (hit) {
+                    it.remove();
+                    rc = true;
+                    LOG.debug("Configured property: {}={} on bean: {}", key, stringValue, target);
+                    autoConfiguredProperties.put(key, stringValue);
+                }
+            } catch (PropertyBindingException e) {
+                if (failIfNotSet) {
+                    // enrich the error with more precise details with option prefix and key
+                    throw new PropertyBindingException(e.getTarget(), e.getPropertyName(), e.getValue(), optionPrefix, optionKey, e.getCause());
+                } else {
+                    LOG.debug("Error configuring property (" + key + ") with name: " + name + ") on bean: " + target
+                            + " with value: " + stringValue + ". This exception is ignored as failIfNotSet=false.", e);
                 }
-
-                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);
             }
         }
 
@@ -710,7 +707,7 @@ public abstract class BaseMainSupport extends ServiceSupport {
         }
         if (!contextProperties.isEmpty()) {
             LOG.debug("Auto-configuring CamelContext from loaded properties: {}", contextProperties.size());
-            setPropertiesOnTarget(camelContext, camelContext, contextProperties, "camel.context.",
+            setPropertiesOnTarget(camelContext, camelContext, contextProperties, null, "camel.context.",
                     mainConfigurationProperties.isAutoConfigurationFailFast(), true, autoConfiguredProperties);
         }
         if (!hystrixProperties.isEmpty()) {
@@ -721,7 +718,7 @@ public abstract class BaseMainSupport extends ServiceSupport {
                 hystrix = new HystrixConfigurationDefinition();
                 model.setHystrixConfiguration(hystrix);
             }
-            setPropertiesOnTarget(camelContext, hystrix, hystrixProperties, "camel.hystrix.",
+            setPropertiesOnTarget(camelContext, hystrix, hystrixProperties, null, "camel.hystrix.",
                     mainConfigurationProperties.isAutoConfigurationFailFast(), true, autoConfiguredProperties);
         }
         if (!resilience4jProperties.isEmpty()) {
@@ -732,7 +729,7 @@ public abstract class BaseMainSupport extends ServiceSupport {
                 resilience4j = new Resilience4jConfigurationDefinition();
                 model.setResilience4jConfiguration(resilience4j);
             }
-            setPropertiesOnTarget(camelContext, resilience4j, resilience4jProperties, "camel.resilience4j.",
+            setPropertiesOnTarget(camelContext, resilience4j, resilience4jProperties, null, "camel.resilience4j.",
                     mainConfigurationProperties.isAutoConfigurationFailFast(), true, autoConfiguredProperties);
         }
         if (!restProperties.isEmpty()) {
@@ -743,7 +740,7 @@ public abstract class BaseMainSupport extends ServiceSupport {
                 rest = new RestConfiguration();
                 model.setRestConfiguration(rest);
             }
-            setPropertiesOnTarget(camelContext, rest, restProperties, "camel.rest.",
+            setPropertiesOnTarget(camelContext, rest, restProperties, null, "camel.rest.",
                     mainConfigurationProperties.isAutoConfigurationFailFast(), true, autoConfiguredProperties);
         }
 
@@ -802,8 +799,9 @@ public abstract class BaseMainSupport extends ServiceSupport {
 
         if (!properties.isEmpty()) {
             LOG.debug("Auto-configuring properties component from loaded properties: {}", properties.size());
-            setPropertiesOnTarget(camelContext, camelContext.getPropertiesComponent(), properties, "camel.component.properties.",
-                    mainConfigurationProperties.isAutoConfigurationFailFast(), true, autoConfiguredProperties);
+            setPropertiesOnTarget(camelContext, camelContext.getPropertiesComponent(), properties, null,
+                    "camel.component.properties.", mainConfigurationProperties.isAutoConfigurationFailFast(),
+                    true, autoConfiguredProperties);
         }
 
         // log which options was not set
@@ -840,7 +838,7 @@ public abstract class BaseMainSupport extends ServiceSupport {
 
         if (!properties.isEmpty()) {
             LOG.debug("Auto-configuring main from loaded properties: {}", properties.size());
-            setPropertiesOnTarget(camelContext, config, properties, "camel.main.",
+            setPropertiesOnTarget(camelContext, config, properties, null, "camel.main.",
                     mainConfigurationProperties.isAutoConfigurationFailFast(), true, autoConfiguredProperties);
         }
 
@@ -925,15 +923,11 @@ public abstract class BaseMainSupport extends ServiceSupport {
             LOG.debug("Auto-configuring {} components/dataformat/languages from loaded properties: {}", properties.size(), total);
         }
 
-        for (Map.Entry<PropertyOptionKey, Map<String, Object>> entry: properties.entrySet()) {
-            setPropertiesOnTarget(
-                    camelContext,
-                    entry.getKey().getInstance(),
-                    entry.getValue(),
-                    entry.getKey().getOptionPrefix(),
-                    mainConfigurationProperties.isAutoConfigurationFailFast(),
-                    true,
-                    autoConfiguredProperties);
+        for (PropertyOptionKey pok : properties.keySet()) {
+            Map<String, Object> values = properties.get(pok);
+            String optionKey = pok.getKey().substring(pok.getOptionPrefix().length());
+            setPropertiesOnTarget(camelContext, pok.getInstance(), values, optionKey, pok.getOptionPrefix(),
+                    mainConfigurationProperties.isAutoConfigurationFailFast(), true, autoConfiguredProperties);
         }
 
         // log which options was not set
@@ -942,7 +936,7 @@ public abstract class BaseMainSupport extends ServiceSupport {
                 Map<String, Object> values = properties.get(pok);
                 values.forEach((k, v) -> {
                     String stringValue = v != null ? v.toString() : null;
-                    LOG.warn("Property ({}={}) not auto-configured with name: {} on bean: {} with value: {}", pok.getOptionPrefix() +  "." + k, stringValue, k, pok.getInstance(), stringValue);
+                    LOG.warn("Property ({}={}) not auto-configured with name: {} on bean: {} with value: {}", pok.getKey(), stringValue, k, pok.getInstance(), stringValue);
                 });
             }
         }
@@ -1016,12 +1010,19 @@ public abstract class BaseMainSupport extends ServiceSupport {
     }
 
     private static final class PropertyOptionKey {
+
+        private final String key;
         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");
+        private PropertyOptionKey(String key, Object instance, String optionPrefix) {
+            this.key = key;
+            this.instance = instance;
+            this.optionPrefix = optionPrefix;
+        }
+
+        public String getKey() {
+            return key;
         }
 
         public Object getInstance() {
@@ -1037,17 +1038,16 @@ public abstract class BaseMainSupport extends ServiceSupport {
             if (this == o) {
                 return true;
             }
-            if (!(o instanceof PropertyOptionKey)) {
+            if (o == null || getClass() != o.getClass()) {
                 return false;
             }
-            PropertyOptionKey key = (PropertyOptionKey) o;
-            return Objects.equals(instance, key.instance)
-                && Objects.equals(optionPrefix, key.optionPrefix);
+            PropertyOptionKey that = (PropertyOptionKey) o;
+            return key.equals(that.key) && instance.equals(that.instance);
         }
 
         @Override
         public int hashCode() {
-            return Objects.hash(instance, optionPrefix);
+            return Objects.hash(key, instance);
         }
     }
 
@@ -1093,7 +1093,7 @@ public abstract class BaseMainSupport extends ServiceSupport {
 
             validateOptionAndValue(key, option, value);
 
-            PropertyOptionKey pok = new PropertyOptionKey(target, prefix);
+            PropertyOptionKey pok = new PropertyOptionKey(key, 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
diff --git a/core/camel-main/src/test/java/org/apache/camel/main/MainComponentConfigurationTest.java b/core/camel-main/src/test/java/org/apache/camel/main/MainComponentConfigurationTest.java
deleted file mode 100644
index a2360ba..0000000
--- a/core/camel-main/src/test/java/org/apache/camel/main/MainComponentConfigurationTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.Properties;
-
-import org.apache.camel.main.support.MyDummyComponent;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class MainComponentConfigurationTest extends Assert {
-    @Test
-    public void testComponentConfiguration() {
-        Properties properties = new Properties();
-        properties.setProperty("camel.component.dummy.configuration.log", "true");
-        properties.setProperty("camel.component.dummy.component-value", "component-value");
-        properties.setProperty("camel.component.dummy.configuration.nested.value", "nested-value");
-        properties.setProperty("camel.component.dummy.configuration", "#class:org.apache.camel.main.support.MyDummyConfiguration");
-
-        Main main = new Main();
-        try {
-            MyDummyComponent dummy = new MyDummyComponent(false);
-
-            main.bind("dummy", dummy);
-            main.setOverrideProperties(properties);
-            main.setDefaultPropertyPlaceholderLocation("false");
-            main.start();
-
-            assertEquals("component-value", dummy.getComponentValue());
-
-            assertNotNull(dummy.getConfiguration());
-            assertTrue(dummy.getConfiguration().isLog());
-            assertNotNull(dummy.getConfiguration().getNested());
-            assertEquals("nested-value", dummy.getConfiguration().getNested().getValue());
-        } finally {
-            main.stop();
-        }
-    }
-}
-
diff --git a/core/camel-main/src/test/java/org/apache/camel/main/support/MyDummyComponent.java b/core/camel-main/src/test/java/org/apache/camel/main/support/MyDummyComponent.java
deleted file mode 100644
index 9b3d73f..0000000
--- a/core/camel-main/src/test/java/org/apache/camel/main/support/MyDummyComponent.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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.support;
-
-import java.util.Map;
-
-import org.apache.camel.Endpoint;
-import org.apache.camel.spi.PropertyConfigurer;
-import org.apache.camel.spi.annotations.Component;
-import org.apache.camel.support.DefaultComponent;
-
-@Component("dummy")
-public class MyDummyComponent extends DefaultComponent {
-    private MyDummyConfiguration configuration;
-    private boolean configurer;
-    private String componentValue;
-
-    public MyDummyComponent(boolean configurer) {
-        this.configurer = configurer;
-    }
-
-    public MyDummyConfiguration getConfiguration() {
-        return configuration;
-    }
-
-    public void setConfiguration(MyDummyConfiguration configuration) {
-        this.configuration = configuration;
-    }
-
-    // this method makes camel no able to find a suitable setter
-    public void setConfiguration(Object configuration) {
-        this.configuration = (MyDummyConfiguration)configuration;
-    }
-
-    public String getComponentValue() {
-        return componentValue;
-    }
-
-    public MyDummyComponent setComponentValue(String componentValue) {
-        this.componentValue = componentValue;
-        return this;
-    }
-
-    @Override
-    protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public PropertyConfigurer getComponentPropertyConfigurer() {
-        return configurer ? new MyDummyComponentConfigurer() : null;
-    }
-}
diff --git a/core/camel-main/src/test/java/org/apache/camel/main/support/MyDummyComponentConfigurer.java b/core/camel-main/src/test/java/org/apache/camel/main/support/MyDummyComponentConfigurer.java
deleted file mode 100644
index 9751c7b..0000000
--- a/core/camel-main/src/test/java/org/apache/camel/main/support/MyDummyComponentConfigurer.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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.support;
-
-import org.apache.camel.CamelContext;
-import org.apache.camel.spi.GeneratedPropertyConfigurer;
-import org.apache.camel.support.component.PropertyConfigurerSupport;
-
-public class MyDummyComponentConfigurer extends PropertyConfigurerSupport implements GeneratedPropertyConfigurer {
-    @Override
-    public boolean configure(CamelContext camelContext, Object component, String name, Object value, boolean ignoreCase) {
-        if (ignoreCase) {
-            return doConfigureIgnoreCase(camelContext, component, name, value);
-        } else {
-            return doConfigure(camelContext, component, name, value);
-        }
-    }
-
-    private static boolean doConfigure(CamelContext camelContext, Object component, String name, Object value) {
-        switch (name) {
-        case "configuration":
-            ((MyDummyComponent) component).setConfiguration(property(camelContext, MyDummyConfiguration.class, value));
-            return true;
-        default:
-            return false;
-        }
-    }
-
-    private static boolean doConfigureIgnoreCase(CamelContext camelContext, Object component, String name, Object value) {
-        switch (name.toLowerCase()) {
-        case "configuration":
-            ((MyDummyComponent) component).setConfiguration(property(camelContext, MyDummyConfiguration.class, value));
-            return true;
-        default:
-            return false;
-        }
-    }
-}
diff --git a/core/camel-main/src/test/java/org/apache/camel/main/support/MyDummyConfiguration.java b/core/camel-main/src/test/java/org/apache/camel/main/support/MyDummyConfiguration.java
deleted file mode 100644
index 153dadf..0000000
--- a/core/camel-main/src/test/java/org/apache/camel/main/support/MyDummyConfiguration.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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.support;
-
-public class MyDummyConfiguration {
-    private boolean log;
-    private NestedConfig nested;
-
-    public boolean isLog() {
-        return log;
-    }
-
-    public MyDummyConfiguration setLog(boolean log) {
-        this.log = log;
-        return this;
-    }
-
-    public NestedConfig getNested() {
-        return nested;
-    }
-
-    public void setNested(NestedConfig nested) {
-        this.nested = nested;
-    }
-
-    public static class NestedConfig {
-        private String value;
-
-        public String getValue() {
-            return value;
-        }
-
-        public NestedConfig setValue(String value) {
-            this.value = value;
-            return this;
-        }
-    }
-}
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 1c8205d..4d101c1 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
@@ -19,7 +19,6 @@ package org.apache.camel.support;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
-import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -472,9 +471,7 @@ public final class PropertyBindingSupport {
         org.apache.camel.util.ObjectHelper.notNull(camelContext, "camelContext");
         org.apache.camel.util.ObjectHelper.notNull(target, "target");
         org.apache.camel.util.ObjectHelper.notNull(properties, "properties");
-
-        final String uOptionPrefix = ignoreCase && isNotEmpty(optionPrefix) ? optionPrefix.toUpperCase(Locale.US) : "";
-        final int size = properties.size();
+        boolean rc = false;
 
         if (configurer instanceof GeneratedPropertyConfigurer) {
             GeneratedPropertyConfigurer gen = (GeneratedPropertyConfigurer) configurer;
@@ -483,9 +480,12 @@ public final class PropertyBindingSupport {
                 Map.Entry<String, Object> entry = iter.next();
                 String key = entry.getKey();
                 Object value = entry.getValue();
-
-                // property configurer does not support nested names so skip if the name has a dot
-                if (key.indexOf('.') != -1) {
+                boolean valid = true;
+                if (nesting) {
+                    // property configurer does not support nested names so skip if the name has a dot
+                    valid = key.indexOf('.') == -1;
+                }
+                if (valid) {
                     try {
                         // GeneratedPropertyConfigurer works by invoking the methods directly but it does
                         // not resolve property placeholders eventually defined in the value before invoking
@@ -497,6 +497,7 @@ public final class PropertyBindingSupport {
                         boolean hit = gen.configure(camelContext, target, key, value, ignoreCase);
                         if (removeParameter && hit) {
                             iter.remove();
+                            rc = true;
                         }
                     } catch (Exception e) {
                         throw new PropertyBindingException(target, key, value, e);
@@ -506,44 +507,39 @@ public final class PropertyBindingSupport {
         }
 
         // must set reference parameters first before the other bindings
+        int size = properties.size();
         setReferenceProperties(camelContext, target, properties);
+        rc |= properties.size() != size;
 
-        // sort the keys by nesting level so when moving to the nest level all the
-        // propertis of the curent level are bound to the target. This allow the 
-        // properties binging engine to be indipendent to the order of properrties.
-        //
-        // As example:
-        //
-        //     configuration.my-property = myCustomValue
-        //     configuration = #class:my.custom.Config
-        //
-        // 'configuration.my-property' has lower precedence over 'configuration' as
-        // it is one level deep and will be set after all the properties of the current
-        // level are set which allow `my-property` to be set of the right instance.
-        properties.keySet().stream()
-            .sorted(Comparator.comparingInt(s -> StringHelper.countChar(s, '.')))
-            .forEach(key -> {
-                final Object value = properties.get(key);
-
-                if (isNotEmpty(optionPrefix)) {
-                    boolean match = key.startsWith(optionPrefix) || ignoreCase && key.toUpperCase(Locale.US).startsWith(uOptionPrefix);
-                    if (!match) {
-                        return;
-                    }
-                    key = key.substring(optionPrefix.length());
-                }
+        String uOptionPrefix = "";
+        if (ignoreCase && isNotEmpty(optionPrefix)) {
+            uOptionPrefix = optionPrefix.toUpperCase(Locale.US);
+        }
 
-                boolean bound = bindProperty(camelContext, target, key, value, ignoreCase, nesting, deepNesting, fluentBuilder, allowPrivateSetter, reference, placeholder);
-                if (bound && removeParameter) {
-                    properties.remove(key);
-                }
-                if (mandatory && !bound) {
-                    throw new PropertyBindingException(target, key, value);
+        for (Iterator<Map.Entry<String, Object>> iter = properties.entrySet().iterator(); iter.hasNext();) {
+            Map.Entry<String, Object> entry = iter.next();
+            String key = entry.getKey();
+            Object value = entry.getValue();
+
+            if (isNotEmpty(optionPrefix)) {
+                boolean match = key.startsWith(optionPrefix) || ignoreCase && key.toUpperCase(Locale.US).startsWith(uOptionPrefix);
+                if (!match) {
+                    continue;
                 }
+                key = key.substring(optionPrefix.length());
             }
-        );
 
-        return properties.size() != size;
+            boolean bound = bindProperty(camelContext, target, key, value, ignoreCase, nesting, deepNesting, fluentBuilder, allowPrivateSetter, reference, placeholder);
+            if (bound && removeParameter) {
+                iter.remove();
+                rc = true;
+            }
+            if (mandatory && !bound) {
+                throw new PropertyBindingException(target, key, value);
+            }
+        }
+
+        return rc;
     }
 
     private static boolean bindProperty(CamelContext camelContext, Object target, String name, Object value,