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 2017/02/22 14:27:50 UTC

[4/4] camel git commit: CAMEL-10538 Add declarative validator according to input/output type

CAMEL-10538 Add declarative validator according to input/output type


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/f9946b2e
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/f9946b2e
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/f9946b2e

Branch: refs/heads/master
Commit: f9946b2e811884d58c1e5f164866591f07b7d064
Parents: f507f4e
Author: Tomohisa Igarashi <tm...@gmail.com>
Authored: Wed Feb 15 09:18:37 2017 +0900
Committer: Claus Ibsen <da...@apache.org>
Committed: Wed Feb 22 14:00:32 2017 +0100

----------------------------------------------------------------------
 .../src/main/resources/camel-checkstyle.xml     |   2 +-
 camel-core/src/main/docs/transformer.adoc       |  19 +-
 camel-core/src/main/docs/validator.adoc         | 190 +++++++++++++++
 .../java/org/apache/camel/CamelContext.java     |  33 ++-
 .../main/java/org/apache/camel/Exchange.java    |   2 +
 .../management/mbean/CamelOpenMBeanTypes.java   |  12 +
 .../mbean/ManagedValidatorRegistryMBean.java    |  47 ++++
 .../org/apache/camel/builder/RouteBuilder.java  |  23 ++
 .../camel/builder/TransformerBuilder.java       |   2 +-
 .../apache/camel/builder/ValidatorBuilder.java  | 166 +++++++++++++
 .../apache/camel/impl/DefaultCamelContext.java  |  74 +++---
 .../apache/camel/impl/DefaultRouteContext.java  |   2 +
 .../camel/impl/DefaultTransformerRegistry.java  |  84 +++++--
 .../camel/impl/DefaultValidatorRegistry.java    | 231 +++++++++++++++++++
 .../camel/impl/transformer/TransformerKey.java  |  32 ++-
 .../impl/validator/ProcessorValidator.java      |  99 ++++++++
 .../camel/impl/validator/ValidatorKey.java      |  48 ++++
 .../DefaultManagementLifecycleStrategy.java     |   4 +
 .../mbean/ManagedTransformerRegistry.java       |   6 +-
 .../mbean/ManagedValidatorRegistry.java         | 102 ++++++++
 .../java/org/apache/camel/model/Constants.java  |   3 +-
 .../apache/camel/model/InputTypeDefinition.java |  20 +-
 .../camel/model/OutputTypeDefinition.java       |  20 +-
 .../org/apache/camel/model/RouteDefinition.java |  52 ++++-
 .../CustomTransformerDefinition.java            |  24 +-
 .../transformer/TransformersDefinition.java     |  10 +-
 .../validator/CustomValidatorDefinition.java    |  98 ++++++++
 .../validator/EndpointValidatorDefinition.java  |  97 ++++++++
 .../validator/PredicateValidatorDefinition.java |  76 ++++++
 .../model/validator/ValidatorDefinition.java    |  80 +++++++
 .../model/validator/ValidatorsDefinition.java   |  54 +++++
 .../camel/model/validator/package-info.java     |  24 ++
 .../apache/camel/processor/ContractAdvice.java  |  95 ++++----
 .../java/org/apache/camel/spi/Contract.java     |  34 +++
 .../apache/camel/spi/TransformerRegistry.java   |  12 +-
 .../java/org/apache/camel/spi/Validator.java    |  96 ++++++++
 .../org/apache/camel/spi/ValidatorRegistry.java |  93 ++++++++
 .../apache/camel/util/CamelContextHelper.java   |  62 +++++
 .../org/apache/camel/model/validator/jaxb.index |  21 ++
 .../camel/builder/TransformerBuilderTest.java   |   7 +-
 .../impl/MultipleLifecycleStrategyTest.java     |   2 +-
 .../impl/validator/ValidatorContractTest.java   | 115 +++++++++
 .../impl/validator/ValidatorRouteTest.java      | 187 +++++++++++++++
 .../ManagedNonManagedServiceTest.java           |   4 +-
 ...roducerRouteAddRemoveRegisterAlwaysTest.java |   2 +-
 .../management/ManagedRouteAddRemoveTest.java   |   2 +-
 .../ManagedTransformerRegistryTest.java         |   8 -
 .../ManagedValidatorRegistryTest.java           | 134 +++++++++++
 .../blueprint/CamelContextFactoryBean.java      |  11 +
 .../camel/cdi/xml/CamelContextFactoryBean.java  |  12 +
 .../xml/AbstractCamelContextFactoryBean.java    |   8 +-
 .../camel/spring/CamelContextFactoryBean.java   |  14 ++
 .../spring/handler/CamelNamespaceHandler.java   |   1 +
 .../validator/SpringValidatorRouteTest.java     |  35 +++
 .../impl/validator/SpringValidatorRouteTest.xml |  68 ++++++
 examples/README.adoc                            |   4 +-
 .../camel-example-transformer-demo/README.md    |   8 +-
 examples/camel-example-transformer-demo/pom.xml |   4 +-
 .../demo/OrderResponseValidator.java            |  26 +++
 .../resources/META-INF/spring/camel-context.xml |  18 +-
 .../src/main/resources/xsd/schema.xsd           |  22 ++
 .../camel-example-validator-spring-boot/pom.xml | 120 ++++++++++
 .../readme.adoc                                 |  28 +++
 .../java/sample/camel/GreetingValidator.java    |  31 +++
 .../src/main/java/sample/camel/SampleBean.java  |  38 +++
 .../sample/camel/SampleCamelApplication.java    |  37 +++
 .../java/sample/camel/SampleCamelRouter.java    |  42 ++++
 .../src/main/resources/application.properties   |  28 +++
 .../camel/SampleCamelApplicationTest.java       |  47 ++++
 examples/pom.xml                                |   1 +
 .../commands/AbstractLocalCamelController.java  |  22 ++
 .../apache/camel/commands/CamelController.java  |   9 +
 .../camel/commands/ValidatorListCommand.java    | 185 +++++++++++++++
 .../AbstractLocalCamelControllerTest.java       |  23 +-
 .../commands/TransformerListCommandTest.java    |   5 +-
 .../commands/ValidatorListCommandTest.java      | 121 ++++++++++
 .../jolokia/DefaultJolokiaCamelController.java  |  44 ++++
 77 files changed, 3434 insertions(+), 188 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/buildingtools/src/main/resources/camel-checkstyle.xml
----------------------------------------------------------------------
diff --git a/buildingtools/src/main/resources/camel-checkstyle.xml b/buildingtools/src/main/resources/camel-checkstyle.xml
index 02fd21c..bde7063 100644
--- a/buildingtools/src/main/resources/camel-checkstyle.xml
+++ b/buildingtools/src/main/resources/camel-checkstyle.xml
@@ -53,7 +53,7 @@ lengths, if/try depths, etc...
     </module>
     
     <module name="FileLength">
-        <property name="max" value="4500"/>
+        <property name="max" value="5000"/>
     </module>
     
     <module name="FileTabCharacter">

http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/docs/transformer.adoc
----------------------------------------------------------------------
diff --git a/camel-core/src/main/docs/transformer.adoc b/camel-core/src/main/docs/transformer.adoc
index abe57b3..598f9c2 100644
--- a/camel-core/src/main/docs/transformer.adoc
+++ b/camel-core/src/main/docs/transformer.adoc
@@ -5,16 +5,15 @@ Transformer
 *Available as of Camel 2.19*
 
 Transformer performs declarative transformation of the message according
-to the declared link:eips/inputType-eip.html[Input Type] and/or
-link:eips/outputType-eip.html[Output Type] on a route definition which declares the expected
-message type.
+to the declared `Input Type` and/or `Output Type` on a route definition which declares
+the expected message type.
 There are two Exchange property indicates current message type, `Exchange.INPUT_TYPE`
 holds input message type and `Exchange.OUTPUT_TYPE` holds output message type. If the
-input type and/or output type declared by link:eips/inputType-eip.html[Input Type] and/or
-link:eips/outputType-eip.html[Output Type] in the route definition, and it is different from
-those properties at runtime, camel internal processor look for a Transformer which transforms
-from the current message type to the expected message type and apply. Once transform succeed or message
-is already in expected type, then `Exchange.INPUT_TYPE` or `Exchange.OUTPUT_TYPE` is updated.
+input type and/or output type declared by `Input Type` and/or `Output Type` in the route
+definition, and it is different from those properties at runtime, camel internal processor
+looks for a Transformer which transforms from the current message type to the expected message
+type and apply. Once transform succeed or message is already in expected type, then
+`Exchange.INPUT_TYPE` or `Exchange.OUTPUT_TYPE` is updated.
 
 
 
@@ -133,7 +132,7 @@ Note that Transformer must be a subclass of `org.apache.camel.spi.Transformer`
 
 | ref | Reference to the custom Transformer bean ID
 
-| type | Fully qualified class name of the custom Transformer class
+| className | Fully qualified class name of the custom Transformer class
 |=======================================================================
 Here is an example to specify custom Transformer class:
 Java DSL:
@@ -148,7 +147,7 @@ transformer()
 XML DSL:
 [source,xml]
 -------------------------------------------------------------------
-<customTransformer type="com.example.MyCustomTransformer" fromType="xml" toType="json"/>
+<customTransformer className="com.example.MyCustomTransformer" fromType="xml" toType="json"/>
 -------------------------------------------------------------------
 
 

http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/docs/validator.adoc
----------------------------------------------------------------------
diff --git a/camel-core/src/main/docs/validator.adoc b/camel-core/src/main/docs/validator.adoc
new file mode 100644
index 0000000..afae832
--- /dev/null
+++ b/camel-core/src/main/docs/validator.adoc
@@ -0,0 +1,190 @@
+[[Validator-Validator]]
+Validator
+^^^^^^^^^^
+
+*Available as of Camel 2.19*
+
+Validator performs declarative validation of the message according to the declared
+`Input Type` and/or `Output Type` on a route definition which declares the expected
+message type. Note that the validation is performed only if `validate` attribute on the
+ type declaration is true.
+if `validate` attribute is true on a `Input Type` and/or `Output Type` declaration,
+camel internal processor looks for a corresponding Validator from the registry and apply.
+
+
+
+[[Validator-DataTypeFormat]]
+Data type format
+^^^^^^^^^^^^^^^
+[source,java]
+---------------------------------------------
+scheme:name
+---------------------------------------------
+where *scheme* is the type of data model like `java`, `xml` or `json`, and *name* is the individual
+data type name.
+
+
+
+[[Validator-SupportedValidators]]
+Supported Validators
+^^^^^^^^^^^^^^^^^^^^^
+
+|=======================================================================
+| Validator | Description
+
+| Predicate Validator | Validate with using link:expression.html[Expression] or link:predicate.html[Predicate]
+
+| Endpoint Transformer | Validate by forwarding to the link:endpoint.html[Endpoint] to be used with validation component such as link:validator-component.adoc[Validation Component] or link:bean-validation.html[Bean Validation Component].
+
+| Custom Transformer | Validate with using custom validator class. Validator must be a subclass of `org.apache.camel.spi.Validator`
+|=======================================================================
+
+
+
+[[Validator-CommonOptions]]
+Common Options
+^^^^^^^^^^^^^
+All validators have following common options to specify which data type is supported by the validator.
+`type` must be specified.
+|=======================================================================
+| Name | Description
+
+| type | <<Validator-DataTypeFormat,Data type>> to validate.
+|=======================================================================
+
+
+
+[[Validator-Predicate]]
+Predicate Validator Options
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+|=======================================================================
+| Name | Description
+
+| expression | link:expression.html[Expression] or link:predicate.html[Predicate] to be used for validation
+|=======================================================================
+Here is an example to specify a validation predicate:
+
+Java DSL:
+[source,java]
+-------------------------------------------------------------------
+validator()
+    .type("csv:CSVOrder")
+    .withExpression(bodyAs(String.class).contains("{name:XOrder}"));
+-------------------------------------------------------------------
+
+XML DSL:
+[source,xml]
+-------------------------------------------------------------------
+<predicateValidator Type="csv:CSVOrder">
+    <simple>${body} contains '{name:XOrder'</simple>
+</dataFormatTransformer>
+-------------------------------------------------------------------
+
+
+
+[[Validator-Endpoint]]
+Endpoint Validator Options
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+|=======================================================================
+| Name | Description
+
+| ref | Reference to the link:endpoint.html[Endpoint] ID
+
+| uri | link:endpoint.html[Endpoint] URI
+|=======================================================================
+Here is an example to specify endpoint URI in Java DSL:
+[source,java]
+-------------------------------------------------------------------
+validator()
+    .type("xml")
+    .withUri("validator:xsd/schema.xsd");
+-------------------------------------------------------------------
+
+And here is an example to specify endpoint ref in XML DSL:
+[source,xml]
+-------------------------------------------------------------------
+<endpointValidator uri="validator:xsd/schema.xsd" type="xml"/>
+-------------------------------------------------------------------
+
+
+
+[[Validator-Custom]]
+Custom Validator Options
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Note that Validator must be a subclass of `org.apache.camel.spi.Validator`
+|=======================================================================
+| Name | Description
+
+| ref | Reference to the custom Validator bean ID
+
+| className | Fully qualified class name of the custom Validator class
+|=======================================================================
+Here is an example to specify custom Validator class:
+Java DSL:
+[source,java]
+-------------------------------------------------------------------
+validator()
+    .type("json")
+    .withJava(com.example.MyCustomValidator.class);
+-------------------------------------------------------------------
+
+XML DSL:
+[source,xml]
+-------------------------------------------------------------------
+<customTransformer className="com.example.MyCustomValidator" type="json"/>
+-------------------------------------------------------------------
+
+
+
+[[Validator-Examples]]
+Examples
+^^^^^^^
+
+For example to declare the Endpoint Validator which uses
+validator component to validate `xml:ABCOrder`, we can do as follows:
+
+Java DSL:
+[source,java]
+-------------------------------------------------------------------
+validator()
+    .type("xml:ABCOrder")
+    .withUri("validator:xsd/schema.xsd");
+-------------------------------------------------------------------
+
+XML DSL:
+[source,xml]
+-------------------------------------------------------------------
+<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
+    <validators>
+        <endpointValidator uri="validator:xsd/schema.xsd" type="xml:ABCOrder"/>
+    </validators>
+    ....
+</camelContext>
+-------------------------------------------------------------------
+
+If you have following route definition, above validator will be applied when `direct:abc` endpoint
+receives the message. Note that the `validate` attribute on the inputType declaration is set to `true`:
+
+Java DSL:
+[source,java]
+-------------------------------------------------------------------
+from("direct:abc")
+    .inputType("xml:ABCOrder", true)
+    .log("${body}");
+-------------------------------------------------------------------
+
+XML DSL:
+[source,xml]
+-------------------------------------------------------------------
+<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
+    ....
+    <route>
+        <from uri="direct:abc"/>
+        <inputType urn="xml:ABCOrder" validate="true"/>
+        <log message="${body}"/>
+    </route>
+</camelContext>
+-------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/java/org/apache/camel/CamelContext.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/CamelContext.java b/camel-core/src/main/java/org/apache/camel/CamelContext.java
index 84269a3..ac0c774 100644
--- a/camel-core/src/main/java/org/apache/camel/CamelContext.java
+++ b/camel-core/src/main/java/org/apache/camel/CamelContext.java
@@ -37,6 +37,7 @@ import org.apache.camel.model.cloud.ServiceCallConfigurationDefinition;
 import org.apache.camel.model.rest.RestDefinition;
 import org.apache.camel.model.rest.RestsDefinition;
 import org.apache.camel.model.transformer.TransformerDefinition;
+import org.apache.camel.model.validator.ValidatorDefinition;
 import org.apache.camel.spi.AsyncProcessorAwaitManager;
 import org.apache.camel.spi.CamelContextNameStrategy;
 import org.apache.camel.spi.ClassResolver;
@@ -77,6 +78,8 @@ import org.apache.camel.spi.TransformerRegistry;
 import org.apache.camel.spi.TypeConverterRegistry;
 import org.apache.camel.spi.UnitOfWorkFactory;
 import org.apache.camel.spi.UuidGenerator;
+import org.apache.camel.spi.Validator;
+import org.apache.camel.spi.ValidatorRegistry;
 import org.apache.camel.util.LoadPropertiesException;
 
 /**
@@ -1262,7 +1265,7 @@ public interface CamelContext extends SuspendableService, RuntimeConfiguration {
      *
      * @param from from data type
      * @param to to data type
-     * @return the resolved data format, or <tt>null</tt> if not found
+     * @return the resolved transformer, or <tt>null</tt> if not found
      */
     Transformer resolveTransformer(DataType from, DataType to);
 
@@ -1273,6 +1276,34 @@ public interface CamelContext extends SuspendableService, RuntimeConfiguration {
     TransformerRegistry getTransformerRegistry();
 
     /**
+     * Sets the validators that can be referenced in the routes.
+     *
+     * @param validators the validators
+     */
+    void setValidators(List<ValidatorDefinition> validators);
+
+    /**
+     * Gets the validators that can be referenced in the routes.
+     *
+     * @return the validators available
+     */
+    List<ValidatorDefinition> getValidators();
+
+    /**
+     * Resolve a validator given from/to data type.
+     *
+     * @param from the data type
+     * @return the resolved validator, or <tt>null</tt> if not found
+     */
+    Validator resolveValidator(DataType type);
+
+    /**
+     * Gets the {@link org.apache.camel.spi.ValidatorRegistry}
+     * @return the ValidatorRegistry
+     */
+    ValidatorRegistry getValidatorRegistry();
+
+    /**
      * @deprecated use {@link #setGlobalOptions(Map) setGlobalOptions(Map<String,String>) instead}.
      */
     @Deprecated

http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/java/org/apache/camel/Exchange.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/Exchange.java b/camel-core/src/main/java/org/apache/camel/Exchange.java
index b6f6c37..cc2acaa 100644
--- a/camel-core/src/main/java/org/apache/camel/Exchange.java
+++ b/camel-core/src/main/java/org/apache/camel/Exchange.java
@@ -166,6 +166,8 @@ public interface Exchange {
 
     String MAXIMUM_CACHE_POOL_SIZE     = "CamelMaximumCachePoolSize";
     String MAXIMUM_ENDPOINT_CACHE_SIZE = "CamelMaximumEndpointCacheSize";
+    String MAXIMUM_TRANSFORMER_CACHE_SIZE = "CamelMaximumTransformerCacheSize";
+    String MAXIMUM_VALIDATOR_CACHE_SIZE = "CamelMaximumValidatorCacheSize";
     String MESSAGE_HISTORY             = "CamelMessageHistory";
     String MULTICAST_INDEX             = "CamelMulticastIndex";
     String MULTICAST_COMPLETE          = "CamelMulticastComplete";

http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/java/org/apache/camel/api/management/mbean/CamelOpenMBeanTypes.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/api/management/mbean/CamelOpenMBeanTypes.java b/camel-core/src/main/java/org/apache/camel/api/management/mbean/CamelOpenMBeanTypes.java
index b03cda1..2672447 100644
--- a/camel-core/src/main/java/org/apache/camel/api/management/mbean/CamelOpenMBeanTypes.java
+++ b/camel-core/src/main/java/org/apache/camel/api/management/mbean/CamelOpenMBeanTypes.java
@@ -228,4 +228,16 @@ public final class CamelOpenMBeanTypes {
                                  new OpenType[]{SimpleType.STRING, SimpleType.STRING, SimpleType.STRING,
                                                 SimpleType.BOOLEAN, SimpleType.BOOLEAN, SimpleType.STRING});
     }
+
+    public static TabularType listValidatorsTabularType() throws OpenDataException {
+        CompositeType ct = listValidatorsCompositeType();
+        return new TabularType("listValidators", "Lists all the validators in the registry", ct, new String[]{"type"});
+    }
+
+    public static CompositeType listValidatorsCompositeType() throws OpenDataException {
+        return new CompositeType("validators", "Validators",
+                                 new String[]{"type", "static", "dynamic", "description"},
+                                 new String[]{"Type", "Static", "Dynamic", "Description"},
+                                 new OpenType[]{SimpleType.STRING, SimpleType.BOOLEAN, SimpleType.BOOLEAN, SimpleType.STRING});
+    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedValidatorRegistryMBean.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedValidatorRegistryMBean.java b/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedValidatorRegistryMBean.java
new file mode 100644
index 0000000..e011f53
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedValidatorRegistryMBean.java
@@ -0,0 +1,47 @@
+/**
+ * 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.api.management.mbean;
+
+import javax.management.openmbean.TabularData;
+
+import org.apache.camel.api.management.ManagedAttribute;
+import org.apache.camel.api.management.ManagedOperation;
+
+public interface ManagedValidatorRegistryMBean extends ManagedServiceMBean {
+
+    @ManagedAttribute(description = "Source")
+    String getSource();
+
+    @ManagedAttribute(description = "Number of dynamic validators cached")
+    Integer getDynamicSize();
+
+    @ManagedAttribute(description = "Number of static validators cached")
+    Integer getStaticSize();
+
+    @ManagedAttribute(description = "Number of total validators cached")
+    Integer getSize();
+
+    @ManagedAttribute(description = "Maximum cache size (capacity)")
+    Integer getMaximumCacheSize();
+
+    @ManagedOperation(description = "Purges the cache")
+    void purge();
+
+    @ManagedOperation(description = "Lists all the validators in the registry")
+    TabularData listValidators();
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/java/org/apache/camel/builder/RouteBuilder.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/builder/RouteBuilder.java b/camel-core/src/main/java/org/apache/camel/builder/RouteBuilder.java
index fde9494..26c2097 100644
--- a/camel-core/src/main/java/org/apache/camel/builder/RouteBuilder.java
+++ b/camel-core/src/main/java/org/apache/camel/builder/RouteBuilder.java
@@ -54,6 +54,7 @@ public abstract class RouteBuilder extends BuilderSupport implements RoutesBuild
     private RestsDefinition restCollection = new RestsDefinition();
     private Map<String, RestConfigurationDefinition> restConfigurations;
     private List<TransformerBuilder> transformerBuilders = new ArrayList<>();
+    private List<ValidatorBuilder> validatorBuilders = new ArrayList<>();
     private RoutesDefinition routeCollection = new RoutesDefinition();
 
     public RouteBuilder() {
@@ -144,6 +145,17 @@ public abstract class RouteBuilder extends BuilderSupport implements RoutesBuild
     }
 
     /**
+     * Create a new {@code ValidatorBuilder}.
+     * 
+     * @return the builder
+     */
+    public ValidatorBuilder validator() {
+        ValidatorBuilder vb = new ValidatorBuilder();
+        validatorBuilders.add(vb);
+        return vb;
+    }
+
+    /**
      * Creates a new route from the given URI input
      *
      * @param uri  the from uri
@@ -341,6 +353,7 @@ public abstract class RouteBuilder extends BuilderSupport implements RoutesBuild
         // but populate rests before routes, as we want to turn rests into routes
         populateRests();
         populateTransformers();
+        populateValidators();
         populateRoutes();
     }
 
@@ -494,6 +507,16 @@ public abstract class RouteBuilder extends BuilderSupport implements RoutesBuild
         }
     }
 
+    protected void populateValidators() {
+        ModelCamelContext camelContext = getContext();
+        if (camelContext == null) {
+            throw new IllegalArgumentException("CamelContext has not been injected!");
+        }
+        for (ValidatorBuilder vb : validatorBuilders) {
+            vb.configure(camelContext);
+        }
+    }
+
     public RestsDefinition getRestCollection() {
         return restCollection;
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/java/org/apache/camel/builder/TransformerBuilder.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/builder/TransformerBuilder.java b/camel-core/src/main/java/org/apache/camel/builder/TransformerBuilder.java
index 9f5f2ec..a8bab64 100644
--- a/camel-core/src/main/java/org/apache/camel/builder/TransformerBuilder.java
+++ b/camel-core/src/main/java/org/apache/camel/builder/TransformerBuilder.java
@@ -173,7 +173,7 @@ public class TransformerBuilder {
             transformer = dtd;
         } else if (clazz != null) {
             CustomTransformerDefinition ctd = new CustomTransformerDefinition();
-            ctd.setType(clazz.getName());
+            ctd.setClassName(clazz.getName());
             transformer = ctd;
         } else if (beanRef != null) {
             CustomTransformerDefinition ctd = new CustomTransformerDefinition();

http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/java/org/apache/camel/builder/ValidatorBuilder.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/builder/ValidatorBuilder.java b/camel-core/src/main/java/org/apache/camel/builder/ValidatorBuilder.java
new file mode 100644
index 0000000..c021939
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/builder/ValidatorBuilder.java
@@ -0,0 +1,166 @@
+/**
+ * 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.builder;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Expression;
+import org.apache.camel.Predicate;
+import org.apache.camel.model.language.ExpressionDefinition;
+import org.apache.camel.model.validator.CustomValidatorDefinition;
+import org.apache.camel.model.validator.EndpointValidatorDefinition;
+import org.apache.camel.model.validator.PredicateValidatorDefinition;
+import org.apache.camel.model.validator.ValidatorDefinition;
+import org.apache.camel.spi.AsPredicate;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.Validator;
+
+/**
+ * A <a href="http://camel.apache.org/dsl.html">Java DSL</a> which is
+ * used to build a {@link org.apache.camel.spi.Validator} and register into {@link org.apache.camel.CamelContext}.
+ * It requires a 'type' to be specified by type() method.
+ * And then you can choose a type of validator by withUri(), withPredicate(), withJava() or withBean() method.
+ */
+public class ValidatorBuilder {
+
+    private String type;
+    private String uri;
+    private ExpressionDefinition expression;
+    private Class<? extends Validator> clazz;
+    private String beanRef;
+
+    /**
+     * Set the data type name.
+     * If you specify 'xml:XYZ', the validator will be picked up if source type is
+     * 'xml:XYZ'. If you specify just 'xml', the validator matches with all of
+     * 'xml' source type like 'xml:ABC' or 'xml:DEF'.
+     *
+     * @param type 'from' data type name
+     */
+    public ValidatorBuilder type(String type) {
+        this.type = type;
+        return this;
+    }
+
+    /**
+     * Set the data type using Java class.
+     *
+     * @param clazz Java class represents data type
+     */
+    public ValidatorBuilder type(Class<?> type) {
+        this.type = new DataType(type).toString();
+        return this;
+    }
+
+    /**
+     * Set the URI to be used for the endpoint {@link Validator}.
+     * @see {@link EndpointValidatorDefinition}, {@link ProcessorValidator}
+     * 
+     * @param uri endpoint URI
+     */
+    public ValidatorBuilder withUri(String uri) {
+        resetType();
+        this.uri = uri;
+        return this;
+    }
+
+    /**
+     * Set the {@link Expression} to be used for the predicate {@link Validator}.
+     * @see {@link PredicateValidatorDefinition}, {@link ProcessorValidator}
+     * 
+     * @param expression validation expression
+     */
+    public ValidatorBuilder withExpression(@AsPredicate Expression expression) {
+        resetType();
+        this.expression = new ExpressionDefinition(expression);
+        return this;
+    }
+
+    /**
+     * Set the {@link Predicate} to be used for the predicate {@link Validator}.
+     * @see {@link PredicateValidatorDefinition}, {@link ProcessorValidator}
+     * 
+     * @param predicate validation predicate
+     */
+    public ValidatorBuilder withExpression(@AsPredicate Predicate predicate) {
+        resetType();
+        this.expression = new ExpressionDefinition(predicate);
+        return this;
+    }
+
+    /**
+     * Set the Java {@code Class} represents a custom {@code Validator} implementation class.
+     * @see {@code CustomValidatorDefinition}
+     * 
+     * @param clazz {@code Class} object represents custom validator implementation
+     */
+    public ValidatorBuilder withJava(Class<? extends Validator> clazz) {
+        resetType();
+        this.clazz = clazz;
+        return this;
+    }
+
+    /**
+     * Set the Java Bean name to be used for custom {@code Validator}.
+     * @see {@code CustomValidatorDefinition}
+     * 
+     * @param ref bean name for the custom {@code Validator}
+     */
+    public ValidatorBuilder withBean(String ref) {
+        resetType();
+        this.beanRef = ref;
+        return this;
+    }
+
+    private void resetType() {
+        this.uri = null;
+        this.expression = null;
+        this.clazz = null;
+        this.beanRef = null;
+    }
+
+    /**
+     * Configure a Validator according to the configurations built on this builder
+     * and register it into given {@code CamelContext}.
+     * 
+     * @param camelContext {@code CamelContext}
+     */
+    public void configure(CamelContext camelContext) {
+        ValidatorDefinition validator;
+        if (uri != null) {
+            EndpointValidatorDefinition etd = new EndpointValidatorDefinition();
+            etd.setUri(uri);
+            validator = etd;
+        } else if (expression != null) {
+            PredicateValidatorDefinition dtd = new PredicateValidatorDefinition();
+            dtd.setExpression(expression);
+            validator = dtd;
+        } else if (clazz != null) {
+            CustomValidatorDefinition ctd = new CustomValidatorDefinition();
+            ctd.setClassName(clazz.getName());
+            validator = ctd;
+        } else if (beanRef != null) {
+            CustomValidatorDefinition ctd = new CustomValidatorDefinition();
+            ctd.setRef(beanRef);
+            validator = ctd;
+        } else {
+            throw new IllegalArgumentException("No Validator type was specified");
+        }
+        
+        validator.setType(type);
+        camelContext.getValidators().add(validator);
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java b/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
index 6a2db9e..4f4648f 100644
--- a/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
+++ b/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
@@ -91,6 +91,7 @@ import org.apache.camel.impl.converter.BaseTypeConverterRegistry;
 import org.apache.camel.impl.converter.DefaultTypeConverter;
 import org.apache.camel.impl.converter.LazyLoadingTypeConverter;
 import org.apache.camel.impl.transformer.TransformerKey;
+import org.apache.camel.impl.validator.ValidatorKey;
 import org.apache.camel.management.DefaultManagementMBeanAssembler;
 import org.apache.camel.management.DefaultManagementStrategy;
 import org.apache.camel.management.JmxSystemPropertyKeys;
@@ -108,6 +109,7 @@ import org.apache.camel.model.cloud.ServiceCallConfigurationDefinition;
 import org.apache.camel.model.rest.RestDefinition;
 import org.apache.camel.model.rest.RestsDefinition;
 import org.apache.camel.model.transformer.TransformerDefinition;
+import org.apache.camel.model.validator.ValidatorDefinition;
 import org.apache.camel.processor.interceptor.BacklogDebugger;
 import org.apache.camel.processor.interceptor.BacklogTracer;
 import org.apache.camel.processor.interceptor.Debug;
@@ -160,6 +162,8 @@ import org.apache.camel.spi.TransformerRegistry;
 import org.apache.camel.spi.TypeConverterRegistry;
 import org.apache.camel.spi.UnitOfWorkFactory;
 import org.apache.camel.spi.UuidGenerator;
+import org.apache.camel.spi.Validator;
+import org.apache.camel.spi.ValidatorRegistry;
 import org.apache.camel.support.ServiceSupport;
 import org.apache.camel.util.CamelContextHelper;
 import org.apache.camel.util.CollectionStringBuffer;
@@ -283,8 +287,10 @@ public class DefaultCamelContext extends ServiceSupport implements ModelCamelCon
     private final StopWatch stopWatch = new StopWatch(false);
     private Date startDate;
     private ModelJAXBContextFactory modelJAXBContextFactory;
-    private List<TransformerDefinition> transformers = new ArrayList<TransformerDefinition>();
+    private List<TransformerDefinition> transformers = new ArrayList<>();
     private TransformerRegistry<TransformerKey> transformerRegistry;
+    private List<ValidatorDefinition> validators = new ArrayList<>();
+    private ValidatorRegistry<ValidatorKey> validatorRegistry;
     private ReloadStrategy reloadStrategy;
 
     /**
@@ -298,7 +304,6 @@ public class DefaultCamelContext extends ServiceSupport implements ModelCamelCon
 
         // create endpoint registry at first since end users may access endpoints before CamelContext is started
         this.endpoints = new DefaultEndpointRegistry(this);
-        this.transformerRegistry = new DefaultTransformerRegistry(this);
 
         // add the defer service startup listener
         this.startupListeners.add(deferStartupListener);
@@ -3134,7 +3139,12 @@ public class DefaultCamelContext extends ServiceSupport implements ModelCamelCon
             log.info("Using ReloadStrategy: {}", reloadStrategy);
             addService(reloadStrategy, true, true);
         }
+
+        // Initialize declarative transformer/validator registry
+        transformerRegistry = new DefaultTransformerRegistry(this, transformers);
         addService(transformerRegistry, true, true);
+        validatorRegistry = new DefaultValidatorRegistry(this, validators);
+        addService(validatorRegistry, true, true);
 
         if (runtimeEndpointRegistry != null) {
             if (runtimeEndpointRegistry instanceof EventNotifier) {
@@ -4315,18 +4325,12 @@ public class DefaultCamelContext extends ServiceSupport implements ModelCamelCon
 
     @Override
     public Transformer resolveTransformer(String scheme) {
-        if (scheme == null) {
-            return null;
-        }
-        return resolveTransformer(getTransformerKey(scheme));
+        return transformerRegistry.resolveTransformer(new TransformerKey(scheme));
     }
 
     @Override
     public Transformer resolveTransformer(DataType from, DataType to) {
-        if (from == null || to == null) {
-            return null;
-        }
-        return resolveTransformer(getTransformerKey(from, to));
+        return transformerRegistry.resolveTransformer(new TransformerKey(from, to));
     }
 
     @Override
@@ -4334,6 +4338,26 @@ public class DefaultCamelContext extends ServiceSupport implements ModelCamelCon
         return transformerRegistry;
     }
 
+    @Override
+    public void setValidators(List<ValidatorDefinition> validators) {
+        this.validators = validators;
+    }
+
+    @Override
+    public List<ValidatorDefinition> getValidators() {
+        return validators;
+    }
+
+    @Override
+    public Validator resolveValidator(DataType type) {
+        return validatorRegistry.resolveValidator(new ValidatorKey(type));
+    }
+
+    @Override
+    public ValidatorRegistry getValidatorRegistry() {
+        return validatorRegistry;
+    }
+
     protected Map<String, RouteService> getRouteServices() {
         return routeServices;
     }
@@ -4365,36 +4389,6 @@ public class DefaultCamelContext extends ServiceSupport implements ModelCamelCon
         return new DefaultModelJAXBContextFactory();
     }
 
-    protected Transformer resolveTransformer(TransformerKey key) {
-        Transformer transformer = transformerRegistry.get(key);
-        if (transformer != null) {
-            return transformer;
-        }
-        for (TransformerDefinition def : getTransformers()) {
-            if (key.match(def)) {
-                try {
-                    transformer = def.createTransformer(this);
-                    transformer.setCamelContext(this);
-                    addService(transformer);
-                } catch (Exception e) {
-                    throw new RuntimeCamelException(e);
-                }
-                log.debug("Registering Transformer '{}'", transformer);
-                transformerRegistry.put(key, transformer);
-                return transformer;
-            }
-        }
-        return null;
-    }
-
-    protected TransformerKey getTransformerKey(String scheme) {
-        return new TransformerKey(scheme);
-    }
-
-    protected TransformerKey getTransformerKey(DataType from, DataType to) {
-        return new TransformerKey(from, to);
-    }
-
     @Override
     public String toString() {
         return "CamelContext(" + getName() + ")";

http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/java/org/apache/camel/impl/DefaultRouteContext.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/DefaultRouteContext.java b/camel-core/src/main/java/org/apache/camel/impl/DefaultRouteContext.java
index fbb3673..594742e 100644
--- a/camel-core/src/main/java/org/apache/camel/impl/DefaultRouteContext.java
+++ b/camel-core/src/main/java/org/apache/camel/impl/DefaultRouteContext.java
@@ -208,9 +208,11 @@ public class DefaultRouteContext implements RouteContext {
                 Contract contract = new Contract();
                 if (route.getInputType() != null) {
                     contract.setInputType(route.getInputType().getUrn());
+                    contract.setValidateInput(route.getInputType().isValidate());
                 }
                 if (route.getOutputType() != null) {
                     contract.setOutputType(route.getOutputType().getUrn());
+                    contract.setValidateOutput(route.getOutputType().isValidate());
                 }
                 internal.addAdvice(new ContractAdvice(contract));
             }

http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/java/org/apache/camel/impl/DefaultTransformerRegistry.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/DefaultTransformerRegistry.java b/camel-core/src/main/java/org/apache/camel/impl/DefaultTransformerRegistry.java
index 6969233..afa9968 100644
--- a/camel-core/src/main/java/org/apache/camel/impl/DefaultTransformerRegistry.java
+++ b/camel-core/src/main/java/org/apache/camel/impl/DefaultTransformerRegistry.java
@@ -19,6 +19,7 @@ package org.apache.camel.impl;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.LinkedHashSet;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
@@ -27,33 +28,84 @@ import java.util.concurrent.ConcurrentMap;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Endpoint;
 import org.apache.camel.impl.transformer.TransformerKey;
+import org.apache.camel.model.transformer.TransformerDefinition;
 import org.apache.camel.spi.DataType;
 import org.apache.camel.spi.EndpointRegistry;
 import org.apache.camel.spi.Transformer;
 import org.apache.camel.spi.TransformerRegistry;
 import org.apache.camel.util.CamelContextHelper;
 import org.apache.camel.util.LRUCache;
+import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.ServiceHelper;
 
 /**
- * Default implementation of {@link org.apache.camel.spi.TransformerRegistry}
+ * Default implementation of {@link org.apache.camel.spi.TransformerRegistry}.
  */
 public class DefaultTransformerRegistry extends LRUCache<TransformerKey, Transformer> implements TransformerRegistry<TransformerKey> {
     private static final long serialVersionUID = 1L;
     private ConcurrentMap<TransformerKey, Transformer> staticMap;
+    private ConcurrentMap<TransformerKey, TransformerKey> aliasMap;
     private final CamelContext context;
 
-    public DefaultTransformerRegistry(CamelContext context) {
-        // do not stop on eviction, as the endpoint may still be in use
-        super(CamelContextHelper.getMaximumEndpointCacheSize(context), CamelContextHelper.getMaximumEndpointCacheSize(context), false);
-        // static map to hold endpoints we do not want to be evicted
-        this.staticMap = new ConcurrentHashMap<TransformerKey, Transformer>();
+    public DefaultTransformerRegistry(CamelContext context) throws Exception {
+        this(context, new ArrayList<>());
+    }
+
+    public DefaultTransformerRegistry(CamelContext context, List<TransformerDefinition> definitions) throws Exception {
+        // do not stop on eviction, as the transformer may still be in use
+        super(CamelContextHelper.getMaximumTransformerCacheSize(context), CamelContextHelper.getMaximumTransformerCacheSize(context), false);
+        // static map to hold transformers we do not want to be evicted
+        this.staticMap = new ConcurrentHashMap<>();
+        this.aliasMap = new ConcurrentHashMap<>();
         this.context = context;
+        
+        for (TransformerDefinition def : definitions) {
+            Transformer transformer = def.createTransformer(context);
+            context.addService(transformer);
+            put(createKey(def), transformer);
+        }
     }
 
-    public DefaultTransformerRegistry(CamelContext context, Map<TransformerKey, Transformer> transformers) {
-        this(context);
-        putAll(transformers);
+    @Override
+    public Transformer resolveTransformer(TransformerKey key) {
+        if (ObjectHelper.isEmpty(key.getScheme()) && key.getTo() == null) {
+            return null;
+        }
+        
+        // try exact match
+        Transformer answer = get(aliasMap.containsKey(key) ? aliasMap.get(key) : key);
+        if (answer != null || ObjectHelper.isNotEmpty(key.getScheme())) {
+            return answer;
+        }
+        
+        // try wildcard match for next - add an alias if matched
+        TransformerKey alias = null;
+        if (key.getFrom() != null && ObjectHelper.isNotEmpty(key.getFrom().getName())) {
+            alias = new TransformerKey(new DataType(key.getFrom().getModel()), key.getTo());
+            answer = get(alias);
+        }
+        if (answer == null && ObjectHelper.isNotEmpty(key.getTo().getName())) {
+            alias = new TransformerKey(key.getFrom(), new DataType(key.getTo().getModel()));
+            answer = get(alias);
+        }
+        if (answer == null && key.getFrom() != null && ObjectHelper.isNotEmpty(key.getFrom().getName())
+            && ObjectHelper.isNotEmpty(key.getTo().getName())) {
+            alias = new TransformerKey(new DataType(key.getFrom().getModel()), new DataType(key.getTo().getModel()));
+            answer = get(alias);
+        }
+        if (answer == null && key.getFrom() != null) {
+            alias = new TransformerKey(key.getFrom().getModel());
+            answer = get(alias);
+        }
+        if (answer == null) {
+            alias = new TransformerKey(key.getTo().getModel());
+            answer = get(alias);
+        }
+        if (answer != null) {
+            aliasMap.put(key, alias);
+        }
+        
+        return answer;
     }
 
     @Override
@@ -90,7 +142,7 @@ public class DefaultTransformerRegistry extends LRUCache<TransformerKey, Transfo
             return answer;
         }
 
-        // we want endpoints to be static if they are part of setting up or starting routes
+        // we want transformers to be static if they are part of setting up or starting routes
         if (context.isSetupRoutes() || context.isStartingRoutes()) {
             answer = staticMap.put(key, transformer);
         } else {
@@ -154,7 +206,7 @@ public class DefaultTransformerRegistry extends LRUCache<TransformerKey, Transfo
 
     @Override
     public Set<TransformerKey> keySet() {
-        Set<TransformerKey> answer = new LinkedHashSet<TransformerKey>();
+        Set<TransformerKey> answer = new LinkedHashSet<>();
         answer.addAll(staticMap.keySet());
         answer.addAll(super.keySet());
         return answer;
@@ -162,7 +214,7 @@ public class DefaultTransformerRegistry extends LRUCache<TransformerKey, Transfo
 
     @Override
     public Collection<Transformer> values() {
-        Collection<Transformer> answer = new ArrayList<Transformer>();
+        Collection<Transformer> answer = new ArrayList<>();
         answer.addAll(staticMap.values());
         answer.addAll(super.values());
         return answer;
@@ -170,7 +222,7 @@ public class DefaultTransformerRegistry extends LRUCache<TransformerKey, Transfo
 
     @Override
     public Set<Entry<TransformerKey, Transformer>> entrySet() {
-        Set<Entry<TransformerKey, Transformer>> answer = new LinkedHashSet<Entry<TransformerKey, Transformer>>();
+        Set<Entry<TransformerKey, Transformer>> answer = new LinkedHashSet<>();
         answer.addAll(staticMap.entrySet());
         answer.addAll(super.entrySet());
         return answer;
@@ -221,4 +273,10 @@ public class DefaultTransformerRegistry extends LRUCache<TransformerKey, Transfo
     public String toString() {
         return "TransformerRegistry for " + context.getName() + ", capacity: " + getMaxCacheSize();
     }
+
+    private TransformerKey createKey(TransformerDefinition def) {
+        return ObjectHelper.isNotEmpty(def.getScheme()) ? new TransformerKey(def.getScheme())
+            : new TransformerKey(new DataType(def.getFromType()), new DataType(def.getToType()));
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/java/org/apache/camel/impl/DefaultValidatorRegistry.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/DefaultValidatorRegistry.java b/camel-core/src/main/java/org/apache/camel/impl/DefaultValidatorRegistry.java
new file mode 100644
index 0000000..9a4d4ca
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/impl/DefaultValidatorRegistry.java
@@ -0,0 +1,231 @@
+/**
+ * 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.impl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Endpoint;
+import org.apache.camel.impl.validator.ValidatorKey;
+import org.apache.camel.model.validator.ValidatorDefinition;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.EndpointRegistry;
+import org.apache.camel.spi.Validator;
+import org.apache.camel.spi.ValidatorRegistry;
+import org.apache.camel.util.CamelContextHelper;
+import org.apache.camel.util.LRUCache;
+import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.ServiceHelper;
+
+/**
+ * Default implementation of {@link org.apache.camel.spi.ValidatorRegistry}.
+ */
+public class DefaultValidatorRegistry extends LRUCache<ValidatorKey, Validator> implements ValidatorRegistry<ValidatorKey> {
+    private static final long serialVersionUID = 1L;
+    private ConcurrentMap<ValidatorKey, Validator> staticMap;
+    private final CamelContext context;
+
+    public DefaultValidatorRegistry(CamelContext context) throws Exception {
+        this(context, new ArrayList<>());
+    }
+
+    public DefaultValidatorRegistry(CamelContext context, List<ValidatorDefinition> definitions) throws Exception {
+        // do not stop on eviction, as the validator may still be in use
+        super(CamelContextHelper.getMaximumValidatorCacheSize(context), CamelContextHelper.getMaximumValidatorCacheSize(context), false);
+        // static map to hold validator we do not want to be evicted
+        this.staticMap = new ConcurrentHashMap<>();
+        this.context = context;
+        
+        for (ValidatorDefinition def : definitions) {
+            Validator validator = def.createValidator(context);
+            context.addService(validator);
+            put(new ValidatorKey(new DataType(def.getType())), validator);
+        }
+    }
+
+    public Validator resolveValidator(ValidatorKey key) {
+        Validator answer = get(key);
+        if (answer == null && ObjectHelper.isNotEmpty(key.getType().getName())) {
+            answer = get(new ValidatorKey(new DataType(key.getType().getModel())));
+        }
+        return answer;
+    }
+
+    @Override
+    public void start() throws Exception {
+        resetStatistics();
+    }
+
+    @Override
+    public Validator get(Object o) {
+        // try static map first
+        Validator answer = staticMap.get(o);
+        if (answer == null) {
+            answer = super.get(o);
+        } else {
+            hits.incrementAndGet();
+        }
+        return answer;
+    }
+
+    @Override
+    public Validator put(ValidatorKey key, Validator validator) {
+        // at first we must see if the key already exists and then replace it back, so it stays the same spot
+        Validator answer = staticMap.remove(key);
+        if (answer != null) {
+            // replace existing
+            staticMap.put(key, validator);
+            return answer;
+        }
+
+        answer = super.remove(key);
+        if (answer != null) {
+            // replace existing
+            super.put(key, validator);
+            return answer;
+        }
+
+        // we want validators to be static if they are part of setting up or starting routes
+        if (context.isSetupRoutes() || context.isStartingRoutes()) {
+            answer = staticMap.put(key, validator);
+        } else {
+            answer = super.put(key, validator);
+        }
+
+        return answer;
+    }
+
+    @Override
+    public void putAll(Map<? extends ValidatorKey, ? extends Validator> map) {
+        // need to use put instead of putAll to ensure the entries gets added to either static or dynamic map
+        for (Map.Entry<? extends ValidatorKey, ? extends Validator> entry : map.entrySet()) {
+            put(entry.getKey(), entry.getValue());
+        }
+    }
+
+    @Override
+    public boolean containsKey(Object o) {
+        return staticMap.containsKey(o) || super.containsKey(o);
+    }
+
+    @Override
+    public boolean containsValue(Object o) {
+        return staticMap.containsValue(o) || super.containsValue(o);
+    }
+
+    @Override
+    public int size() {
+        return staticMap.size() + super.size();
+    }
+
+    public int staticSize() {
+        return staticMap.size();
+    }
+
+    @Override
+    public int dynamicSize() {
+        return super.size();
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return staticMap.isEmpty() && super.isEmpty();
+    }
+
+    @Override
+    public Validator remove(Object o) {
+        Validator answer = staticMap.remove(o);
+        if (answer == null) {
+            answer = super.remove(o);
+        }
+        return answer;
+    }
+
+    @Override
+    public void clear() {
+        staticMap.clear();
+        super.clear();
+    }
+
+    @Override
+    public Set<ValidatorKey> keySet() {
+        Set<ValidatorKey> answer = new LinkedHashSet<>();
+        answer.addAll(staticMap.keySet());
+        answer.addAll(super.keySet());
+        return answer;
+    }
+
+    @Override
+    public Collection<Validator> values() {
+        Collection<Validator> answer = new ArrayList<>();
+        answer.addAll(staticMap.values());
+        answer.addAll(super.values());
+        return answer;
+    }
+
+    @Override
+    public Set<Entry<ValidatorKey, Validator>> entrySet() {
+        Set<Entry<ValidatorKey, Validator>> answer = new LinkedHashSet<>();
+        answer.addAll(staticMap.entrySet());
+        answer.addAll(super.entrySet());
+        return answer;
+    }
+
+    @Override
+    public int getMaximumCacheSize() {
+        return super.getMaxCacheSize();
+    }
+
+    /**
+     * Purges the cache
+     */
+    @Override
+    public void purge() {
+        // only purge the dynamic part
+        super.clear();
+    }
+
+    @Override
+    public boolean isStatic(DataType type) {
+        return staticMap.containsKey(new ValidatorKey(type));
+    }
+
+    @Override
+    public boolean isDynamic(DataType type) {
+        return super.containsKey(new ValidatorKey(type));
+    }
+
+    @Override
+    public void stop() throws Exception {
+        ServiceHelper.stopServices(staticMap.values());
+        ServiceHelper.stopServices(values());
+        purge();
+    }
+
+    @Override
+    public String toString() {
+        return "ValidatorRegistry for " + context.getName() + ", capacity: " + getMaxCacheSize();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/java/org/apache/camel/impl/transformer/TransformerKey.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/transformer/TransformerKey.java b/camel-core/src/main/java/org/apache/camel/impl/transformer/TransformerKey.java
index f75f9b5..4878bcd 100644
--- a/camel-core/src/main/java/org/apache/camel/impl/transformer/TransformerKey.java
+++ b/camel-core/src/main/java/org/apache/camel/impl/transformer/TransformerKey.java
@@ -19,11 +19,11 @@ package org.apache.camel.impl.transformer;
 import org.apache.camel.impl.DefaultCamelContext;
 import org.apache.camel.model.transformer.TransformerDefinition;
 import org.apache.camel.spi.DataType;
-import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.StringHelper;
 import org.apache.camel.util.ValueHolder;
 
 /**
- * Key used in Transformer registry in {@link DefaultCamelContext},
+ * Key used in {@link org.apache.camel.spi.TransformerRegistry} in {@link DefaultCamelContext},
  * to ensure a consistent lookup.
  */
 public final class TransformerKey extends ValueHolder<String> {
@@ -34,8 +34,8 @@ public final class TransformerKey extends ValueHolder<String> {
 
     public TransformerKey(String scheme) {
         super(scheme);
+        StringHelper.notEmpty(scheme, "scheme");
         this.scheme = scheme;
-        ObjectHelper.notEmpty(scheme, "scheme");
     }
 
     public TransformerKey(DataType from, DataType to) {
@@ -48,22 +48,16 @@ public final class TransformerKey extends ValueHolder<String> {
         return from + "/" + to;
     }
 
-    /**
-     * Test if specified TransformerDefinition matches with data type represented by this key.
-     * @param def TransformerDefinition
-     * @return true if it matches, otherwise false
-     */
-    public boolean match(TransformerDefinition def) {
-        if (scheme != null) {
-            return scheme.equals(def.getScheme());
-        }
-        if (from == null) {
-            return to.toString().equals(def.getToType());
-        }
-        if (to == null) {
-            return from.toString().equals(def.getFromType());
-        }
-        return from.toString().equals(def.getFromType()) && to.toString().equals(def.getToType());
+    public String getScheme() {
+        return scheme;
+    }
+
+    public DataType getFrom() {
+        return from;
+    }
+
+    public DataType getTo() {
+        return to;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/java/org/apache/camel/impl/validator/ProcessorValidator.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/validator/ProcessorValidator.java b/camel-core/src/main/java/org/apache/camel/impl/validator/ProcessorValidator.java
new file mode 100644
index 0000000..e02cbcf
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/impl/validator/ProcessorValidator.java
@@ -0,0 +1,99 @@
+/**
+ * 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.impl.validator;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.Processor;
+import org.apache.camel.ValidationException;
+import org.apache.camel.impl.DefaultExchange;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.Validator;
+import org.apache.camel.util.ServiceHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A {@link Validator} implementation which leverages {@link Processor} to perform validation.
+ * 
+ * {@see Validator}
+ */
+public class ProcessorValidator extends Validator {
+    private static final Logger LOG = LoggerFactory.getLogger(ProcessorValidator.class);
+
+    private Processor processor;
+    private String validatorString;
+
+    public ProcessorValidator(CamelContext context) {
+        setCamelContext(context);
+    }
+
+    /**
+     * Perform content validation with specified type using Processor.
+     * @param message message to apply validation
+     * @param type 'from' data type
+     */
+    @Override
+    public void validate(Message message, DataType type) throws ValidationException {
+        Exchange exchange = message.getExchange();
+        
+        LOG.debug("Sending to validate processor '{}'", processor);
+        DefaultExchange validateExchange = new DefaultExchange(exchange);
+        validateExchange.setIn(message);
+        validateExchange.setProperties(exchange.getProperties());
+        try {
+            processor.process(validateExchange);
+        } catch (Exception e) {
+            if (e instanceof ValidationException) {
+                throw (ValidationException)e;
+            } else {
+                throw new ValidationException(String.format("Validation failed for '%s'", type), validateExchange, e);
+            }
+        }
+    }
+
+    /**
+     * Set Processor.
+     * @param processor Processor
+     * @return this ProcessorTransformer instance
+     */
+    public ProcessorValidator setProcessor(Processor processor) {
+        this.processor = processor;
+        this.validatorString = null;
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        if (validatorString == null) {
+            validatorString =
+                String.format("ProcessorValidator[type='%s', processor='%s']", getType(), processor);
+        }
+        return validatorString;
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        ServiceHelper.startService(this.processor);
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        ServiceHelper.stopService(this.processor);
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/java/org/apache/camel/impl/validator/ValidatorKey.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/validator/ValidatorKey.java b/camel-core/src/main/java/org/apache/camel/impl/validator/ValidatorKey.java
new file mode 100644
index 0000000..df4989e
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/impl/validator/ValidatorKey.java
@@ -0,0 +1,48 @@
+/**
+ * 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.impl.validator;
+
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.model.transformer.TransformerDefinition;
+import org.apache.camel.model.validator.ValidatorDefinition;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.util.StringHelper;
+import org.apache.camel.util.ValueHolder;
+
+/**
+ * Key used in {@link org.apache.camel.spi.ValidatorRegistry} in {@link DefaultCamelContext},
+ * to ensure a consistent lookup.
+ */
+public final class ValidatorKey extends ValueHolder<String> {
+
+    private DataType type;
+
+    public ValidatorKey(DataType type) {
+        super(type.toString());
+        this.type = type;
+    }
+
+    public DataType getType() {
+        return type;
+    }
+
+    @Override
+    public String toString() {
+        return get();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/java/org/apache/camel/management/DefaultManagementLifecycleStrategy.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/management/DefaultManagementLifecycleStrategy.java b/camel-core/src/main/java/org/apache/camel/management/DefaultManagementLifecycleStrategy.java
index 7c3784e..4ab9ab9 100644
--- a/camel-core/src/main/java/org/apache/camel/management/DefaultManagementLifecycleStrategy.java
+++ b/camel-core/src/main/java/org/apache/camel/management/DefaultManagementLifecycleStrategy.java
@@ -50,6 +50,7 @@ import org.apache.camel.impl.ConsumerCache;
 import org.apache.camel.impl.DefaultCamelContext;
 import org.apache.camel.impl.DefaultEndpointRegistry;
 import org.apache.camel.impl.DefaultTransformerRegistry;
+import org.apache.camel.impl.DefaultValidatorRegistry;
 import org.apache.camel.impl.EventDrivenConsumerRoute;
 import org.apache.camel.impl.ProducerCache;
 import org.apache.camel.impl.ThrottlingExceptionRoutePolicy;
@@ -73,6 +74,7 @@ import org.apache.camel.management.mbean.ManagedThrottlingInflightRoutePolicy;
 import org.apache.camel.management.mbean.ManagedTracer;
 import org.apache.camel.management.mbean.ManagedTransformerRegistry;
 import org.apache.camel.management.mbean.ManagedTypeConverterRegistry;
+import org.apache.camel.management.mbean.ManagedValidatorRegistry;
 import org.apache.camel.model.AOPDefinition;
 import org.apache.camel.model.InterceptDefinition;
 import org.apache.camel.model.OnCompletionDefinition;
@@ -495,6 +497,8 @@ public class DefaultManagementLifecycleStrategy extends ServiceSupport implement
             answer = getManagementObjectStrategy().getManagedObjectForEventNotifier(context, (EventNotifier) service);
         } else if (service instanceof DefaultTransformerRegistry) {
             answer = new ManagedTransformerRegistry(context, (DefaultTransformerRegistry)service);
+        } else if (service instanceof DefaultValidatorRegistry) {
+            answer = new ManagedValidatorRegistry(context, (DefaultValidatorRegistry)service);
         } else if (service != null) {
             // fallback as generic service
             answer = getManagementObjectStrategy().getManagedObjectForService(context, service);

http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedTransformerRegistry.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedTransformerRegistry.java b/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedTransformerRegistry.java
index ec58eef..a74c524 100644
--- a/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedTransformerRegistry.java
+++ b/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedTransformerRegistry.java
@@ -40,9 +40,9 @@ import org.apache.camel.util.ObjectHelper;
 public class ManagedTransformerRegistry extends ManagedService implements ManagedTransformerRegistryMBean {
     private final TransformerRegistry transformerRegistry;
 
-    public ManagedTransformerRegistry(CamelContext context, TransformerRegistry endpointRegistry) {
-        super(context, endpointRegistry);
-        this.transformerRegistry = endpointRegistry;
+    public ManagedTransformerRegistry(CamelContext context, TransformerRegistry transformerRegistry) {
+        super(context, transformerRegistry);
+        this.transformerRegistry = transformerRegistry;
     }
 
     public void init(ManagementStrategy strategy) {

http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedValidatorRegistry.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedValidatorRegistry.java b/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedValidatorRegistry.java
new file mode 100644
index 0000000..7cdf54a
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedValidatorRegistry.java
@@ -0,0 +1,102 @@
+/**
+ * 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.management.mbean;
+
+import java.util.Collection;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.TabularData;
+import javax.management.openmbean.TabularDataSupport;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.api.management.ManagedResource;
+import org.apache.camel.api.management.mbean.CamelOpenMBeanTypes;
+import org.apache.camel.api.management.mbean.ManagedValidatorRegistryMBean;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.ManagementStrategy;
+import org.apache.camel.spi.Validator;
+import org.apache.camel.spi.ValidatorRegistry;
+import org.apache.camel.util.ObjectHelper;
+
+/**
+ * @version 
+ */
+@ManagedResource(description = "Managed ValidatorRegistry")
+public class ManagedValidatorRegistry extends ManagedService implements ManagedValidatorRegistryMBean {
+    private final ValidatorRegistry validatorRegistry;
+
+    public ManagedValidatorRegistry(CamelContext context, ValidatorRegistry validatorRegistry) {
+        super(context, validatorRegistry);
+        this.validatorRegistry = validatorRegistry;
+    }
+
+    public void init(ManagementStrategy strategy) {
+        super.init(strategy);
+    }
+
+    public ValidatorRegistry getValidatorRegistry() {
+        return validatorRegistry;
+    }
+
+    public String getSource() {
+        return validatorRegistry.toString();
+    }
+
+    public Integer getDynamicSize() {
+        return validatorRegistry.dynamicSize();
+    }
+
+    public Integer getStaticSize() {
+        return validatorRegistry.staticSize();
+    }
+
+    public Integer getSize() {
+        return validatorRegistry.size();
+    }
+
+    public Integer getMaximumCacheSize() {
+        return validatorRegistry.getMaximumCacheSize();
+    }
+
+    public void purge() {
+        validatorRegistry.purge();
+    }
+
+    @SuppressWarnings("unchecked")
+    public TabularData listValidators() {
+        try {
+            TabularData answer = new TabularDataSupport(CamelOpenMBeanTypes.listValidatorsTabularType());
+            Collection<Validator> validators = validatorRegistry.values();
+            for (Validator validator : validators) {
+                CompositeType ct = CamelOpenMBeanTypes.listValidatorsCompositeType();
+                DataType type = validator.getType();
+                String desc = validator.toString();
+                boolean isStatic = validatorRegistry.isStatic(type);
+                boolean isDynamic = validatorRegistry.isDynamic(type);
+
+                CompositeData data = new CompositeDataSupport(ct, new String[]{"type", "static", "dynamic", "description"},
+                                                              new Object[]{type.toString(), isStatic, isDynamic, desc});
+                answer.put(data);
+            }
+            return answer;
+        } catch (Exception e) {
+            throw ObjectHelper.wrapRuntimeCamelException(e);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/java/org/apache/camel/model/Constants.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/Constants.java b/camel-core/src/main/java/org/apache/camel/model/Constants.java
index d6bbf3b..c145041 100644
--- a/camel-core/src/main/java/org/apache/camel/model/Constants.java
+++ b/camel-core/src/main/java/org/apache/camel/model/Constants.java
@@ -32,7 +32,8 @@ public final class Constants {
         + "org.apache.camel.model.language:"
         + "org.apache.camel.model.loadbalancer:"
         + "org.apache.camel.model.rest:"
-        + "org.apache.camel.model.transformer";
+        + "org.apache.camel.model.transformer:"
+        + "org.apache.camel.model.validator";
 
     public static final String PLACEHOLDER_QNAME = "http://camel.apache.org/schema/placeholder";
 

http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/java/org/apache/camel/model/InputTypeDefinition.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/InputTypeDefinition.java b/camel-core/src/main/java/org/apache/camel/model/InputTypeDefinition.java
index bbf04eb..7a74f8e 100644
--- a/camel-core/src/main/java/org/apache/camel/model/InputTypeDefinition.java
+++ b/camel-core/src/main/java/org/apache/camel/model/InputTypeDefinition.java
@@ -36,8 +36,10 @@ import org.apache.camel.spi.Metadata;
 @XmlRootElement(name = "inputType")
 @XmlAccessorType(XmlAccessType.FIELD)
 public class InputTypeDefinition extends OptionalIdentifiedDefinition<InputTypeDefinition> {
-    @XmlAttribute(required = true)
+    @XmlAttribute @Metadata(required = "true")
     private String urn;
+    @XmlAttribute  @Metadata(defaultValue = "false")
+    private Boolean validate = false;
 
     public InputTypeDefinition() {
     }
@@ -66,6 +68,22 @@ public class InputTypeDefinition extends OptionalIdentifiedDefinition<InputTypeD
         this.urn = "java:" + clazz.getName();
     }
 
+    /**
+     * Get if validation is required for this input type.
+     * @return true if validate
+     */
+    public boolean isValidate() {
+        return this.validate;
+    }
+
+    /**
+     * Set if validation is required for this input type.
+     * @param validate true if validate
+     */
+    public void setValidate(boolean validate) {
+        this.validate = validate;
+    }
+
     @Override
     public String toString() {
         return "inputType[" + urn + "]";

http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/java/org/apache/camel/model/OutputTypeDefinition.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/OutputTypeDefinition.java b/camel-core/src/main/java/org/apache/camel/model/OutputTypeDefinition.java
index 837a447..9862f05 100644
--- a/camel-core/src/main/java/org/apache/camel/model/OutputTypeDefinition.java
+++ b/camel-core/src/main/java/org/apache/camel/model/OutputTypeDefinition.java
@@ -36,8 +36,10 @@ import org.apache.camel.spi.Metadata;
 @XmlRootElement(name = "outputType")
 @XmlAccessorType(XmlAccessType.FIELD)
 public class OutputTypeDefinition extends OptionalIdentifiedDefinition<OutputTypeDefinition> {
-    @XmlAttribute(required = true)
+    @XmlAttribute @Metadata(required = "true")
     private String urn;
+    @XmlAttribute  @Metadata(defaultValue = "false")
+    private Boolean validate = false;
 
     public OutputTypeDefinition() {
     }
@@ -67,6 +69,22 @@ public class OutputTypeDefinition extends OptionalIdentifiedDefinition<OutputTyp
         this.urn = "java:" + clazz.getName();
     }
 
+    /**
+     * Get if validation is required for this output type.
+     * @return true if validate
+     */
+    public boolean isValidate() {
+        return this.validate;
+    }
+
+    /**
+     * Set if validation is required for this output type.
+     * @param validate true if validate
+     */
+    public void setValidate(boolean validate) {
+        this.validate = validate;
+    }
+
     @Override
     public String toString() {
         return "outputType[" + urn + "]";

http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/java/org/apache/camel/model/RouteDefinition.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/RouteDefinition.java b/camel-core/src/main/java/org/apache/camel/model/RouteDefinition.java
index 97078dd..0a3a7ac 100644
--- a/camel-core/src/main/java/org/apache/camel/model/RouteDefinition.java
+++ b/camel-core/src/main/java/org/apache/camel/model/RouteDefinition.java
@@ -637,47 +637,91 @@ public class RouteDefinition extends ProcessorDefinition<RouteDefinition> {
     /**
      * Declare an input type.
      * @param urn input type URN
+     * @param validate if it's true, content validation is performed for this input type
      * @return the builder
      */
-    public RouteDefinition inputType(String urn) {
+    public RouteDefinition inputType(String urn, boolean validate) {
         inputType = new InputTypeDefinition();
         inputType.setUrn(urn);
+        inputType.setValidate(validate);
         return this;
     }
 
     /**
+     * Declare an input type.
+     * @param urn input type URN
+     * @return the builder
+     */
+    public RouteDefinition inputType(String urn) {
+        return inputType(urn, false);
+    }
+
+    /**
      * Declare an input type with Java class.
      * @param clazz Class object of the input type
+     * @param validate if it's true, content validation is performed for this input type
      * @return the builder
      */
-    public RouteDefinition inputType(Class clazz) {
+    public RouteDefinition inputType(Class clazz, boolean validate) {
         inputType = new InputTypeDefinition();
         inputType.setJavaClass(clazz);
+        inputType.setValidate(validate);
         return this;
     }
 
     /**
+     * Declare an input type with Java class.
+     * @param clazz Class object of the input type
+     * @return the builder
+     */
+    public RouteDefinition inputType(Class clazz) {
+        return inputType(clazz, false);
+    }
+
+    /**
      * Declare an output type.
      * @param urn output type URN
+     * @param validate if it's true, content validation is performed for this output type
      * @return the builder
      */
-    public RouteDefinition outputType(String urn) {
+    public RouteDefinition outputType(String urn, boolean validate) {
         outputType = new OutputTypeDefinition();
         outputType.setUrn(urn);
+        outputType.setValidate(validate);
         return this;
     }
 
     /**
+     * Declare an output type.
+     * @param urn output type URN
+     * @return the builder
+     */
+    public RouteDefinition outputType(String urn) {
+        return outputType(urn, false);
+    }
+
+    /**
      * Declare an output type with Java class.
      * @param clazz Class object of the output type
+     * @param validate if it's true, content validation is performed for this output type
      * @return the builder
      */
-    public RouteDefinition outputType(Class clazz) {
+    public RouteDefinition outputType(Class clazz, boolean validate) {
         outputType = new OutputTypeDefinition();
         outputType.setJavaClass(clazz);
+        outputType.setValidate(validate);
         return this;
     }
 
+    /**
+     * Declare an output type with Java class.
+     * @param clazz Class object of the output type
+     * @return the builder
+     */
+    public RouteDefinition outputType(Class clazz) {
+        return outputType(clazz, false);
+    }
+
     // Properties
     // -----------------------------------------------------------------------
 

http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/java/org/apache/camel/model/transformer/CustomTransformerDefinition.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/transformer/CustomTransformerDefinition.java b/camel-core/src/main/java/org/apache/camel/model/transformer/CustomTransformerDefinition.java
index bce6a22..d0ff031 100644
--- a/camel-core/src/main/java/org/apache/camel/model/transformer/CustomTransformerDefinition.java
+++ b/camel-core/src/main/java/org/apache/camel/model/transformer/CustomTransformerDefinition.java
@@ -39,12 +39,12 @@ public class CustomTransformerDefinition extends TransformerDefinition {
     @XmlAttribute
     private String ref;
     @XmlAttribute
-    private String type;
+    private String className;
 
     @Override
     protected Transformer doCreateTransformer(CamelContext context) throws Exception {
-        if (ref == null && type == null) {
-            throw new IllegalArgumentException("'ref' or 'type' must be specified for customTransformer");
+        if (ref == null && className == null) {
+            throw new IllegalArgumentException("'ref' or 'className' must be specified for customTransformer");
         }
         Transformer transformer;
         if (ref != null) {
@@ -56,9 +56,9 @@ public class CustomTransformerDefinition extends TransformerDefinition {
                 throw new IllegalArgumentException(String.format("Transformer '%s' is already in use. Please check if duplicate transformer exists.", ref));
             }
         } else {
-            Class<Transformer> transformerClass = context.getClassResolver().resolveMandatoryClass(type, Transformer.class);
+            Class<Transformer> transformerClass = context.getClassResolver().resolveMandatoryClass(className, Transformer.class);
             if (transformerClass == null) {
-                throw new IllegalArgumentException("Cannot find transformer class: " + type);
+                throw new IllegalArgumentException("Cannot find transformer class: " + className);
             }
             transformer = context.getInjector().newInstance(transformerClass);
 
@@ -74,7 +74,7 @@ public class CustomTransformerDefinition extends TransformerDefinition {
     }
 
     /**
-     * Set a bean reference of the Transformer
+     * Set a bean reference of the {@link Transformer}
      *
      * @param ref the bean reference of the Transformer
      */
@@ -82,17 +82,17 @@ public class CustomTransformerDefinition extends TransformerDefinition {
         this.ref = ref;
     }
 
-    public String getType() {
-        return type;
+    public String getClassName() {
+        return className;
     }
 
     /**
-     * Set a class name of the Transformer
+     * Set a class name of the {@link Transformer}
      *
-     * @param type the class name of the Transformer
+     * @param className the class name of the Transformer
      */
-    public void setType(String type) {
-        this.type = type;
+    public void setClassName(String className) {
+        this.className = className;
     }
 
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/java/org/apache/camel/model/transformer/TransformersDefinition.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/transformer/TransformersDefinition.java b/camel-core/src/main/java/org/apache/camel/model/transformer/TransformersDefinition.java
index ede69cc..88b1b88 100644
--- a/camel-core/src/main/java/org/apache/camel/model/transformer/TransformersDefinition.java
+++ b/camel-core/src/main/java/org/apache/camel/model/transformer/TransformersDefinition.java
@@ -38,17 +38,17 @@ public class TransformersDefinition {
         @XmlElement(required = false, name = "endpointTransformer", type = EndpointTransformerDefinition.class),
         @XmlElement(required = false, name = "customTransformer", type = CustomTransformerDefinition.class)}
         )
-    private List<TransformerDefinition> transforms;
+    private List<TransformerDefinition> transformers;
 
     /**
      * The configured transformers
      */
-    public void setTransformers(List<TransformerDefinition> transforms) {
-        this.transforms = transforms;
+    public void setTransformers(List<TransformerDefinition> transformers) {
+        this.transformers = transformers;
     }
 
-    public List<TransformerDefinition> getTransforms() {
-        return transforms;
+    public List<TransformerDefinition> getTransformers() {
+        return transformers;
     }
 
 }