CAMEL-10680: Camel catalog - validate endpoint properties - consumer vs producer. And fixed a bug in validator.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/28f4bfe0 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/28f4bfe0 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/28f4bfe0 Branch: refs/heads/camel-2.18.x Commit: 28f4bfe018685d92848970c32e98f1e40059127c Parents: e074e27 Author: Claus Ibsen <davscl...@apache.org> Authored: Mon Jan 9 12:08:12 2017 +0100 Committer: Claus Ibsen <davscl...@apache.org> Committed: Mon Jan 9 12:08:44 2017 +0100 ---------------------------------------------------------------------- .../org/apache/camel/catalog/CamelCatalog.java | 16 ++++++++ .../camel/catalog/DefaultCamelCatalog.java | 30 ++++++++++++-- .../camel/catalog/EndpointValidationResult.java | 43 ++++++++++++++++++++ .../apache/camel/catalog/JSonSchemaHelper.java | 34 ++++++++++++++++ .../apache/camel/catalog/CamelCatalogTest.java | 26 ++++++++++++ 5 files changed, 146 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/28f4bfe0/platforms/catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java ---------------------------------------------------------------------- diff --git a/platforms/catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java b/platforms/catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java index 426cd02..1e5474a 100644 --- a/platforms/catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java +++ b/platforms/catalog/src/main/java/org/apache/camel/catalog/CamelCatalog.java @@ -313,6 +313,22 @@ public interface CamelCatalog { EndpointValidationResult validateEndpointProperties(String uri, boolean ignoreLenientProperties); /** + * Parses and validates the endpoint uri and constructs a key/value properties of each option. + * <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 + * but in the uri because of using lenient properties. + * For example using the HTTP components to provide query parameters in the endpoint uri. + * + * @param uri the endpoint uri + * @param ignoreLenientProperties whether to ignore components that uses lenient properties. + * @param consumerOnly whether the endpoint is only used as a consumer + * @param producerOnly whether the endpoint is only used as a producer + * @return validation result + */ + EndpointValidationResult validateEndpointProperties(String uri, boolean ignoreLenientProperties, boolean consumerOnly, boolean producerOnly); + + /** * Parses and validates the simple expression. * <p/> * <b>Important:</b> This requires having <tt>camel-core</tt> on the classpath http://git-wip-us.apache.org/repos/asf/camel/blob/28f4bfe0/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java ---------------------------------------------------------------------- diff --git a/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java b/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java index 0292f2b..14457e7 100644 --- a/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java +++ b/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java @@ -54,10 +54,12 @@ import static org.apache.camel.catalog.JSonSchemaHelper.getPropertyPrefix; import static org.apache.camel.catalog.JSonSchemaHelper.getRow; import static org.apache.camel.catalog.JSonSchemaHelper.isComponentLenientProperties; import static org.apache.camel.catalog.JSonSchemaHelper.isPropertyBoolean; +import static org.apache.camel.catalog.JSonSchemaHelper.isPropertyConsumerOnly; import static org.apache.camel.catalog.JSonSchemaHelper.isPropertyInteger; import static org.apache.camel.catalog.JSonSchemaHelper.isPropertyMultiValue; import static org.apache.camel.catalog.JSonSchemaHelper.isPropertyNumber; import static org.apache.camel.catalog.JSonSchemaHelper.isPropertyObject; +import static org.apache.camel.catalog.JSonSchemaHelper.isPropertyProducerOnly; import static org.apache.camel.catalog.JSonSchemaHelper.isPropertyRequired; import static org.apache.camel.catalog.JSonSchemaHelper.stripOptionalPrefixFromName; import static org.apache.camel.catalog.URISupport.createQueryString; @@ -960,11 +962,16 @@ public class DefaultCamelCatalog implements CamelCatalog { @Override public EndpointValidationResult validateEndpointProperties(String uri) { - return validateEndpointProperties(uri, false); + return validateEndpointProperties(uri, false, false, false); } @Override public EndpointValidationResult validateEndpointProperties(String uri, boolean ignoreLenientProperties) { + return validateEndpointProperties(uri, ignoreLenientProperties,false, false); + } + + @Override + public EndpointValidationResult validateEndpointProperties(String uri, boolean ignoreLenientProperties, boolean consumerOnly, boolean producerOnly) { EndpointValidationResult result = new EndpointValidationResult(uri); Map<String, String> properties; @@ -1057,6 +1064,23 @@ public class DefaultCamelCatalog implements CamelCatalog { } } } else { + if ("parameter".equals(kind)) { + // consumer only or producer only mode for parameters + if (consumerOnly) { + boolean producer = isPropertyProducerOnly(rows, name); + if (producer) { + // the option is only for producer so you cannot use it in consumer mode + result.addNotConsumerOnly(name); + } + } else if (producerOnly) { + boolean consumer = isPropertyConsumerOnly(rows, name); + if (consumer) { + // the option is only for consumer so you cannot use it in producer mode + result.addNotProducerOnly(name); + } + } + } + // default value String defaultValue = getPropertyDefaultValue(rows, name); if (defaultValue != null) { @@ -1096,8 +1120,8 @@ public class DefaultCamelCatalog implements CamelCatalog { } } - // is reference lookup of bean (not applicable for @UriPath, or multi-valued) - if (!mulitValue && !"path".equals(kind) && isPropertyObject(rows, name)) { + // is reference lookup of bean (not applicable for @UriPath, enums, or multi-valued) + if (!mulitValue && enums == null && !"path".equals(kind) && isPropertyObject(rows, name)) { // must start with # and be at least 2 characters if (!value.startsWith("#") || value.length() <= 1) { result.addInvalidReference(name, value); http://git-wip-us.apache.org/repos/asf/camel/blob/28f4bfe0/platforms/catalog/src/main/java/org/apache/camel/catalog/EndpointValidationResult.java ---------------------------------------------------------------------- diff --git a/platforms/catalog/src/main/java/org/apache/camel/catalog/EndpointValidationResult.java b/platforms/catalog/src/main/java/org/apache/camel/catalog/EndpointValidationResult.java index d1f31e6..fa2515e 100644 --- a/platforms/catalog/src/main/java/org/apache/camel/catalog/EndpointValidationResult.java +++ b/platforms/catalog/src/main/java/org/apache/camel/catalog/EndpointValidationResult.java @@ -41,6 +41,8 @@ public class EndpointValidationResult implements Serializable { // options private Set<String> unknown; private Map<String, String[]> unknownSuggestions; + private Set<String> notConsumerOnly; + private Set<String> notProducerOnly; private Set<String> required; private Map<String, String> invalidEnum; private Map<String, String[]> invalidEnumChoices; @@ -67,6 +69,9 @@ public class EndpointValidationResult implements Serializable { boolean ok = syntaxError == null && unknownComponent == null && incapable == null && unknown == null && required == null; if (ok) { + ok = notConsumerOnly == null && notProducerOnly == null; + } + if (ok) { ok = invalidEnum == null && invalidEnumChoices == null && invalidReference == null && invalidBoolean == null && invalidInteger == null && invalidNumber == null; } @@ -186,6 +191,26 @@ public class EndpointValidationResult implements Serializable { defaultValues.put(name, value); } + public void addNotConsumerOnly(String name) { + if (notConsumerOnly == null) { + notConsumerOnly = new LinkedHashSet<String>(); + } + if (!notConsumerOnly.contains(name)) { + notConsumerOnly.add(name); + errors++; + } + } + + public void addNotProducerOnly(String name) { + if (notProducerOnly == null) { + notProducerOnly = new LinkedHashSet<String>(); + } + if (!notProducerOnly.contains(name)) { + notProducerOnly.add(name); + errors++; + } + } + public String getSyntaxError() { return syntaxError; } @@ -238,6 +263,14 @@ public class EndpointValidationResult implements Serializable { return defaultValues; } + public Set<String> getNotConsumerOnly() { + return notConsumerOnly; + } + + public Set<String> getNotProducerOnly() { + return notProducerOnly; + } + /** * A human readable summary of the validation errors. * @@ -274,6 +307,16 @@ public class EndpointValidationResult implements Serializable { } } } + if (notConsumerOnly != null) { + for (String name : notConsumerOnly) { + options.put(name, "Option not applicable in consumer only mode"); + } + } + if (notProducerOnly != null) { + for (String name : notProducerOnly) { + options.put(name, "Option not applicable in producer only mode"); + } + } if (required != null) { for (String name : required) { options.put(name, "Missing required option"); http://git-wip-us.apache.org/repos/asf/camel/blob/28f4bfe0/platforms/catalog/src/main/java/org/apache/camel/catalog/JSonSchemaHelper.java ---------------------------------------------------------------------- diff --git a/platforms/catalog/src/main/java/org/apache/camel/catalog/JSonSchemaHelper.java b/platforms/catalog/src/main/java/org/apache/camel/catalog/JSonSchemaHelper.java index 3a31027..3acffdf 100644 --- a/platforms/catalog/src/main/java/org/apache/camel/catalog/JSonSchemaHelper.java +++ b/platforms/catalog/src/main/java/org/apache/camel/catalog/JSonSchemaHelper.java @@ -123,6 +123,40 @@ public final class JSonSchemaHelper { return false; } + public static boolean isPropertyConsumerOnly(List<Map<String, String>> rows, String name) { + for (Map<String, String> row : rows) { + String labels = null; + boolean found = false; + if (row.containsKey("name")) { + found = name.equals(row.get("name")); + } + if (row.containsKey("label")) { + labels = row.get("label"); + } + if (found) { + return labels != null && labels.contains("consumer"); + } + } + return false; + } + + public static boolean isPropertyProducerOnly(List<Map<String, String>> rows, String name) { + for (Map<String, String> row : rows) { + String labels = null; + boolean found = false; + if (row.containsKey("name")) { + found = name.equals(row.get("name")); + } + if (row.containsKey("label")) { + labels = row.get("label"); + } + if (found) { + return labels != null && labels.contains("producer"); + } + } + return false; + } + public static boolean isPropertyRequired(List<Map<String, String>> rows, String name) { for (Map<String, String> row : rows) { boolean required = false; http://git-wip-us.apache.org/repos/asf/camel/blob/28f4bfe0/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java ---------------------------------------------------------------------- diff --git a/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java b/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java index 85a6076..6380941 100644 --- a/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java +++ b/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java @@ -878,4 +878,30 @@ public class CamelCatalogTest { assertTrue(result.isSuccess()); } + @Test + public void testValidateEndpointConsumerOnly() throws Exception { + String uri = "file:inbox?bufferSize=4096&readLock=changed&delete=true"; + EndpointValidationResult result = catalog.validateEndpointProperties(uri, false, true, false); + assertTrue(result.isSuccess()); + + uri = "file:inbox?bufferSize=4096&readLock=changed&delete=true&fileExist=Append"; + result = catalog.validateEndpointProperties(uri, false, true, false); + assertFalse(result.isSuccess()); + + assertEquals("fileExist", result.getNotConsumerOnly().iterator().next()); + } + + @Test + public void testValidateEndpointProducerOnly() throws Exception { + String uri = "file:outbox?bufferSize=4096&fileExist=Append"; + EndpointValidationResult result = catalog.validateEndpointProperties(uri, false, false, true); + assertTrue(result.isSuccess()); + + uri = "file:outbox?bufferSize=4096&fileExist=Append&delete=true"; + result = catalog.validateEndpointProperties(uri, false, false, true); + assertFalse(result.isSuccess()); + + assertEquals("delete", result.getNotProducerOnly().iterator().next()); + } + }