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

[camel] 01/02: CAMEL-14311: Add validate configuration properties to camel-catalog.

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

commit 1400650f37f6e11047fbeeaa15861b853952bdfa
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Fri Dec 20 19:41:03 2019 +0100

    CAMEL-14311: Add validate configuration properties to camel-catalog.
---
 catalog/camel-catalog/pom.xml                      |   1 +
 .../org/apache/camel/catalog/CamelCatalog.java     |   8 +
 .../catalog/CamelCatalogJSonSchemaResolver.java    |   7 +
 .../org/apache/camel/catalog/CamelCatalogTest.java | 234 +++++++++++++++++++
 .../ConfigurationPropertiesValidationResult.java   |  41 ++++
 .../runtimecatalog/EndpointValidationResult.java   |  33 +++
 .../camel/runtimecatalog/JSonSchemaResolver.java   |   7 +
 .../camel/runtimecatalog/RuntimeCamelCatalog.java  |  14 +-
 .../runtimecatalog/impl/AbstractCamelCatalog.java  | 250 +++++++++++++++++++--
 .../impl/CamelContextJSonSchemaResolver.java       |  19 ++
 .../impl/RuntimeCamelCatalogTest.java              |  53 ++++-
 .../org/apache/camel/support/JSonSchemaHelper.java | 157 +++++++++++--
 .../camel/support/PropertyBindingSupport.java      |   2 +-
 13 files changed, 782 insertions(+), 44 deletions(-)

diff --git a/catalog/camel-catalog/pom.xml b/catalog/camel-catalog/pom.xml
index 4c3e8a1..ba9a7ca 100644
--- a/catalog/camel-catalog/pom.xml
+++ b/catalog/camel-catalog/pom.xml
@@ -125,6 +125,7 @@
                                     </directory>
                                     <!-- the following files are maintained in camel-api and not here, so they are copied over -->
                                     <includes>
+                                        <include>ConfigurationPropertiesValidationResult.java</include>
                                         <include>EndpointValidationResult.java</include>
                                         <include>JSonSchemaResolver.java</include>
                                         <include>LanguageValidationResult.java</include>
diff --git a/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java b/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java
index 3bcef3d..bbba0f8 100644
--- a/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java
+++ b/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java
@@ -474,6 +474,14 @@ public interface CamelCatalog {
     LanguageValidationResult validateLanguageExpression(ClassLoader classLoader, String language, String text);
 
     /**
+     * Parses and validates the configuration property
+     *
+     * @param text  the configuration text
+     * @return validation result
+     */
+    ConfigurationPropertiesValidationResult validateConfigurationProperty(String text);
+
+    /**
      * Returns the component name from the given endpoint uri
      *
      * @param uri  the endpoint uri
diff --git a/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/CamelCatalogJSonSchemaResolver.java b/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/CamelCatalogJSonSchemaResolver.java
index eb49604..a43c4e2 100644
--- a/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/CamelCatalogJSonSchemaResolver.java
+++ b/catalog/camel-catalog/src/main/java/org/apache/camel/catalog/CamelCatalogJSonSchemaResolver.java
@@ -105,6 +105,13 @@ public class CamelCatalogJSonSchemaResolver implements JSonSchemaResolver {
     }
 
     @Override
+    public String getMainJsonSchema() {
+        final String file = "META-INF/camel-main-configuration-metadata.json";
+
+        return loadResourceFromVersionManager(file);
+    }
+
+    @Override
     public String getOtherJSonSchema(String name) {
         final String file = camelCatalog.getRuntimeProvider().getOtherJSonSchemaDirectory() + "/" + name + ".json";
 
diff --git a/catalog/camel-catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java b/catalog/camel-catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java
index 79864a6..ddc9c84 100644
--- a/catalog/camel-catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java
+++ b/catalog/camel-catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java
@@ -1301,4 +1301,238 @@ public class CamelCatalogTest {
         assertEquals("Kerberos Renew Jitter", row.get("displayName"));
     }
 
+    @Test
+    public void testValidateConfigurationPropertyComponent() throws Exception {
+        String text = "camel.component.seda.queueSize=1234";
+        ConfigurationPropertiesValidationResult result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+
+        text = "camel.component.seda.queue-size=1234";
+        result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+
+        text = "camel.component.seda.queuesize=1234";
+        result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+
+        text = "camel.component.seda.queueSize=abc";
+        result = catalog.validateConfigurationProperty(text);
+        assertFalse(result.isSuccess());
+        assertEquals("abc", result.getInvalidInteger().get("camel.component.seda.queueSize"));
+
+        text = "camel.component.seda.foo=abc";
+        result = catalog.validateConfigurationProperty(text);
+        assertFalse(result.isSuccess());
+        assertTrue(result.getUnknown().contains("camel.component.seda.foo"));
+
+        text = "camel.component.jms.acknowledgementModeName=abc";
+        result = catalog.validateConfigurationProperty(text);
+        assertFalse(result.isSuccess());
+        assertEquals("abc", result.getInvalidEnum().get("camel.component.jms.acknowledgementModeName"));
+        List<String> list = result.getEnumChoices("camel.component.jms.acknowledgementModeName");
+        assertEquals(4, list.size());
+        assertEquals("SESSION_TRANSACTED", list.get(0));
+        assertEquals("CLIENT_ACKNOWLEDGE", list.get(1));
+        assertEquals("AUTO_ACKNOWLEDGE", list.get(2));
+        assertEquals("DUPS_OK_ACKNOWLEDGE", list.get(3));
+    }
+
+    @Test
+    public void testValidateConfigurationPropertyLanguage() throws Exception {
+        String text = "camel.language.tokenize.token=;";
+        ConfigurationPropertiesValidationResult result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+
+        text = "camel.language.tokenize.regex=true";
+        result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+
+        text = "camel.language.tokenize.regex=abc";
+        result = catalog.validateConfigurationProperty(text);
+        assertFalse(result.isSuccess());
+        assertEquals("abc", result.getInvalidBoolean().get("camel.language.tokenize.regex"));
+
+        text = "camel.language.tokenize.foo=abc";
+        result = catalog.validateConfigurationProperty(text);
+        assertFalse(result.isSuccess());
+        assertTrue(result.getUnknown().contains("camel.language.tokenize.foo"));
+    }
+
+    @Test
+    public void testValidateConfigurationPropertyDataformat() throws Exception {
+        String text = "camel.dataformat.bindy-csv.type=csv";
+        ConfigurationPropertiesValidationResult result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+
+        text = "camel.dataformat.bindy-csv.locale=us";
+        result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+
+        text = "camel.dataformat.bindy-csv.allowEmptyStream=abc";
+        result = catalog.validateConfigurationProperty(text);
+        assertFalse(result.isSuccess());
+        assertEquals("abc", result.getInvalidBoolean().get("camel.dataformat.bindy-csv.allowEmptyStream"));
+
+        text = "camel.dataformat.bindy-csv.foo=abc";
+        result = catalog.validateConfigurationProperty(text);
+        assertFalse(result.isSuccess());
+        assertTrue(result.getUnknown().contains("camel.dataformat.bindy-csv.foo"));
+
+        text = "camel.dataformat.bindy-csv.type=abc";
+        result = catalog.validateConfigurationProperty(text);
+        assertFalse(result.isSuccess());
+        assertEquals("abc", result.getInvalidEnum().get("camel.dataformat.bindy-csv.type"));
+        List<String> list = result.getEnumChoices("camel.dataformat.bindy-csv.type");
+        assertEquals(3, list.size());
+        assertEquals("Csv", list.get(0));
+        assertEquals("Fixed", list.get(1));
+        assertEquals("KeyValue", list.get(2));
+    }
+
+    @Test
+    public void testValidateConfigurationPropertyComponentQuartz() throws Exception {
+        String text = "camel.component.quartz.auto-start-scheduler=true";
+        ConfigurationPropertiesValidationResult result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+
+        text = "camel.component.quartz.properties=#myProp";
+        result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+
+        text = "camel.component.quartz.properties=123";
+        result = catalog.validateConfigurationProperty(text);
+        assertFalse(result.isSuccess());
+
+        text = "camel.component.quartz.properties.foo=123";
+        result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+
+        text = "camel.component.quartz.properties.bar=true";
+        result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+
+        text = "camel.component.quartz.properties[0]=yes";
+        result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+
+        text = "camel.component.quartz.properties[1]=no";
+        result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+
+        text = "camel.component.quartz.properties[foo]=abc";
+        result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+
+        text = "camel.component.quartz.properties[foo].beer=yes";
+        result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+
+        text = "camel.component.quartz.properties[foo].drink=no";
+        result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+    }
+
+    @Test
+    public void testValidateConfigurationPropertyComponentJClouds() throws Exception {
+        String text = "camel.component.jclouds.basicPropertyBinding=true";
+        ConfigurationPropertiesValidationResult result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+
+        text = "camel.component.jclouds.blobStores=#myStores";
+        result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+
+        text = "camel.component.jclouds.blobStores=foo";
+        result = catalog.validateConfigurationProperty(text);
+        assertFalse(result.isSuccess());
+        assertTrue(result.getInvalidArray().containsKey("camel.component.jclouds.blobStores"));
+
+        text = "camel.component.jclouds.blobStores[0]=foo";
+        result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+
+        text = "camel.component.jclouds.blobStores[1]=bar";
+        result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+
+        text = "camel.component.jclouds.blobStores[foo]=123";
+        result = catalog.validateConfigurationProperty(text);
+        assertFalse(result.isSuccess());
+        assertEquals("foo", result.getInvalidInteger().get("camel.component.jclouds.blobStores[foo]"));
+
+        text = "camel.component.jclouds.blobStores[0].beer=yes";
+        result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+
+        text = "camel.component.jclouds.blobStores[1].drink=no";
+        result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+
+        text = "camel.component.jclouds.blobStores[foo].beer=yes";
+        result = catalog.validateConfigurationProperty(text);
+        assertFalse(result.isSuccess());
+        assertEquals("foo", result.getInvalidInteger().get("camel.component.jclouds.blobStores[foo].beer"));
+    }
+
+    @Test
+    public void testValidateConfigurationPropertyMain() throws Exception {
+        String text = "camel.main.allow-use-original-message=true";
+        ConfigurationPropertiesValidationResult result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+
+        text = "camel.main.allow-use-original-message=abc";
+        result = catalog.validateConfigurationProperty(text);
+        assertFalse(result.isSuccess());
+        assertEquals("abc", result.getInvalidBoolean().get("camel.main.allow-use-original-message"));
+
+        text = "camel.main.foo=abc";
+        result = catalog.validateConfigurationProperty(text);
+        assertFalse(result.isSuccess());
+        assertTrue(result.getUnknown().contains("camel.main.foo"));
+
+        text = "camel.resilience4j.minimum-number-of-calls=123";
+        result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+
+        text = "camel.resilience4j.minimum-number-of-calls=abc";
+        result = catalog.validateConfigurationProperty(text);
+        assertFalse(result.isSuccess());
+        assertEquals("abc", result.getInvalidInteger().get("camel.resilience4j.minimum-number-of-calls"));
+
+        text = "camel.resilience4j.slow-call-rate-threshold=12.5";
+        result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+
+        text = "camel.resilience4j.slow-call-rate-threshold=12x5";
+        result = catalog.validateConfigurationProperty(text);
+        assertFalse(result.isSuccess());
+        assertEquals("12x5", result.getInvalidNumber().get("camel.resilience4j.slow-call-rate-threshold"));
+
+        text = "camel.rest.api-properties=#foo";
+        result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+
+        text = "camel.rest.api-properties=bar";
+        result = catalog.validateConfigurationProperty(text);
+        assertFalse(result.isSuccess());
+        assertEquals("bar", result.getInvalidMap().get("camel.rest.api-properties"));
+
+        text = "camel.rest.api-properties.foo=abc";
+        result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+
+        text = "camel.rest.api-properties.bar=123";
+        result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+
+        text = "camel.rest.api-properties.beer=yes";
+        result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+
+        // TODO: add support for [] maps for main
+//        text = "camel.rest.api-properties[drink]=no";
+//        result = catalog.validateConfigurationProperty(text);
+//        assertTrue(result.isSuccess());
+    }
+
 }
diff --git a/core/camel-api/src/main/java/org/apache/camel/runtimecatalog/ConfigurationPropertiesValidationResult.java b/core/camel-api/src/main/java/org/apache/camel/runtimecatalog/ConfigurationPropertiesValidationResult.java
new file mode 100644
index 0000000..14047b1
--- /dev/null
+++ b/core/camel-api/src/main/java/org/apache/camel/runtimecatalog/ConfigurationPropertiesValidationResult.java
@@ -0,0 +1,41 @@
+/*
+ * 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.runtimecatalog;
+
+/**
+ * Details result of validating configuration properties (eg application.properties for camel-main).
+ */
+public class ConfigurationPropertiesValidationResult extends EndpointValidationResult {
+
+    // TODO: Move stuff to base class for EndpointValidationResult so they can share code
+
+    private String key;
+    private String value;
+
+    public ConfigurationPropertiesValidationResult(String key, String value) {
+        this.key = key;
+        this.value = value;
+    }
+
+    public String getKey() {
+        return key;
+    }
+
+    public String getValue() {
+        return value;
+    }
+}
diff --git a/core/camel-api/src/main/java/org/apache/camel/runtimecatalog/EndpointValidationResult.java b/core/camel-api/src/main/java/org/apache/camel/runtimecatalog/EndpointValidationResult.java
index 091820a..6070f1d 100644
--- a/core/camel-api/src/main/java/org/apache/camel/runtimecatalog/EndpointValidationResult.java
+++ b/core/camel-api/src/main/java/org/apache/camel/runtimecatalog/EndpointValidationResult.java
@@ -51,6 +51,8 @@ public class EndpointValidationResult implements Serializable {
     private Map<String, String> invalidEnum;
     private Map<String, String[]> invalidEnumChoices;
     private Map<String, String[]> invalidEnumSuggestions;
+    private Map<String, String> invalidMap;
+    private Map<String, String> invalidArray;
     private Map<String, String> invalidReference;
     private Map<String, String> invalidBoolean;
     private Map<String, String> invalidInteger;
@@ -94,6 +96,9 @@ public class EndpointValidationResult implements Serializable {
             ok = invalidEnum == null && invalidEnumChoices == null && invalidReference == null
                 && invalidBoolean == null && invalidInteger == null && invalidNumber == null;
         }
+        if (ok) {
+           ok = invalidMap == null && invalidArray == null;
+        }
         return ok;
     }
 
@@ -191,6 +196,26 @@ public class EndpointValidationResult implements Serializable {
         }
     }
 
+    public void addInvalidMap(String name, String value) {
+        if (invalidMap == null) {
+            invalidMap = new LinkedHashMap<>();
+        }
+        if (!invalidMap.containsKey(name)) {
+            invalidMap.put(name, value);
+            errors++;
+        }
+    }
+
+    public void addInvalidArray(String name, String value) {
+        if (invalidArray == null) {
+            invalidArray = new LinkedHashMap<>();
+        }
+        if (!invalidArray.containsKey(name)) {
+            invalidArray.put(name, value);
+            errors++;
+        }
+    }
+
     public void addInvalidBoolean(String name, String value) {
         if (invalidBoolean == null) {
             invalidBoolean = new LinkedHashMap<>();
@@ -303,6 +328,14 @@ public class EndpointValidationResult implements Serializable {
         return invalidReference;
     }
 
+    public Map<String, String> getInvalidMap() {
+        return invalidMap;
+    }
+
+    public Map<String, String> getInvalidArray() {
+        return invalidArray;
+    }
+
     public Map<String, String> getInvalidBoolean() {
         return invalidBoolean;
     }
diff --git a/core/camel-api/src/main/java/org/apache/camel/runtimecatalog/JSonSchemaResolver.java b/core/camel-api/src/main/java/org/apache/camel/runtimecatalog/JSonSchemaResolver.java
index a6a8fc5..a849b0b 100644
--- a/core/camel-api/src/main/java/org/apache/camel/runtimecatalog/JSonSchemaResolver.java
+++ b/core/camel-api/src/main/java/org/apache/camel/runtimecatalog/JSonSchemaResolver.java
@@ -61,4 +61,11 @@ public interface JSonSchemaResolver {
      */
     String getModelJSonSchema(String name);
 
+    /**
+     * Returns the camel-main json schema
+     *
+     * @return the camel-main json schema
+     */
+    String getMainJsonSchema();
+
 }
diff --git a/core/camel-api/src/main/java/org/apache/camel/runtimecatalog/RuntimeCamelCatalog.java b/core/camel-api/src/main/java/org/apache/camel/runtimecatalog/RuntimeCamelCatalog.java
index 57bcda7..8228595 100644
--- a/core/camel-api/src/main/java/org/apache/camel/runtimecatalog/RuntimeCamelCatalog.java
+++ b/core/camel-api/src/main/java/org/apache/camel/runtimecatalog/RuntimeCamelCatalog.java
@@ -108,7 +108,7 @@ public interface RuntimeCamelCatalog extends StaticService {
     EndpointValidationResult validateProperties(String scheme, Map<String, String> properties);
 
     /**
-     * Parses and validates the endpoint uri and constructs a key/value properties of each option.
+     * Parses and validates the endpoint uri
      *
      * @param uri  the endpoint uri
      * @return validation result
@@ -116,7 +116,7 @@ public interface RuntimeCamelCatalog extends StaticService {
     EndpointValidationResult validateEndpointProperties(String uri);
 
     /**
-     * Parses and validates the endpoint uri and constructs a key/value properties of each option.
+     * Parses and validates the endpoint uri
      * <p/>
      * The option ignoreLenientProperties can be used to ignore components that uses lenient properties.
      * When this is true, then the uri validation is stricter but would fail on properties that are not part of the component
@@ -130,7 +130,7 @@ public interface RuntimeCamelCatalog extends StaticService {
     EndpointValidationResult validateEndpointProperties(String uri, boolean ignoreLenientProperties);
 
     /**
-     * Parses and validates the endpoint uri and constructs a key/value properties of each option.
+     * Parses and validates the endpoint uri
      * <p/>
      * The option ignoreLenientProperties can be used to ignore components that uses lenient properties.
      * When this is true, then the uri validation is stricter but would fail on properties that are not part of the component
@@ -170,6 +170,14 @@ public interface RuntimeCamelCatalog extends StaticService {
     LanguageValidationResult validateLanguageExpression(ClassLoader classLoader, String language, String text);
 
     /**
+     * Parses and validates the configuration property
+     *
+     * @param text  the configuration text
+     * @return validation result
+     */
+    ConfigurationPropertiesValidationResult validateConfigurationProperty(String text);
+
+    /**
      * Returns the component name from the given endpoint uri
      *
      * @param uri  the endpoint uri
diff --git a/core/camel-base/src/main/java/org/apache/camel/runtimecatalog/impl/AbstractCamelCatalog.java b/core/camel-base/src/main/java/org/apache/camel/runtimecatalog/impl/AbstractCamelCatalog.java
index fe32e5b..2e06468 100644
--- a/core/camel-base/src/main/java/org/apache/camel/runtimecatalog/impl/AbstractCamelCatalog.java
+++ b/core/camel-base/src/main/java/org/apache/camel/runtimecatalog/impl/AbstractCamelCatalog.java
@@ -26,6 +26,7 @@ import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
@@ -34,36 +35,18 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
+import org.apache.camel.runtimecatalog.ConfigurationPropertiesValidationResult;
 import org.apache.camel.runtimecatalog.EndpointValidationResult;
 import org.apache.camel.runtimecatalog.JSonSchemaResolver;
 import org.apache.camel.runtimecatalog.LanguageValidationResult;
 
 import static org.apache.camel.runtimecatalog.impl.CatalogHelper.after;
+import static org.apache.camel.runtimecatalog.impl.CatalogHelper.before;
 import static org.apache.camel.runtimecatalog.impl.URISupport.createQueryString;
 import static org.apache.camel.runtimecatalog.impl.URISupport.isEmpty;
 import static org.apache.camel.runtimecatalog.impl.URISupport.normalizeUri;
 import static org.apache.camel.runtimecatalog.impl.URISupport.stripQuery;
-import static org.apache.camel.support.JSonSchemaHelper.getNames;
-import static org.apache.camel.support.JSonSchemaHelper.getPropertyDefaultValue;
-import static org.apache.camel.support.JSonSchemaHelper.getPropertyEnum;
-import static org.apache.camel.support.JSonSchemaHelper.getPropertyKind;
-import static org.apache.camel.support.JSonSchemaHelper.getPropertyNameFromNameWithPrefix;
-import static org.apache.camel.support.JSonSchemaHelper.getPropertyPrefix;
-import static org.apache.camel.support.JSonSchemaHelper.getRow;
-import static org.apache.camel.support.JSonSchemaHelper.isComponentConsumerOnly;
-import static org.apache.camel.support.JSonSchemaHelper.isComponentLenientProperties;
-import static org.apache.camel.support.JSonSchemaHelper.isComponentProducerOnly;
-import static org.apache.camel.support.JSonSchemaHelper.isPropertyBoolean;
-import static org.apache.camel.support.JSonSchemaHelper.isPropertyConsumerOnly;
-import static org.apache.camel.support.JSonSchemaHelper.isPropertyDeprecated;
-import static org.apache.camel.support.JSonSchemaHelper.isPropertyInteger;
-import static org.apache.camel.support.JSonSchemaHelper.isPropertyMultiValue;
-import static org.apache.camel.support.JSonSchemaHelper.isPropertyNumber;
-import static org.apache.camel.support.JSonSchemaHelper.isPropertyObject;
-import static org.apache.camel.support.JSonSchemaHelper.isPropertyProducerOnly;
-import static org.apache.camel.support.JSonSchemaHelper.isPropertyRequired;
-import static org.apache.camel.support.JSonSchemaHelper.parseJsonSchema;
-import static org.apache.camel.support.JSonSchemaHelper.stripOptionalPrefixFromName;
+import static org.apache.camel.support.JSonSchemaHelper.*;
 
 /**
  * Base class for both the runtime RuntimeCamelCatalog from camel-core and the complete CamelCatalog from camel-catalog.
@@ -1036,6 +1019,228 @@ public abstract class AbstractCamelCatalog {
         return tokens.toArray(new String[tokens.size()]);
     }
 
+    public ConfigurationPropertiesValidationResult validateConfigurationProperty(String text) {
+        String longKey = before(text, "=");
+        String key = longKey;
+        String value = after(text, "=");
+
+        ConfigurationPropertiesValidationResult result = new ConfigurationPropertiesValidationResult(key, value);
+        boolean accept = acceptConfigurationPropertyKey(key);
+        if (!accept) {
+            result.addUnknown(key);
+            return result;
+        }
+
+        boolean component = key.startsWith("camel.component.");
+        boolean dataformat = key.startsWith("camel.dataformat.");
+        boolean language = key.startsWith("camel.language.");
+        boolean main = key.startsWith("camel.main.") || key.startsWith("camel.hystrix.") | key.startsWith("camel.resilience4j.") || key.startsWith("camel.rest.");
+        if (component || dataformat || language) {
+            String group;
+            if (component) {
+                key = key.substring(16);
+                group = "componentProperties";
+            } else if (dataformat) {
+                key = key.substring(17);
+                group = "properties";
+            } else {
+                key = key.substring(15);
+                group = "properties";
+            }
+            if (!key.contains(".")) {
+                result.addIncapable(key);
+                return result;
+            }
+            String name = before(key, ".");
+            String option = after(key, ".");
+            if (name != null && option != null && value != null) {
+                String json;
+                if (component) {
+                    json = jsonSchemaResolver.getComponentJSonSchema(name);
+                } else if (dataformat) {
+                    json = jsonSchemaResolver.getDataFormatJSonSchema(name);
+                } else {
+                    json = jsonSchemaResolver.getLanguageJSonSchema(name);
+                }
+                if (json == null) {
+                    result.addUnknownComponent(name);
+                    return result;
+                }
+                List<Map<String, String>> rows = parseJsonSchema(group, json, true);
+
+                // lower case option and remove dash
+                String nOption = option.replaceAll("-", "").toLowerCase(Locale.US);
+                String suffix = null;
+                int posDot = nOption.indexOf('.');
+                int posBracket = nOption.indexOf('[');
+                if (posDot > 0 && posBracket > 0) {
+                    int first = Math.min(posDot, posBracket);
+                    suffix = nOption.substring(first);
+                    nOption = nOption.substring(0, first);
+                } else if (posDot > 0) {
+                    suffix = nOption.substring(posDot);
+                    nOption = nOption.substring(0, posDot);
+                } else if (posBracket > 0) {
+                    suffix = nOption.substring(posBracket);
+                    nOption = nOption.substring(0, posBracket);
+                }
+                doValidateConfigurationProperty(result, rows, name, value, longKey, nOption, suffix);
+            }
+        } else if (main) {
+            // skip camel.
+            key = key.substring(6);
+            String name = before(key, ".");
+            String option = after(key, ".");
+            if (name != null && option != null && value != null) {
+                String json = jsonSchemaResolver.getMainJsonSchema();
+                if (json == null) {
+                    result.addIncapable("camel-main not detected on classpath");
+                    return result;
+                }
+                List<Map<String, String>> rows = parseMainJsonSchema(json);
+
+                // lower case option and remove dash
+                String lookupKey = longKey.replaceAll("-", "").toLowerCase(Locale.US);
+                String suffix = null;
+                int pos = option.indexOf('.');
+                // TODO: add support for [] maps for main
+                if (pos > 0 && option.length() > pos) {
+                    suffix = option.substring(pos + 1);
+                    // remove .suffix from lookup key
+                    int len = lookupKey.length() - suffix.length() - 1;
+                    lookupKey = lookupKey.substring(0, len);
+                }
+                doValidateConfigurationProperty(result, rows, name, value, longKey, lookupKey, suffix);
+            }
+        }
+
+        return result;
+    }
+
+    private void doValidateConfigurationProperty(ConfigurationPropertiesValidationResult result, List<Map<String, String>> rows,
+                                                 String name, String value, String longKey,
+                                                 String lookupKey, String suffix) {
+
+        // find option
+        String rowKey = rows.stream()
+                .map(e -> e.get("name"))
+                .filter(n -> n.toLowerCase(Locale.US).equals(lookupKey)).findFirst().orElse(null);
+        if (rowKey == null) {
+            // unknown option
+            result.addUnknown(longKey);
+            if (suggestionStrategy != null) {
+                String[] suggestions = suggestionStrategy.suggestEndpointOptions(getNames(rows), name);
+                if (suggestions != null) {
+                    result.addUnknownSuggestions(name, suggestions);
+                }
+            }
+        } else {
+            boolean optionPlaceholder = value.startsWith("{{") || value.startsWith("${") || value.startsWith("$simple{");
+            boolean lookup = value.startsWith("#") && value.length() > 1;
+
+            // deprecated
+            if (!optionPlaceholder && !lookup && isPropertyDeprecated(rows, rowKey)) {
+                result.addDeprecated(longKey);
+            }
+
+            // is boolean
+            if (!optionPlaceholder && !lookup && isPropertyBoolean(rows, rowKey)) {
+                // value must be a boolean
+                boolean bool = "true".equalsIgnoreCase(value) || "false".equalsIgnoreCase(value);
+                if (!bool) {
+                    result.addInvalidBoolean(longKey, value);
+                }
+            }
+
+            // is integer
+            if (!optionPlaceholder && !lookup && isPropertyInteger(rows, rowKey)) {
+                // value must be an integer
+                boolean valid = validateInteger(value);
+                if (!valid) {
+                    result.addInvalidInteger(longKey, value);
+                }
+            }
+
+            // is number
+            if (!optionPlaceholder && !lookup && isPropertyNumber(rows, rowKey)) {
+                // value must be an number
+                boolean valid = false;
+                try {
+                    valid = !Double.valueOf(value).isNaN() || !Float.valueOf(value).isNaN();
+                } catch (Exception e) {
+                    // ignore
+                }
+                if (!valid) {
+                    result.addInvalidNumber(longKey, value);
+                }
+            }
+
+            // is enum
+            String enums = getPropertyEnum(rows, rowKey);
+            if (!optionPlaceholder && !lookup && enums != null) {
+                String[] choices = enums.split(",");
+                boolean found = false;
+                for (String s : choices) {
+                    if (value.equalsIgnoreCase(s)) {
+                        found = true;
+                        break;
+                    }
+                }
+                if (!found) {
+                    result.addInvalidEnum(longKey, value);
+                    result.addInvalidEnumChoices(longKey, choices);
+                    if (suggestionStrategy != null) {
+                        Set<String> names = new LinkedHashSet<>();
+                        names.addAll(Arrays.asList(choices));
+                        String[] suggestions = suggestionStrategy.suggestEndpointOptions(names, value);
+                        if (suggestions != null) {
+                            result.addInvalidEnumSuggestions(longKey, suggestions);
+                        }
+                    }
+                }
+            }
+
+            String javaType = getPropertyJavaType(rows, rowKey);
+            if (!optionPlaceholder && !lookup && javaType != null
+                    && (javaType.startsWith("java.util.Map") || javaType.startsWith("java.util.Properties"))) {
+                // there must be a valid suffix
+                if (suffix == null || suffix.isEmpty() || suffix.equals(".")) {
+                    result.addInvalidMap(longKey, value);
+                } else if (suffix.startsWith("[") && !suffix.contains("]")) {
+                    result.addInvalidMap(longKey, value);
+                }
+            }
+            if (!optionPlaceholder && !lookup && javaType != null && isPropertyArray(rows, rowKey)) {
+                // there must be a suffix and it must be using [] style
+                if (suffix == null || suffix.isEmpty() || suffix.equals(".")) {
+                    result.addInvalidArray(longKey, value);
+                } else if (!suffix.startsWith("[") && !suffix.contains("]")) {
+                    result.addInvalidArray(longKey, value);
+                } else {
+                    String index = before(suffix.substring(1), "]");
+                    // value must be an integer
+                    boolean valid = validateInteger(index);
+                    if (!valid) {
+                        result.addInvalidInteger(longKey, index);
+                    }
+                }
+            }
+        }
+    }
+
+    private static boolean acceptConfigurationPropertyKey(String key) {
+        if (key == null) {
+            return false;
+        }
+        return key.startsWith("camel.component.")
+                || key.startsWith("camel.dataformat.")
+                || key.startsWith("camel.language.")
+                || key.startsWith("camel.main.")
+                || key.startsWith("camel.hystrix.")
+                || key.startsWith("camel.resilience4j.")
+                || key.startsWith("camel.rest.");
+    }
+
     private LanguageValidationResult doValidateSimple(ClassLoader classLoader, String simple, boolean predicate) {
         if (classLoader == null) {
             classLoader = getClass().getClassLoader();
@@ -1225,7 +1430,8 @@ public abstract class AbstractCamelCatalog {
     private static boolean validateInteger(String value) {
         boolean valid = false;
         try {
-            valid = Integer.valueOf(value) != null;
+            Integer.parseInt(value);
+            valid = true;
         } catch (Exception e) {
             // ignore
         }
diff --git a/core/camel-base/src/main/java/org/apache/camel/runtimecatalog/impl/CamelContextJSonSchemaResolver.java b/core/camel-base/src/main/java/org/apache/camel/runtimecatalog/impl/CamelContextJSonSchemaResolver.java
index ac8f092..9e92aa5 100644
--- a/core/camel-base/src/main/java/org/apache/camel/runtimecatalog/impl/CamelContextJSonSchemaResolver.java
+++ b/core/camel-base/src/main/java/org/apache/camel/runtimecatalog/impl/CamelContextJSonSchemaResolver.java
@@ -17,10 +17,13 @@
 package org.apache.camel.runtimecatalog.impl;
 
 import java.io.IOException;
+import java.io.InputStream;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.CatalogCamelContext;
 import org.apache.camel.runtimecatalog.JSonSchemaResolver;
+import org.apache.camel.spi.ClassResolver;
+import org.apache.camel.util.IOHelper;
 
 /**
  * Uses runtime {@link CamelContext} to resolve the JSon schema files.
@@ -79,4 +82,20 @@ public class CamelContextJSonSchemaResolver implements JSonSchemaResolver {
         return null;
     }
 
+    @Override
+    public String getMainJsonSchema() {
+        String path = "META-INF/camel-main-configuration-metadata.json";
+        ClassResolver resolver = camelContext.getClassResolver();
+        InputStream inputStream = resolver.loadResourceAsStream(path);
+        if (inputStream != null) {
+            try {
+                return IOHelper.loadText(inputStream);
+            } catch (IOException e) {
+                // ignore
+            } finally {
+                IOHelper.close(inputStream);
+            }
+        }
+        return null;
+    }
 }
diff --git a/core/camel-core/src/test/java/org/apache/camel/runtimecatalog/impl/RuntimeCamelCatalogTest.java b/core/camel-core/src/test/java/org/apache/camel/runtimecatalog/impl/RuntimeCamelCatalogTest.java
index 37d79a8..93693f3 100644
--- a/core/camel-core/src/test/java/org/apache/camel/runtimecatalog/impl/RuntimeCamelCatalogTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/runtimecatalog/impl/RuntimeCamelCatalogTest.java
@@ -20,6 +20,7 @@ import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.runtimecatalog.ConfigurationPropertiesValidationResult;
 import org.apache.camel.runtimecatalog.EndpointValidationResult;
 import org.apache.camel.runtimecatalog.LanguageValidationResult;
 import org.apache.camel.runtimecatalog.RuntimeCamelCatalog;
@@ -28,10 +29,8 @@ import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+
+import static org.junit.Assert.*;
 
 public class RuntimeCamelCatalogTest {
 
@@ -376,4 +375,50 @@ public class RuntimeCamelCatalogTest {
         assertEquals("delete", result.getNotProducerOnly().iterator().next());
     }
 
+    @Test
+    public void testValidateConfigurationPropertyComponent() throws Exception {
+        String text = "camel.component.seda.queueSize=1234";
+        ConfigurationPropertiesValidationResult result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+
+        text = "camel.component.seda.queue-size=1234";
+        result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+
+        text = "camel.component.seda.queuesize=1234";
+        result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+
+        text = "camel.component.seda.queueSize=abc";
+        result = catalog.validateConfigurationProperty(text);
+        assertFalse(result.isSuccess());
+        assertEquals("abc", result.getInvalidInteger().get("camel.component.seda.queueSize"));
+
+        text = "camel.component.seda.foo=abc";
+        result = catalog.validateConfigurationProperty(text);
+        assertFalse(result.isSuccess());
+        assertTrue(result.getUnknown().contains("camel.component.seda.foo"));
+    }
+
+    @Test
+    public void testValidateConfigurationPropertyLanguage() throws Exception {
+        String text = "camel.language.tokenize.token=;";
+        ConfigurationPropertiesValidationResult result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+
+        text = "camel.language.tokenize.regex=true";
+        result = catalog.validateConfigurationProperty(text);
+        assertTrue(result.isSuccess());
+
+        text = "camel.language.tokenize.regex=abc";
+        result = catalog.validateConfigurationProperty(text);
+        assertFalse(result.isSuccess());
+        assertEquals("abc", result.getInvalidBoolean().get("camel.language.tokenize.regex"));
+
+        text = "camel.language.tokenize.foo=abc";
+        result = catalog.validateConfigurationProperty(text);
+        assertFalse(result.isSuccess());
+        assertTrue(result.getUnknown().contains("camel.language.tokenize.foo"));
+    }
+
 }
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/JSonSchemaHelper.java b/core/camel-support/src/main/java/org/apache/camel/support/JSonSchemaHelper.java
index 6c77d3f..fc90ac9 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/JSonSchemaHelper.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/JSonSchemaHelper.java
@@ -24,6 +24,7 @@ import java.util.Map;
 import java.util.Set;
 import java.util.stream.Collectors;
 
+import org.apache.camel.util.json.JsonArray;
 import org.apache.camel.util.json.JsonObject;
 import org.apache.camel.util.json.Jsoner;
 
@@ -36,6 +37,69 @@ public final class JSonSchemaHelper {
     }
 
     /**
+     * Parses the camel-main json schema to split it into a list or rows, where each row contains key value pairs with the metadata
+     *
+     * @param json the main configuration json
+     * @return a list of all the rows, where each row is a set of key value pairs with metadata
+     * @throws RuntimeException is thrown if error parsing the json data
+     */
+    @SuppressWarnings("unchecked")
+    public static List<Map<String, String>> parseMainJsonSchema(String json) {
+        List<Map<String, String>> answer = new ArrayList<>();
+        if (json == null) {
+            return answer;
+        }
+
+        // convert into a List<Map<String, String>> structure which is expected as output from this parser
+        try {
+            JsonObject output = (JsonObject) Jsoner.deserialize(json);
+            for (String key : output.keySet()) {
+                JsonArray array = (JsonArray) output.get(key);
+                if (key.equals("properties")) {
+                    // flattern each entry in the row with name as they key, and its value as the content (its a map also)
+                    for (Object obj : array) {
+                        Map entry = (Map) obj;
+                        Map<String, String> newRow = new LinkedHashMap();
+                        newRow.putAll(entry);
+                        answer.add(newRow);
+                        String name = ((Map) obj).get("name").toString();
+                        // use naming style with camel case
+                        String lookupKey = dashToCamelCase(name);
+                        newRow.put("name", lookupKey);
+                        // its the java type
+                        String type = newRow.get("type");
+                        newRow.put("javaType", type);
+                        newRow.put("type", fromMainToType(type));
+                    }
+                }
+            }
+        } catch (Exception e) {
+            // wrap parsing exceptions as runtime
+            throw new RuntimeException("Cannot parse json", e);
+        }
+
+        return answer;
+    }
+
+    private static String fromMainToType(String type) {
+        if ("boolean".equals(type) || "java.lang.Boolean".equals(type)) {
+            return "boolean";
+        } else if ("int".equals(type) || "java.lang.Integer".equals(type)) {
+            return "integer";
+        } else if ("long".equals(type) || "java.lang.Long".equals(type)) {
+            return "integer";
+        } else if ("float".equals(type) || "java.lang.Float".equals(type)) {
+            return "number";
+        } else if ("double".equals(type) || "java.lang.Double".equals(type)) {
+            return "number";
+        } else if ("string".equals(type) || "java.lang.String".equals(type)) {
+            return "string";
+        } else {
+            return "object";
+        }
+    }
+
+    /**
      * Parses the json schema to split it into a list or rows, where each row contains key value pairs with the metadata
      *
      * @param group the group to parse from such as <tt>component</tt>, <tt>componentProperties</tt>, or <tt>properties</tt>.
@@ -150,7 +214,7 @@ public final class JSonSchemaHelper {
             String labels = null;
             boolean found = false;
             if (row.containsKey("name")) {
-                found = name.equals(row.get("name"));
+                found = name.equalsIgnoreCase(row.get("name"));
             }
             if (row.containsKey("label")) {
                 labels = row.get("label");
@@ -167,7 +231,7 @@ public final class JSonSchemaHelper {
             String labels = null;
             boolean found = false;
             if (row.containsKey("name")) {
-                found = name.equals(row.get("name"));
+                found = name.equalsIgnoreCase(row.get("name"));
             }
             if (row.containsKey("label")) {
                 labels = row.get("label");
@@ -184,7 +248,7 @@ public final class JSonSchemaHelper {
             boolean required = false;
             boolean found = false;
             if (row.containsKey("name")) {
-                found = name.equals(row.get("name"));
+                found = name.equalsIgnoreCase(row.get("name"));
             }
             if (row.containsKey("required")) {
                 required = "true".equals(row.get("required"));
@@ -201,7 +265,7 @@ public final class JSonSchemaHelper {
             boolean deprecated = false;
             boolean found = false;
             if (row.containsKey("name")) {
-                found = name.equals(row.get("name"));
+                found = name.equalsIgnoreCase(row.get("name"));
             }
             if (row.containsKey("deprecated")) {
                 deprecated = "true".equals(row.get("deprecated"));
@@ -218,7 +282,7 @@ public final class JSonSchemaHelper {
             String kind = null;
             boolean found = false;
             if (row.containsKey("name")) {
-                found = name.equals(row.get("name"));
+                found = name.equalsIgnoreCase(row.get("name"));
             }
             if (row.containsKey("kind")) {
                 kind = row.get("kind");
@@ -230,12 +294,29 @@ public final class JSonSchemaHelper {
         return null;
     }
 
+    public static String getPropertyJavaType(List<Map<String, String>> rows, String name) {
+        for (Map<String, String> row : rows) {
+            String javaType = null;
+            boolean found = false;
+            if (row.containsKey("name")) {
+                found = name.equalsIgnoreCase(row.get("name"));
+            }
+            if (row.containsKey("javaType")) {
+                javaType = row.get("javaType");
+            }
+            if (found) {
+                return javaType;
+            }
+        }
+        return null;
+    }
+
     public static boolean isPropertyBoolean(List<Map<String, String>> rows, String name) {
         for (Map<String, String> row : rows) {
             String type = null;
             boolean found = false;
             if (row.containsKey("name")) {
-                found = name.equals(row.get("name"));
+                found = name.equalsIgnoreCase(row.get("name"));
             }
             if (row.containsKey("type")) {
                 type = row.get("type");
@@ -252,7 +333,7 @@ public final class JSonSchemaHelper {
             String type = null;
             boolean found = false;
             if (row.containsKey("name")) {
-                found = name.equals(row.get("name"));
+                found = name.equalsIgnoreCase(row.get("name"));
             }
             if (row.containsKey("type")) {
                 type = row.get("type");
@@ -264,12 +345,29 @@ public final class JSonSchemaHelper {
         return false;
     }
 
+    public static boolean isPropertyArray(List<Map<String, String>> rows, String name) {
+        for (Map<String, String> row : rows) {
+            String type = null;
+            boolean found = false;
+            if (row.containsKey("name")) {
+                found = name.equalsIgnoreCase(row.get("name"));
+            }
+            if (row.containsKey("type")) {
+                type = row.get("type");
+            }
+            if (found) {
+                return "array".equals(type);
+            }
+        }
+        return false;
+    }
+
     public static boolean isPropertyNumber(List<Map<String, String>> rows, String name) {
         for (Map<String, String> row : rows) {
             String type = null;
             boolean found = false;
             if (row.containsKey("name")) {
-                found = name.equals(row.get("name"));
+                found = name.equalsIgnoreCase(row.get("name"));
             }
             if (row.containsKey("type")) {
                 type = row.get("type");
@@ -286,7 +384,7 @@ public final class JSonSchemaHelper {
             String type = null;
             boolean found = false;
             if (row.containsKey("name")) {
-                found = name.equals(row.get("name"));
+                found = name.equalsIgnoreCase(row.get("name"));
             }
             if (row.containsKey("type")) {
                 type = row.get("type");
@@ -303,7 +401,7 @@ public final class JSonSchemaHelper {
             String defaultValue = null;
             boolean found = false;
             if (row.containsKey("name")) {
-                found = name.equals(row.get("name"));
+                found = name.equalsIgnoreCase(row.get("name"));
             }
             if (row.containsKey("defaultValue")) {
                 defaultValue = row.get("defaultValue");
@@ -328,7 +426,7 @@ public final class JSonSchemaHelper {
                     // try again
                     return stripOptionalPrefixFromName(rows, name);
                 } else {
-                    found = name.equals(row.get("name"));
+                    found = name.equalsIgnoreCase(row.get("name"));
                 }
             }
             if (found) {
@@ -343,7 +441,7 @@ public final class JSonSchemaHelper {
             String enums = null;
             boolean found = false;
             if (row.containsKey("name")) {
-                found = name.equals(row.get("name"));
+                found = name.equalsIgnoreCase(row.get("name"));
             }
             if (row.containsKey("enum")) {
                 enums = row.get("enum");
@@ -360,7 +458,7 @@ public final class JSonSchemaHelper {
             String prefix = null;
             boolean found = false;
             if (row.containsKey("name")) {
-                found = name.equals(row.get("name"));
+                found = name.equalsIgnoreCase(row.get("name"));
             }
             if (row.containsKey("prefix")) {
                 prefix = row.get("prefix");
@@ -377,7 +475,7 @@ public final class JSonSchemaHelper {
             boolean multiValue = false;
             boolean found = false;
             if (row.containsKey("name")) {
-                found = name.equals(row.get("name"));
+                found = name.equalsIgnoreCase(row.get("name"));
             }
             if (row.containsKey("multiValue")) {
                 multiValue = "true".equals(row.get("multiValue"));
@@ -426,4 +524,35 @@ public final class JSonSchemaHelper {
         return answer;
     }
 
+    /**
+     * Converts the string from dash format into camel case (hello-great-world -> helloGreatWorld)
+     *
+     * @param text  the string
+     * @return the string camel cased
+     */
+    private static String dashToCamelCase(String text) {
+        if (text == null) {
+            return null;
+        }
+        int length = text.length();
+        if (length == 0) {
+            return text;
+        }
+        if (text.indexOf('-') == -1) {
+            return text;
+        }
+
+        StringBuilder sb = new StringBuilder();
+
+        for (int i = 0; i < text.length(); i++) {
+            char c = text.charAt(i);
+            if (c == '-') {
+                i++;
+                sb.append(Character.toUpperCase(text.charAt(i)));
+            } else {
+                sb.append(c);
+            }
+        }
+        return sb.toString();
+    }
 }
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 25d5bd8..1a09199 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
@@ -713,7 +713,7 @@ public final class PropertyBindingSupport {
         } else if (answer instanceof List) {
             List list = (List) answer;
             if (isNotEmpty(lookupKey)) {
-                int idx = Integer.valueOf(lookupKey);
+                int idx = Integer.parseInt(lookupKey);
                 answer = list.get(idx);
             } else {
                 if (list.isEmpty()) {