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:47 UTC
[1/4] camel git commit: CAMEL-10538 Added
inputTypeWithValidate()/outputTypeWithValidate() instead of adding boolean
parameter. Fixed doc.
Repository: camel
Updated Branches:
refs/heads/master f507f4eed -> d676a2f43
CAMEL-10538 Added inputTypeWithValidate()/outputTypeWithValidate() instead of adding boolean parameter. Fixed doc.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/d676a2f4
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/d676a2f4
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/d676a2f4
Branch: refs/heads/master
Commit: d676a2f43632578dcfa6ca4ef069ad163cb9db8b
Parents: f9946b2
Author: Tomohisa Igarashi <tm...@gmail.com>
Authored: Wed Feb 22 21:42:00 2017 +0900
Committer: Claus Ibsen <da...@apache.org>
Committed: Wed Feb 22 14:00:32 2017 +0100
----------------------------------------------------------------------
camel-core/src/main/docs/validator.adoc | 13 ++--
.../org/apache/camel/model/RouteDefinition.java | 72 +++++++++++++-------
.../impl/validator/ValidatorContractTest.java | 4 +-
.../impl/validator/ValidatorRouteTest.java | 8 +--
.../java/sample/camel/SampleCamelRouter.java | 2 +-
5 files changed, 63 insertions(+), 36 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/d676a2f4/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
index afae832..477bdcd 100644
--- a/camel-core/src/main/docs/validator.adoc
+++ b/camel-core/src/main/docs/validator.adoc
@@ -78,7 +78,7 @@ XML DSL:
-------------------------------------------------------------------
<predicateValidator Type="csv:CSVOrder">
<simple>${body} contains '{name:XOrder'</simple>
-</dataFormatTransformer>
+</predicateValidator>
-------------------------------------------------------------------
@@ -107,8 +107,10 @@ And here is an example to specify endpoint ref in XML DSL:
-------------------------------------------------------------------
<endpointValidator uri="validator:xsd/schema.xsd" type="xml"/>
-------------------------------------------------------------------
-
-
+Note that the Endpoint Validator just forwards the message to the specified endpoint. In above example,
+camel forwards the message to the `validator:` endpoint, which actually is a
+link:validator-component.adoc[Validation Component]. You can also use any other validation component like
+link:bean-validation.html[Bean Validation Component].
[[Validator-Custom]]
Custom Validator Options
@@ -166,13 +168,14 @@ XML DSL:
-------------------------------------------------------------------
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`:
+receives the message. Note that `inputTypeWithValidate` is used instead of `inputType` in Java DSL,
+and the `validate` attribute on the inputType declaration is set to `true` in XML DSL:
Java DSL:
[source,java]
-------------------------------------------------------------------
from("direct:abc")
- .inputType("xml:ABCOrder", true)
+ .inputTypeWithValidate("xml:ABCOrder")
.log("${body}");
-------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/d676a2f4/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 0a3a7ac..688cb64 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
@@ -636,90 +636,114 @@ public class RouteDefinition extends ProcessorDefinition<RouteDefinition> {
/**
* Declare an input type.
+ *
+ * @see {@link org.apache.camel.spi.Transformer}
* @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, boolean validate) {
+ public RouteDefinition inputType(String urn) {
inputType = new InputTypeDefinition();
inputType.setUrn(urn);
- inputType.setValidate(validate);
+ inputType.setValidate(false);
return this;
}
/**
- * Declare an input type.
+ * Declare an input type with validation enabled.
+ *
+ * @see {@link org.apache.camel.spi.Transformer}, {@link org.apache.camel.spi.Validator}
* @param urn input type URN
* @return the builder
*/
- public RouteDefinition inputType(String urn) {
- return inputType(urn, false);
+ public RouteDefinition inputTypeWithValidate(String urn) {
+ inputType = new InputTypeDefinition();
+ inputType.setUrn(urn);
+ inputType.setValidate(true);
+ return this;
}
/**
* Declare an input type with Java class.
+ *
+ * @see {@link org.apache.camel.spi.Transformer}
* @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, boolean validate) {
+ public RouteDefinition inputType(Class clazz) {
inputType = new InputTypeDefinition();
inputType.setJavaClass(clazz);
- inputType.setValidate(validate);
+ inputType.setValidate(false);
return this;
}
/**
- * Declare an input type with Java class.
+ * Declare an input type with Java class with validation enabled.
+ *
+ * @see {@link org.apache.camel.spi.Transformer}, {@link org.apache.camel.spi.Validator}
* @param clazz Class object of the input type
* @return the builder
*/
- public RouteDefinition inputType(Class clazz) {
- return inputType(clazz, false);
+ public RouteDefinition inputTypeWithValidate(Class clazz) {
+ inputType = new InputTypeDefinition();
+ inputType.setJavaClass(clazz);
+ inputType.setValidate(true);
+ return this;
}
/**
* Declare an output type.
+ *
+ * @see {@link org.apache.camel.spi.Transformer}
* @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, boolean validate) {
+ public RouteDefinition outputType(String urn) {
outputType = new OutputTypeDefinition();
outputType.setUrn(urn);
- outputType.setValidate(validate);
+ outputType.setValidate(false);
return this;
}
/**
- * Declare an output type.
+ * Declare an output type with validation enabled.
+ *
+ * @see {@link org.apache.camel.spi.Transformer}, {@link org.apache.camel.spi.Validator}
* @param urn output type URN
* @return the builder
*/
- public RouteDefinition outputType(String urn) {
- return outputType(urn, false);
+ public RouteDefinition outputTypeWithValidate(String urn) {
+ outputType = new OutputTypeDefinition();
+ outputType.setUrn(urn);
+ outputType.setValidate(true);
+ return this;
}
/**
* Declare an output type with Java class.
+ *
+ * @see {@link org.apache.camel.spi.Transformer}
* @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, boolean validate) {
+ public RouteDefinition outputType(Class clazz) {
outputType = new OutputTypeDefinition();
outputType.setJavaClass(clazz);
- outputType.setValidate(validate);
+ outputType.setValidate(false);
return this;
}
/**
- * Declare an output type with Java class.
+ * Declare an output type with Java class with validation enabled.
+ *
+ * @see {@link org.apache.camel.spi.Transformer}, {@link org.apache.camel.spi.Validator}
* @param clazz Class object of the output type
* @return the builder
*/
- public RouteDefinition outputType(Class clazz) {
- return outputType(clazz, false);
+ public RouteDefinition outputTypeWithValidate(Class clazz) {
+ outputType = new OutputTypeDefinition();
+ outputType.setJavaClass(clazz);
+ outputType.setValidate(true);
+ return this;
}
// Properties
http://git-wip-us.apache.org/repos/asf/camel/blob/d676a2f4/camel-core/src/test/java/org/apache/camel/impl/validator/ValidatorContractTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/impl/validator/ValidatorContractTest.java b/camel-core/src/test/java/org/apache/camel/impl/validator/ValidatorContractTest.java
index 8633010..a5f65cc 100644
--- a/camel-core/src/test/java/org/apache/camel/impl/validator/ValidatorContractTest.java
+++ b/camel-core/src/test/java/org/apache/camel/impl/validator/ValidatorContractTest.java
@@ -50,7 +50,7 @@ public class ValidatorContractTest extends ContextTestSupport {
.type(A.class)
.withUri("direct:validator");
from("direct:a")
- .inputType(A.class, true)
+ .inputTypeWithValidate(A.class)
.to("mock:a");
from("direct:validator")
.to("mock:validator");
@@ -82,7 +82,7 @@ public class ValidatorContractTest extends ContextTestSupport {
.type(A.class)
.withUri("direct:validator");
from("direct:a")
- .outputType(A.class, true)
+ .outputTypeWithValidate(A.class)
.to("mock:a");
from("direct:validator")
.to("mock:validator");
http://git-wip-us.apache.org/repos/asf/camel/blob/d676a2f4/camel-core/src/test/java/org/apache/camel/impl/validator/ValidatorRouteTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/impl/validator/ValidatorRouteTest.java b/camel-core/src/test/java/org/apache/camel/impl/validator/ValidatorRouteTest.java
index 3d3f7f1..3d92741 100644
--- a/camel-core/src/test/java/org/apache/camel/impl/validator/ValidatorRouteTest.java
+++ b/camel-core/src/test/java/org/apache/camel/impl/validator/ValidatorRouteTest.java
@@ -99,7 +99,7 @@ public class ValidatorRouteTest extends ContextTestSupport {
.type("json")
.withExpression(bodyAs(String.class).contains("{name:XOrder}"));
from("direct:predicate")
- .inputType("json:JsonXOrder", true)
+ .inputTypeWithValidate("json:JsonXOrder")
.outputType("json:JsonXOrderResponse")
.setBody(simple("{name:XOrderResponse}"))
.setProperty(Exchange.OUTPUT_TYPE, constant("json:JsonXOrderResponse"));
@@ -110,7 +110,7 @@ public class ValidatorRouteTest extends ContextTestSupport {
.withUri("myxml:endpoint");
from("direct:endpoint")
.inputType("xml:XmlXOrder")
- .outputType("xml:XmlXOrderResponse", true)
+ .outputTypeWithValidate("xml:XmlXOrderResponse")
.validate(exchangeProperty(VALIDATOR_INVOKED).isNull())
.setBody(simple("<XOrderResponse/>"))
.setProperty(Exchange.OUTPUT_TYPE, constant("xml:XmlXOrderResponse"));
@@ -122,8 +122,8 @@ public class ValidatorRouteTest extends ContextTestSupport {
.type("other:OtherXOrderResponse")
.withJava(OtherXOrderResponseValidator.class);
from("direct:custom")
- .inputType("other:OtherXOrder", true)
- .outputType("other:OtherXOrderResponse", true)
+ .inputTypeWithValidate("other:OtherXOrder")
+ .outputTypeWithValidate("other:OtherXOrderResponse")
.validate(exchangeProperty(VALIDATOR_INVOKED).isEqualTo(OtherXOrderValidator.class))
.setBody(simple("name=XOrderResponse"))
.setProperty(Exchange.OUTPUT_TYPE, constant("other:OtherXOrderResponse"));
http://git-wip-us.apache.org/repos/asf/camel/blob/d676a2f4/examples/camel-example-validator-spring-boot/src/main/java/sample/camel/SampleCamelRouter.java
----------------------------------------------------------------------
diff --git a/examples/camel-example-validator-spring-boot/src/main/java/sample/camel/SampleCamelRouter.java b/examples/camel-example-validator-spring-boot/src/main/java/sample/camel/SampleCamelRouter.java
index b7535ea..d6a4dcf 100644
--- a/examples/camel-example-validator-spring-boot/src/main/java/sample/camel/SampleCamelRouter.java
+++ b/examples/camel-example-validator-spring-boot/src/main/java/sample/camel/SampleCamelRouter.java
@@ -34,7 +34,7 @@ public class SampleCamelRouter extends RouteBuilder {
.withBean("greetingValidator");
from("timer:hello?period={{timer.period}}")
- .outputType("greeting", true)
+ .outputTypeWithValidate("greeting")
.transform(method("myBean", "saySomething"))
.to("stream:out");
}
[2/4] camel git commit: CAMEL-10538 Add declarative validator
according to input/output type
Posted by da...@apache.org.
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/examples/README.adoc
----------------------------------------------------------------------
diff --git a/examples/README.adoc b/examples/README.adoc
index 9eeae55..08e5ff5 100644
--- a/examples/README.adoc
+++ b/examples/README.adoc
@@ -93,7 +93,9 @@ Number of Examples: 84
| link:camel-example-transformer-cdi/README.md[Transformer CDI] (camel-example-transformer-cdi) | Input/Output Type Contract | An example demonstrating declarative transformation along data type declaration using Java DSL and CDI
-| link:camel-example-transformer-demo/README.md[Transformer Spring XML] (camel-example-transformer-demo) | Input/Output Type Contract | An example demonstrating declarative transformation along data type declaration using Spring DSL
+| link:camel-example-transformer-demo/README.md[Transformer and Validator Spring XML] (camel-example-transformer-demo) | Input/Output Type Contract | An example demonstrating declarative transformation and validation along data type declaration using Spring DSL
+
+| link:camel-example-validator-spring-boot/README.md[Validator Spring Boot] (camel-example-validator-spring-boot) | Input/Output Type Contract | An example demonstrating declarative validation along data type declaration using Spring Boot
| link:camel-example-bam/README.md[BAM (deprecated)] (camel-example-bam) | Management and Monitoring | *deprecated* An example showing how to use Camel as a Business Activity Monitoring tool
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/examples/camel-example-transformer-demo/README.md
----------------------------------------------------------------------
diff --git a/examples/camel-example-transformer-demo/README.md b/examples/camel-example-transformer-demo/README.md
index 8f203f8..11123d9 100644
--- a/examples/camel-example-transformer-demo/README.md
+++ b/examples/camel-example-transformer-demo/README.md
@@ -1,9 +1,9 @@
-# Declarative Transformer Demo using Spring XML
+# Declarative Transformer and Validator Demo using Spring XML
### Introduction
-This example shows how to work with declarative transformation by declaring data types.
+This example shows how to work with declarative transformation and validation by declaring data types.
### Build
@@ -20,6 +20,10 @@ To run the example type
You can see the routing rules by looking at the Spring XML configuration lives in
`src/main/resources/META-INF/spring`
+If you enable DEBUG level log for org.apache.camel.processor, you can see the details
+of when/which transformers & validators are applied. Check the
+`src/main/resources/log4j2.properties`
+
### Forum, Help, etc
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/examples/camel-example-transformer-demo/pom.xml
----------------------------------------------------------------------
diff --git a/examples/camel-example-transformer-demo/pom.xml b/examples/camel-example-transformer-demo/pom.xml
index af3759c..d81a437 100644
--- a/examples/camel-example-transformer-demo/pom.xml
+++ b/examples/camel-example-transformer-demo/pom.xml
@@ -27,12 +27,12 @@
<artifactId>camel-example-transformer-demo</artifactId>
<name>Camel :: Example :: Transformer :: Demo</name>
- <description>An example demonstrating declarative transformation along data type declaration using Spring DSL</description>
+ <description>An example demonstrating declarative transformation and validation along data type declaration using Spring DSL</description>
<packaging>jar</packaging>
<properties>
<category>Input/Output Type Contract</category>
- <title>Transformer Spring XML</title>
+ <title>Transformer and Validator Spring XML</title>
</properties>
<dependencies>
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/examples/camel-example-transformer-demo/src/main/java/org/apache/camel/example/transformer/demo/OrderResponseValidator.java
----------------------------------------------------------------------
diff --git a/examples/camel-example-transformer-demo/src/main/java/org/apache/camel/example/transformer/demo/OrderResponseValidator.java b/examples/camel-example-transformer-demo/src/main/java/org/apache/camel/example/transformer/demo/OrderResponseValidator.java
new file mode 100644
index 0000000..2ebf9f3
--- /dev/null
+++ b/examples/camel-example-transformer-demo/src/main/java/org/apache/camel/example/transformer/demo/OrderResponseValidator.java
@@ -0,0 +1,26 @@
+package org.apache.camel.example.transformer.demo;
+
+import org.apache.camel.Message;
+import org.apache.camel.ValidationException;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.Validator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class OrderResponseValidator extends Validator {
+ private static final Logger LOG = LoggerFactory.getLogger(OrderResponseValidator.class);
+
+ @Override
+ public void validate(Message message, DataType type) throws ValidationException {
+ Object body = message.getBody();
+ LOG.info("Validating message body: {}", body);
+ if (!(body instanceof OrderResponse)) {
+ throw new ValidationException(message.getExchange(), "Expected OrderResponse, but was " + body.getClass());
+ }
+ OrderResponse r = (OrderResponse)body;
+ if (!r.isAccepted()) {
+ throw new ValidationException(message.getExchange(), "Order was not accepted:" + r);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/examples/camel-example-transformer-demo/src/main/resources/META-INF/spring/camel-context.xml
----------------------------------------------------------------------
diff --git a/examples/camel-example-transformer-demo/src/main/resources/META-INF/spring/camel-context.xml b/examples/camel-example-transformer-demo/src/main/resources/META-INF/spring/camel-context.xml
index 09c3b72..fa22fe0 100644
--- a/examples/camel-example-transformer-demo/src/main/resources/META-INF/spring/camel-context.xml
+++ b/examples/camel-example-transformer-demo/src/main/resources/META-INF/spring/camel-context.xml
@@ -51,13 +51,23 @@
<camel:dataFormatTransformer ref="jsondf" scheme="json"/>
</camel:transformers>
<!-- END SNIPPET: e3 -->
+ <!-- START SNIPPET: e8 -->
+ <camel:validators>
+ <camel:endpointValidator type="xml" uri="validator:xsd/schema.xsd"/>
+ <camel:predicateValidator type="json">
+ <camel:simple>${body} contains 'orderId' and ${body} not contains 'accepted'</camel:simple>
+ </camel:predicateValidator>
+ <camel:customValidator type="java:org.apache.camel.example.transformer.demo.OrderResponse"
+ className="org.apache.camel.example.transformer.demo.OrderResponseValidator"/>
+ </camel:validators>
+ <!-- END SNIPPET: e8 -->
<!-- START SNIPPET: e4 -->
<camel:route id="xml">
<camel:from uri="direct:xml"/>
<!-- This route expects XML as an input/output type -->
- <camel:inputType urn="xml:XMLOrder"/>
- <camel:outputType urn="xml:XMLOrderResponse"/>
+ <camel:inputType urn="xml:XMLOrder" validate="true"/>
+ <camel:outputType urn="xml:XMLOrderResponse" validate="true"/>
<camel:to uri="direct:java"/>
</camel:route>
<!-- END SNIPPET: e4 -->
@@ -67,7 +77,7 @@
<camel:from uri="direct:json"/>
<!-- This route expects JSON as an input/output type -->
<!-- Only scheme 'json' is specified for the type, which means it handles arbitrary JSON content -->
- <camel:inputType urn="json"/>
+ <camel:inputType urn="json" validate="true"/>
<camel:outputType urn="json"/>
<camel:to uri="direct:java"/>
</camel:route>
@@ -81,7 +91,7 @@
<!-- If it comes from json route, the JSON-Java transformer is applied. -->
<!-- If it's sent via ProducerTemplate directly without specifying input/output type, no transformer is applied. -->
<camel:inputType urn="java:org.apache.camel.example.transformer.demo.Order"/>
- <camel:outputType urn="java:org.apache.camel.example.transformer.demo.OrderResponse"/>
+ <camel:outputType urn="java:org.apache.camel.example.transformer.demo.OrderResponse" validate="true"/>
<camel:wireTap uri="direct:csv"/>
<camel:process ref="orderProcessor"/>
</camel:route>
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/examples/camel-example-transformer-demo/src/main/resources/xsd/schema.xsd
----------------------------------------------------------------------
diff --git a/examples/camel-example-transformer-demo/src/main/resources/xsd/schema.xsd b/examples/camel-example-transformer-demo/src/main/resources/xsd/schema.xsd
new file mode 100644
index 0000000..cd1455e
--- /dev/null
+++ b/examples/camel-example-transformer-demo/src/main/resources/xsd/schema.xsd
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ <xs:element name="order" type="order"/>
+
+ <xs:element name="orderResponse" type="orderResponse"/>
+
+ <xs:complexType name="order">
+ <xs:sequence/>
+ <xs:attribute name="orderId" type="xs:string"/>
+ <xs:attribute name="itemId" type="xs:string"/>
+ <xs:attribute name="quantity" type="xs:int" use="required"/>
+ </xs:complexType>
+
+ <xs:complexType name="orderResponse">
+ <xs:sequence/>
+ <xs:attribute name="orderId" type="xs:string"/>
+ <xs:attribute name="accepted" type="xs:boolean" use="required"/>
+ <xs:attribute name="description" type="xs:string"/>
+ </xs:complexType>
+</xs:schema>
+
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/examples/camel-example-validator-spring-boot/pom.xml
----------------------------------------------------------------------
diff --git a/examples/camel-example-validator-spring-boot/pom.xml b/examples/camel-example-validator-spring-boot/pom.xml
new file mode 100644
index 0000000..91ebba2
--- /dev/null
+++ b/examples/camel-example-validator-spring-boot/pom.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>examples</artifactId>
+ <version>2.19.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>camel-example-validator-spring-boot</artifactId>
+ <name>Camel :: Example :: Validator :: Spring Boot</name>
+ <description>An example showing how to work with declarative validation and Spring Boot</description>
+
+ <properties>
+ <category>Input/Output Type Contract</category>
+ <title>Validator Spring Boot</title>
+
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+ <spring.boot-version>${spring-boot-version}</spring.boot-version>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ <!-- Spring Boot BOM -->
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-dependencies</artifactId>
+ <version>${spring.boot-version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ <!-- Camel BOM -->
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-spring-boot-dependencies</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+
+ <!-- Spring Boot -->
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-web</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-undertow</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-actuator</artifactId>
+ </dependency>
+
+ <!-- Camel -->
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-spring-boot-starter</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-stream-starter</artifactId>
+ </dependency>
+
+ <!-- test -->
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-test-spring</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <version>${spring-boot-version}</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>repackage</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/examples/camel-example-validator-spring-boot/readme.adoc
----------------------------------------------------------------------
diff --git a/examples/camel-example-validator-spring-boot/readme.adoc b/examples/camel-example-validator-spring-boot/readme.adoc
new file mode 100644
index 0000000..1bc83e4
--- /dev/null
+++ b/examples/camel-example-validator-spring-boot/readme.adoc
@@ -0,0 +1,28 @@
+# Camel Example Validator Spring Boot
+
+This example shows how to work with a simple Apache Camel application using Spring Boot with declarative content validation enabled.
+
+The example generates messages using timer trigger, writes them to standard output. The output type is declared as `greeting`, which has corresponding validator defined.
+
+## Camel routes
+
+The Camel route is located in the `SampleCamelRouter` class. In this class the route
+starts from a timer, that triggers every 2nd second and calls a Spring Bean `SampleBean`
+which returns a message, that is routed to a stream endpoint which writes to standard output.
+The output type is declared as `greeting`, and the validator `GreetingValidator` is registered
+to be triggered for `greeting` output message right after the routing.
+
+## Using Camel components
+
+Apache Camel provides 200+ components which you can use to integrate and route messages between many systems
+and data formats. To use any of these Camel components, add the component as a dependency to your project.
+
+## How to run
+
+You can run this example using
+
+ mvn spring-boot:run
+
+## More information
+
+You can find more information about Apache Camel at the website: http://camel.apache.org/
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/examples/camel-example-validator-spring-boot/src/main/java/sample/camel/GreetingValidator.java
----------------------------------------------------------------------
diff --git a/examples/camel-example-validator-spring-boot/src/main/java/sample/camel/GreetingValidator.java b/examples/camel-example-validator-spring-boot/src/main/java/sample/camel/GreetingValidator.java
new file mode 100644
index 0000000..79129ff
--- /dev/null
+++ b/examples/camel-example-validator-spring-boot/src/main/java/sample/camel/GreetingValidator.java
@@ -0,0 +1,31 @@
+package sample.camel;
+
+import org.apache.camel.Message;
+import org.apache.camel.ValidationException;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.Validator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+@Component("greetingValidator")
+public class GreetingValidator extends Validator {
+
+ private static final Logger LOG = LoggerFactory.getLogger(GreetingValidator.class);
+
+ @Value("${greeting}")
+ private String greeting;
+
+ @Override
+ public void validate(Message message, DataType type) throws ValidationException {
+ Object body = message.getBody();
+ LOG.info("Validating : [{}]", body);
+ if (body instanceof String && body.equals(greeting)) {
+ LOG.info("OK");
+ } else {
+ throw new ValidationException(message.getExchange(), "Wrong content");
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/examples/camel-example-validator-spring-boot/src/main/java/sample/camel/SampleBean.java
----------------------------------------------------------------------
diff --git a/examples/camel-example-validator-spring-boot/src/main/java/sample/camel/SampleBean.java b/examples/camel-example-validator-spring-boot/src/main/java/sample/camel/SampleBean.java
new file mode 100644
index 0000000..b60ef69
--- /dev/null
+++ b/examples/camel-example-validator-spring-boot/src/main/java/sample/camel/SampleBean.java
@@ -0,0 +1,38 @@
+/**
+ * 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 sample.camel;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+/**
+ * A bean that returns a message when you call the {@link #saySomething()} method.
+ * <p/>
+ * Uses <tt>@Component("myBean")</tt> to register this bean with the name <tt>myBean</tt>
+ * that we use in the Camel route to lookup this bean.
+ */
+@Component("myBean")
+public class SampleBean {
+
+ @Value("${greeting}")
+ private String say;
+
+ public String saySomething() {
+ return say;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/examples/camel-example-validator-spring-boot/src/main/java/sample/camel/SampleCamelApplication.java
----------------------------------------------------------------------
diff --git a/examples/camel-example-validator-spring-boot/src/main/java/sample/camel/SampleCamelApplication.java b/examples/camel-example-validator-spring-boot/src/main/java/sample/camel/SampleCamelApplication.java
new file mode 100644
index 0000000..5d9304a
--- /dev/null
+++ b/examples/camel-example-validator-spring-boot/src/main/java/sample/camel/SampleCamelApplication.java
@@ -0,0 +1,37 @@
+/**
+ * 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 sample.camel;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+//CHECKSTYLE:OFF
+/**
+ * A sample Spring Boot application that starts the Camel routes.
+ */
+@SpringBootApplication
+public class SampleCamelApplication {
+
+ /**
+ * A main method to start this application.
+ */
+ public static void main(String[] args) {
+ SpringApplication.run(SampleCamelApplication.class, args);
+ }
+
+}
+//CHECKSTYLE:ON
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/examples/camel-example-validator-spring-boot/src/main/java/sample/camel/SampleCamelRouter.java
----------------------------------------------------------------------
diff --git a/examples/camel-example-validator-spring-boot/src/main/java/sample/camel/SampleCamelRouter.java b/examples/camel-example-validator-spring-boot/src/main/java/sample/camel/SampleCamelRouter.java
new file mode 100644
index 0000000..b7535ea
--- /dev/null
+++ b/examples/camel-example-validator-spring-boot/src/main/java/sample/camel/SampleCamelRouter.java
@@ -0,0 +1,42 @@
+/**
+ * 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 sample.camel;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.springframework.stereotype.Component;
+
+/**
+ * A simple Camel route that triggers from a timer and calls a bean and prints to system out.
+ * <p/>
+ * Use <tt>@Component</tt> to make Camel auto detect this route when starting.
+ */
+@Component
+public class SampleCamelRouter extends RouteBuilder {
+
+ @Override
+ public void configure() throws Exception {
+ validator()
+ .type("greeting")
+ .withBean("greetingValidator");
+
+ from("timer:hello?period={{timer.period}}")
+ .outputType("greeting", true)
+ .transform(method("myBean", "saySomething"))
+ .to("stream:out");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/examples/camel-example-validator-spring-boot/src/main/resources/application.properties
----------------------------------------------------------------------
diff --git a/examples/camel-example-validator-spring-boot/src/main/resources/application.properties b/examples/camel-example-validator-spring-boot/src/main/resources/application.properties
new file mode 100644
index 0000000..1d32a64
--- /dev/null
+++ b/examples/camel-example-validator-spring-boot/src/main/resources/application.properties
@@ -0,0 +1,28 @@
+#
+# 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.
+#
+
+# the name of Camel
+camel.springboot.name = SampleCamel
+
+# properties used in the Camel route and beans
+# --------------------------------------------
+
+# what to say
+greeting = Hello World
+
+# how often to trigger the timer
+timer.period = 2000
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/examples/camel-example-validator-spring-boot/src/test/java/sample/camel/SampleCamelApplicationTest.java
----------------------------------------------------------------------
diff --git a/examples/camel-example-validator-spring-boot/src/test/java/sample/camel/SampleCamelApplicationTest.java b/examples/camel-example-validator-spring-boot/src/test/java/sample/camel/SampleCamelApplicationTest.java
new file mode 100644
index 0000000..7d53276
--- /dev/null
+++ b/examples/camel-example-validator-spring-boot/src/test/java/sample/camel/SampleCamelApplicationTest.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 sample.camel;
+
+import java.util.concurrent.TimeUnit;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.builder.NotifyBuilder;
+import org.apache.camel.test.spring.CamelSpringBootRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import static org.junit.Assert.assertTrue;
+
+@RunWith(CamelSpringBootRunner.class)
+@SpringBootTest(classes = SampleCamelApplication.class)
+public class SampleCamelApplicationTest {
+
+ @Autowired
+ private CamelContext camelContext;
+
+ @Test
+ public void shouldProduceMessages() throws Exception {
+ // we expect that one or more messages is automatic done by the Camel
+ // route as it uses a timer to trigger
+ NotifyBuilder notify = new NotifyBuilder(camelContext).whenDone(1).create();
+
+ assertTrue(notify.matches(10, TimeUnit.SECONDS));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/examples/pom.xml
----------------------------------------------------------------------
diff --git a/examples/pom.xml b/examples/pom.xml
index a0c31a1..05a2e98 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -110,6 +110,7 @@
<module>camel-example-twitter-salesforce</module>
<module>camel-example-twitter-websocket</module>
<module>camel-example-twitter-websocket-blueprint</module>
+ <module>camel-example-validator-spring-boot</module>
<module>camel-example-widget-gadget-cdi</module>
<module>camel-example-widget-gadget-java</module>
<module>camel-example-widget-gadget-xml</module>
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractLocalCamelController.java
----------------------------------------------------------------------
diff --git a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractLocalCamelController.java b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractLocalCamelController.java
index a4d33d4..f37d85b 100644
--- a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractLocalCamelController.java
+++ b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractLocalCamelController.java
@@ -47,6 +47,7 @@ import org.apache.camel.spi.ManagementAgent;
import org.apache.camel.spi.RestRegistry;
import org.apache.camel.spi.RuntimeEndpointRegistry;
import org.apache.camel.spi.Transformer;
+import org.apache.camel.spi.Validator;
import org.apache.camel.util.JsonSchemaHelper;
/**
@@ -646,6 +647,27 @@ public abstract class AbstractLocalCamelController extends AbstractCamelControll
return answer;
}
+ @Override
+ public List<Map<String, String>> getValidators(String camelContextName) throws Exception {
+ List<Map<String, String>> answer = new ArrayList<Map<String, String>>();
+
+ if (camelContextName != null) {
+ CamelContext context = this.getLocalCamelContext(camelContextName);
+ if (context != null) {
+ List<Validator> validators = new ArrayList<Validator>(context.getValidatorRegistry().values());
+ for (Validator validator : validators) {
+ Map<String, String> row = new LinkedHashMap<String, String>();
+ row.put("camelContextName", context.getName());
+ row.put("type", validator.getType().toString());
+ row.put("state", validator.getStatus().toString());
+ row.put("description", validator.toString());
+ answer.add(row);
+ }
+ }
+ }
+ return answer;
+ }
+
private static String getEndpointState(Endpoint endpoint) {
// must use String type to be sure remote JMX can read the attribute without requiring Camel classes.
if (endpoint instanceof StatefulService) {
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CamelController.java
----------------------------------------------------------------------
diff --git a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CamelController.java b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CamelController.java
index 2cf70a4..67de587 100644
--- a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CamelController.java
+++ b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CamelController.java
@@ -376,4 +376,13 @@ public interface CamelController {
* @throws java.lang.Exception can be thrown
*/
List<Map<String, String>> getTransformers(String camelContextName) throws Exception;
+
+ /**
+ * Return the validators
+ *
+ * @param camelContextName the Camel context.
+ * @return a list of key/value pairs with validator information
+ * @throws java.lang.Exception can be thrown
+ */
+ List<Map<String, String>> getValidators(String camelContextName) throws Exception;
}
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/ValidatorListCommand.java
----------------------------------------------------------------------
diff --git a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/ValidatorListCommand.java b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/ValidatorListCommand.java
new file mode 100644
index 0000000..07608f0
--- /dev/null
+++ b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/ValidatorListCommand.java
@@ -0,0 +1,185 @@
+/**
+ * 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.commands;
+
+import java.io.PrintStream;
+import java.net.URLDecoder;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.camel.util.JsonSchemaHelper;
+import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.URISupport;
+
+/**
+ * List the Camel validators available in the JVM.
+ */
+public class ValidatorListCommand extends AbstractCamelCommand {
+
+ private static final String CONTEXT_NAME_COLUMN_LABEL = "Context";
+ private static final String TYPE_COLUMN_LABEL = "Type";
+ private static final String STATE_COLUMN_LABEL = "State";
+ private static final String DESCRIPTION_COLUMN_LABEL = "Description";
+
+ private static final int DEFAULT_COLUMN_WIDTH_INCREMENT = 0;
+ private static final String DEFAULT_FIELD_PREAMBLE = " ";
+ private static final String DEFAULT_FIELD_POSTAMBLE = " ";
+ private static final String DEFAULT_HEADER_PREAMBLE = " ";
+ private static final String DEFAULT_HEADER_POSTAMBLE = " ";
+ private static final int DEFAULT_FORMAT_BUFFER_LENGTH = 24;
+ // endpoint uris can be very long so clip by default after 120 chars
+ private static final int MAX_COLUMN_WIDTH = 120;
+ private static final int MIN_COLUMN_WIDTH = 12;
+
+ boolean decode = true;
+ boolean verbose;
+ boolean explain;
+ private final String context;
+
+ public ValidatorListCommand(String context, boolean decode, boolean verbose, boolean explain) {
+ this.decode = decode;
+ this.verbose = verbose;
+ this.explain = explain;
+ this.context = context;
+ }
+
+ @Override
+ public Object execute(CamelController camelController, PrintStream out, PrintStream err) throws Exception {
+ final List<Map<String, String>> camelContextInfos = camelController.getCamelContexts(this.context);
+ final Map<String, List<Map<String, String>>> contextsToValidators = new HashMap<>();
+
+ for (Map<String, String> camelContextInfo : camelContextInfos) {
+ String camelContextName = camelContextInfo.get("name");
+ final List<Map<String, String>> validators = camelController.getValidators(camelContextName);
+ if (validators.isEmpty()) {
+ continue;
+ }
+ contextsToValidators.put(camelContextName, validators);
+ }
+
+ final Map<String, Integer> columnWidths = computeColumnWidths(contextsToValidators);
+ final String headerFormat = buildFormatString(columnWidths, true);
+ final String rowFormat = buildFormatString(columnWidths, false);
+
+ for (Map.Entry<String, List<Map<String, String>>> stringListEntry : contextsToValidators.entrySet()) {
+ final String camelContextName = stringListEntry.getKey();
+ final List<Map<String, String>> validators = stringListEntry.getValue();
+
+ if (verbose) {
+ out.println(String.format(headerFormat, CONTEXT_NAME_COLUMN_LABEL, TYPE_COLUMN_LABEL, STATE_COLUMN_LABEL, DESCRIPTION_COLUMN_LABEL));
+ out.println(String.format(headerFormat, "-------", "----", "-----", "-----------"));
+ } else {
+ out.println(String.format(headerFormat, CONTEXT_NAME_COLUMN_LABEL, TYPE_COLUMN_LABEL, STATE_COLUMN_LABEL));
+ out.println(String.format(headerFormat, "-------", "----", "-----"));
+ }
+ for (Map<String, String> row : validators) {
+ String type = row.get("type");
+ String state = row.get("state");
+ if (verbose) {
+ String desc = row.get("description");
+ out.println(String.format(rowFormat, camelContextName, type, state, desc));
+ } else {
+ out.println(String.format(rowFormat, camelContextName, type, state));
+ }
+ }
+ }
+ return null;
+ }
+
+ private Map<String, Integer> computeColumnWidths(final Map<String, List<Map<String, String>>> contextsToValidators) throws Exception {
+ int maxCamelContextLen = 0;
+ int maxTypeLen = 0;
+ int maxStatusLen = 0;
+ int maxDescLen = 0;
+
+ for (Map.Entry<String, List<Map<String, String>>> stringListEntry : contextsToValidators.entrySet()) {
+ final String camelContextName = stringListEntry.getKey();
+
+ maxCamelContextLen = java.lang.Math.max(maxCamelContextLen, camelContextName.length());
+
+ final List<Map<String, String>> validators = stringListEntry.getValue();
+
+
+ for (Map<String, String> row : validators) {
+ String type = row.get("type");
+ maxTypeLen = java.lang.Math.max(maxTypeLen, type == null ? 0 : type.length());
+ String status = row.get("state");
+ maxStatusLen = java.lang.Math.max(maxStatusLen, status == null ? 0 : status.length());
+ if (verbose) {
+ String desc = row.get("description");
+ maxDescLen = java.lang.Math.max(maxDescLen, desc == null ? 0 : desc.length());
+ }
+ }
+ }
+
+ final Map<String, Integer> retval = new Hashtable<>();
+ retval.put(CONTEXT_NAME_COLUMN_LABEL, maxCamelContextLen);
+ retval.put(TYPE_COLUMN_LABEL, maxTypeLen);
+ retval.put(STATE_COLUMN_LABEL, maxStatusLen);
+ if (verbose) {
+ retval.put(DESCRIPTION_COLUMN_LABEL, maxDescLen);
+ }
+
+ return retval;
+ }
+
+ private String buildFormatString(final Map<String, Integer> columnWidths, final boolean isHeader) {
+ final String fieldPreamble;
+ final String fieldPostamble;
+ final int columnWidthIncrement;
+
+ if (isHeader) {
+ fieldPreamble = DEFAULT_HEADER_PREAMBLE;
+ fieldPostamble = DEFAULT_HEADER_POSTAMBLE;
+ } else {
+ fieldPreamble = DEFAULT_FIELD_PREAMBLE;
+ fieldPostamble = DEFAULT_FIELD_POSTAMBLE;
+ }
+ columnWidthIncrement = DEFAULT_COLUMN_WIDTH_INCREMENT;
+
+ int ctxLen = java.lang.Math.min(columnWidths.get(CONTEXT_NAME_COLUMN_LABEL) + columnWidthIncrement, getMaxColumnWidth());
+ ctxLen = Math.max(MIN_COLUMN_WIDTH, ctxLen);
+ int typeLen = java.lang.Math.min(columnWidths.get(TYPE_COLUMN_LABEL) + columnWidthIncrement, getMaxColumnWidth());
+ typeLen = Math.max(MIN_COLUMN_WIDTH, typeLen);
+ int stateLen = -1;
+ if (verbose) {
+ stateLen = java.lang.Math.min(columnWidths.get(STATE_COLUMN_LABEL) + columnWidthIncrement, getMaxColumnWidth());
+ stateLen = Math.max(MIN_COLUMN_WIDTH, stateLen);
+ }
+ // last row does not have min width
+
+ final StringBuilder retval = new StringBuilder(DEFAULT_FORMAT_BUFFER_LENGTH);
+ retval.append(fieldPreamble).append("%-").append(ctxLen).append('.').append(ctxLen).append('s').append(fieldPostamble).append(' ');
+ retval.append(fieldPreamble).append("%-").append(typeLen).append('.').append(typeLen).append('s').append(fieldPostamble).append(' ');
+ if (verbose) {
+ retval.append(fieldPreamble).append("%-").append(stateLen).append('.').append(stateLen).append('s').append(fieldPostamble).append(' ');
+ }
+ retval.append(fieldPreamble).append("%s").append(fieldPostamble).append(' ');
+
+ return retval.toString();
+ }
+
+ private int getMaxColumnWidth() {
+ if (verbose) {
+ return Integer.MAX_VALUE;
+ } else {
+ return MAX_COLUMN_WIDTH;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/platforms/commands/commands-core/src/test/java/org/apache/camel/commands/AbstractLocalCamelControllerTest.java
----------------------------------------------------------------------
diff --git a/platforms/commands/commands-core/src/test/java/org/apache/camel/commands/AbstractLocalCamelControllerTest.java b/platforms/commands/commands-core/src/test/java/org/apache/camel/commands/AbstractLocalCamelControllerTest.java
index 682ac0d..896dd46 100644
--- a/platforms/commands/commands-core/src/test/java/org/apache/camel/commands/AbstractLocalCamelControllerTest.java
+++ b/platforms/commands/commands-core/src/test/java/org/apache/camel/commands/AbstractLocalCamelControllerTest.java
@@ -21,11 +21,13 @@ import java.util.Map;
import org.apache.camel.CamelContext;
import org.apache.camel.Message;
+import org.apache.camel.ValidationException;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.impl.ExplicitCamelContextNameStrategy;
import org.apache.camel.spi.DataType;
import org.apache.camel.spi.Transformer;
+import org.apache.camel.spi.Validator;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -50,6 +52,9 @@ public class AbstractLocalCamelControllerTest {
.fromType("xml:foo")
.toType("json:bar")
.withJava(DummyTransformer.class);
+ validator()
+ .type("xml:foo")
+ .withJava(DummyValidator.class);
from("direct:start1").id("route1").delay(100).to("mock:result1");
from("direct:start2").id("route2").delay(100).to("mock:result2");
from("direct:start3").id("route3").delay(100).to("mock:result3");
@@ -117,7 +122,6 @@ public class AbstractLocalCamelControllerTest {
@Test
public void testTransformer() throws Exception {
- context.resolveTransformer(new DataType("xml:foo"), new DataType("json:bar"));
List<Map<String, String>> transformers = localCamelController.getTransformers("context1");
assertEquals(1, transformers.size());
Map<String, String> dummyTransformer = transformers.get(0);
@@ -129,9 +133,26 @@ public class AbstractLocalCamelControllerTest {
assertEquals("Started", dummyTransformer.get("state"));
}
+ @Test
+ public void testValidator() throws Exception {
+ List<Map<String, String>> validators = localCamelController.getValidators("context1");
+ assertEquals(1, validators.size());
+ Map<String, String> dummyValidator = validators.get(0);
+ assertEquals("context1", dummyValidator.get("camelContextName"));
+ assertEquals("DummyValidator[type='xml:foo']", dummyValidator.get("description"));
+ assertEquals("xml:foo", dummyValidator.get("type"));
+ assertEquals("Started", dummyValidator.get("state"));
+ }
+
public static class DummyTransformer extends Transformer {
@Override
public void transform(Message message, DataType from, DataType to) throws Exception {
}
}
+
+ public static class DummyValidator extends Validator {
+ @Override
+ public void validate(Message message, DataType type) throws ValidationException {
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/platforms/commands/commands-core/src/test/java/org/apache/camel/commands/TransformerListCommandTest.java
----------------------------------------------------------------------
diff --git a/platforms/commands/commands-core/src/test/java/org/apache/camel/commands/TransformerListCommandTest.java b/platforms/commands/commands-core/src/test/java/org/apache/camel/commands/TransformerListCommandTest.java
index 5f71849..0acd9e5 100644
--- a/platforms/commands/commands-core/src/test/java/org/apache/camel/commands/TransformerListCommandTest.java
+++ b/platforms/commands/commands-core/src/test/java/org/apache/camel/commands/TransformerListCommandTest.java
@@ -78,18 +78,15 @@ public class TransformerListCommandTest {
etd.setToType("json:bar");
etd.setUri("direct:transformer");
context.getTransformers().add(etd);
- context.resolveTransformer(new DataType("xml:foo"), new DataType("json:bar"));
DataFormatTransformerDefinition dftd = new DataFormatTransformerDefinition();
dftd.setFromType(this.getClass());
dftd.setToType("xml:test");
dftd.setDataFormatType(new StringDataFormat());
context.getTransformers().add(dftd);
- context.resolveTransformer(new DataType(this.getClass()), new DataType("xml:test"));
CustomTransformerDefinition ctd = new CustomTransformerDefinition();
ctd.setScheme("custom");
- ctd.setType(MyTransformer.class.getName());
+ ctd.setClassName(MyTransformer.class.getName());
context.getTransformers().add(ctd);
- context.resolveTransformer("custom");
context.setNameStrategy(new ExplicitCamelContextNameStrategy("foobar"));
context.start();
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/platforms/commands/commands-core/src/test/java/org/apache/camel/commands/ValidatorListCommandTest.java
----------------------------------------------------------------------
diff --git a/platforms/commands/commands-core/src/test/java/org/apache/camel/commands/ValidatorListCommandTest.java b/platforms/commands/commands-core/src/test/java/org/apache/camel/commands/ValidatorListCommandTest.java
new file mode 100644
index 0000000..3457520
--- /dev/null
+++ b/platforms/commands/commands-core/src/test/java/org/apache/camel/commands/ValidatorListCommandTest.java
@@ -0,0 +1,121 @@
+/**
+ * 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.commands;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Message;
+import org.apache.camel.ValidationException;
+import org.apache.camel.builder.ExpressionBuilder;
+import org.apache.camel.builder.PredicateBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.builder.SimpleBuilder;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.impl.ExplicitCamelContextNameStrategy;
+import org.apache.camel.model.dataformat.StringDataFormat;
+import org.apache.camel.model.language.ExpressionDefinition;
+import org.apache.camel.model.transformer.CustomTransformerDefinition;
+import org.apache.camel.model.transformer.DataFormatTransformerDefinition;
+import org.apache.camel.model.transformer.EndpointTransformerDefinition;
+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.spi.DataType;
+import org.apache.camel.spi.Transformer;
+import org.apache.camel.spi.Validator;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class ValidatorListCommandTest {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ValidatorListCommandTest.class);
+
+ @Test
+ public void testValidatorList() throws Exception {
+ String out = doTest(false);
+ assertTrue(out.contains("xml:foo"));
+ assertTrue(out.contains("java:" + this.getClass().getName()));
+ assertTrue(out.contains("custom"));
+ assertTrue(out.contains("Started"));
+ assertFalse(out.contains("ProcessorValidator["));
+ assertFalse(out.contains("processor='validate(body)'"));
+ assertFalse(out.contains("processor='sendTo(direct://validator)'"));
+ assertFalse(out.contains("MyValidator["));
+ }
+
+ @Test
+ public void testValidatorListVerbose() throws Exception {
+ String out = doTest(true);
+ assertTrue(out.contains("xml:foo"));
+ assertTrue(out.contains("java:" + this.getClass().getName()));
+ assertTrue(out.contains("custom"));
+ assertTrue(out.contains("Started"));
+ assertTrue(out.contains("ProcessorValidator["));
+ assertTrue(out.contains("processor='validate(body)'"));
+ assertTrue(out.contains("processor='sendTo(direct://validator)'"));
+ assertTrue(out.contains("MyValidator["));
+ }
+
+ private String doTest(boolean verbose) throws Exception {
+ CamelContext context = new DefaultCamelContext();
+ EndpointValidatorDefinition evd = new EndpointValidatorDefinition();
+ evd.setType("xml:foo");
+ evd.setUri("direct:validator");
+ context.getValidators().add(evd);
+ PredicateValidatorDefinition pvd = new PredicateValidatorDefinition();
+ pvd.setType(this.getClass());
+ pvd.setExpression(new ExpressionDefinition(ExpressionBuilder.bodyExpression()));
+ context.getValidators().add(pvd);
+ CustomValidatorDefinition cvd = new CustomValidatorDefinition();
+ cvd.setType("custom");
+ cvd.setClassName(MyValidator.class.getName());
+ context.getValidators().add(cvd);
+ context.setNameStrategy(new ExplicitCamelContextNameStrategy("foobar"));
+ context.start();
+
+ CamelController controller = new DummyCamelController(context);
+
+ OutputStream os = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(os);
+
+ ValidatorListCommand command = new ValidatorListCommand(null, false, verbose, false);
+ command.execute(controller, ps, null);
+
+ String out = os.toString();
+ assertNotNull(out);
+ LOG.info("\n\n{}\n", out);
+
+ context.stop();
+ return out;
+ }
+
+ public static class MyValidator extends Validator {
+ @Override
+ public void validate(Message message, DataType type) throws ValidationException {
+ return;
+ }
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/platforms/commands/commands-jolokia/src/main/java/org/apache/camel/commands/jolokia/DefaultJolokiaCamelController.java
----------------------------------------------------------------------
diff --git a/platforms/commands/commands-jolokia/src/main/java/org/apache/camel/commands/jolokia/DefaultJolokiaCamelController.java b/platforms/commands/commands-jolokia/src/main/java/org/apache/camel/commands/jolokia/DefaultJolokiaCamelController.java
index e342840..cf30c39 100644
--- a/platforms/commands/commands-jolokia/src/main/java/org/apache/camel/commands/jolokia/DefaultJolokiaCamelController.java
+++ b/platforms/commands/commands-jolokia/src/main/java/org/apache/camel/commands/jolokia/DefaultJolokiaCamelController.java
@@ -820,6 +820,50 @@ public class DefaultJolokiaCamelController extends AbstractCamelController imple
return answer;
}
+ @Override
+ public List<Map<String, String>> getValidators(String camelContextName) throws Exception {
+ if (jolokia == null) {
+ throw new IllegalStateException("Need to connect to remote jolokia first");
+ }
+
+ List<Map<String, String>> answer = new ArrayList<Map<String, String>>();
+
+ ObjectName found = lookupCamelContext(camelContextName);
+ if (found != null) {
+ String pattern = String.format("%s:context=%s,type=services,name=DefaultValidatorRegistry", found.getDomain(), found.getKeyProperty("context"));
+ ObjectName on = ObjectName.getInstance(pattern);
+
+ J4pExecResponse response = jolokia.execute(new J4pExecRequest(on, "listValidators()"));
+ if (response != null) {
+ JSONObject data = response.getValue();
+ if (data != null) {
+ for (Object obj : data.values()) {
+ JSONObject data2 = (JSONObject) obj;
+ JSONObject service = (JSONObject) data2.values().iterator().next();
+
+ Map<String, String> row = new LinkedHashMap<String, String>();
+ row.put("type", asString(service.get("type")));
+ row.put("static", asString(service.get("static")));
+ row.put("dynamic", asString(service.get("dynamic")));
+ row.put("description", asString(service.get("description")));
+ answer.add(row);
+ }
+ }
+ }
+
+ // sort the list
+ Collections.sort(answer, new Comparator<Map<String, String>>() {
+ @Override
+ public int compare(Map<String, String> service1, Map<String, String> service2) {
+ String type1 = service1.get("type");
+ String type2 = service2.get("type");
+ return type1.compareTo(type2);
+ }
+ });
+ }
+ return answer;
+ }
+
private static String asKey(String attributeKey) {
char ch = Character.toLowerCase(attributeKey.charAt(0));
return ch + attributeKey.substring(1);
[3/4] camel git commit: CAMEL-10538 Add declarative validator
according to input/output type
Posted by da...@apache.org.
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/java/org/apache/camel/model/validator/CustomValidatorDefinition.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/validator/CustomValidatorDefinition.java b/camel-core/src/main/java/org/apache/camel/model/validator/CustomValidatorDefinition.java
new file mode 100644
index 0000000..5c1e164
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/model/validator/CustomValidatorDefinition.java
@@ -0,0 +1,98 @@
+/**
+ * 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.model.validator;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.Transformer;
+import org.apache.camel.spi.Validator;
+
+/**
+ * Represents a CustomValidator. One of the bean reference (ref) or fully qualified class name (className)
+ * of the custom {@link Validator} needs to be specified.
+ *
+ * {@see ValidatorDefinition}
+ * {@see Validator}
+ */
+@Metadata(label = "validation")
+@XmlType(name = "customValidator")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class CustomValidatorDefinition extends ValidatorDefinition {
+
+ @XmlAttribute
+ private String ref;
+ @XmlAttribute
+ private String className;
+
+ @Override
+ protected Validator doCreateValidator(CamelContext context) throws Exception {
+ if (ref == null && className == null) {
+ throw new IllegalArgumentException("'ref' or 'type' must be specified for customValidator");
+ }
+ Validator validator;
+ if (ref != null) {
+ validator = context.getRegistry().lookupByNameAndType(ref, Validator.class);
+ if (validator == null) {
+ throw new IllegalArgumentException("Cannot find validator with ref:" + ref);
+ }
+ if (validator.getType() != null) {
+ throw new IllegalArgumentException(String.format("Validator '%s' is already in use. Please check if duplicate validator exists.", ref));
+ }
+ } else {
+ Class<Validator> validatorClass = context.getClassResolver().resolveMandatoryClass(className, Validator.class);
+ if (validatorClass == null) {
+ throw new IllegalArgumentException("Cannot find validator class: " + className);
+ }
+ validator = context.getInjector().newInstance(validatorClass);
+
+ }
+ validator.setCamelContext(context);
+ return validator.setType(getType());
+ }
+
+ public String getRef() {
+ return ref;
+ }
+
+ /**
+ * Set a bean reference of the {@link Validator}
+ *
+ * @param ref the bean reference of the Transformer
+ */
+ public void setRef(String ref) {
+ this.ref = ref;
+ }
+
+ public String getClassName() {
+ return className;
+ }
+
+ /**
+ * Set a class name of the {@link Validator}
+ *
+ * @param className the class name of the Validator
+ */
+ 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/validator/EndpointValidatorDefinition.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/validator/EndpointValidatorDefinition.java b/camel-core/src/main/java/org/apache/camel/model/validator/EndpointValidatorDefinition.java
new file mode 100644
index 0000000..537216b
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/model/validator/EndpointValidatorDefinition.java
@@ -0,0 +1,97 @@
+/**
+ * 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.model.validator;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlType;
+
+import org.w3c.dom.ls.LSResourceResolver;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Endpoint;
+import org.apache.camel.ExchangePattern;
+import org.apache.camel.component.validator.ValidatorEndpoint;
+import org.apache.camel.component.validator.ValidatorResourceResolverFactory;
+import org.apache.camel.impl.validator.ProcessorValidator;
+import org.apache.camel.processor.SendProcessor;
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.Validator;
+import org.apache.camel.util.ObjectHelper;
+
+/**
+ * Represents an endpoint {@link Validator} which leverages camel validator component such as
+ * <a href="http://camel.apache.org/validation.html">Validator Component</a> and
+ * <a href="http://camel.apache.org/bean-validation.html">Bean Validator Component</a> to
+ * perform content validation. A {@link ProcessorValidator} will be created internally
+ * with a {@link SendProcessor} which forwards the message to the validator Endpoint.
+ *
+ * {@see ValidatorDefinition}
+ * {@see Validator}
+ */
+@Metadata(label = "validation")
+@XmlType(name = "endpointValidator")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class EndpointValidatorDefinition extends ValidatorDefinition {
+
+ @XmlAttribute
+ private String ref;
+ @XmlAttribute
+ private String uri;
+
+ @Override
+ protected Validator doCreateValidator(CamelContext context) throws Exception {
+ Endpoint endpoint = uri != null ? context.getEndpoint(uri)
+ : context.getRegistry().lookupByNameAndType(ref, Endpoint.class);
+ SendProcessor processor = new SendProcessor(endpoint, ExchangePattern.InOut);
+ return new ProcessorValidator(context)
+ .setProcessor(processor)
+ .setType(getType());
+ }
+
+ public String getRef() {
+ return ref;
+ }
+
+ /**
+ * Set the reference of the Endpoint.
+ *
+ * @param ref reference of the Endpoint
+ */
+ public void setRef(String ref) {
+ this.ref = ref;
+ }
+
+ public String getUri() {
+ return uri;
+ }
+
+ /**
+ * Set the URI of the Endpoint.
+ *
+ * @param uri URI of the Endpoint
+ */
+ public void setUri(String uri) {
+ this.uri = uri;
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/java/org/apache/camel/model/validator/PredicateValidatorDefinition.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/validator/PredicateValidatorDefinition.java b/camel-core/src/main/java/org/apache/camel/model/validator/PredicateValidatorDefinition.java
new file mode 100644
index 0000000..89f72a5
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/model/validator/PredicateValidatorDefinition.java
@@ -0,0 +1,76 @@
+/**
+ * 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.model.validator;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElementRef;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Expression;
+import org.apache.camel.Predicate;
+import org.apache.camel.impl.validator.ProcessorValidator;
+import org.apache.camel.model.ExpressionNodeHelper;
+import org.apache.camel.model.language.ExpressionDefinition;
+import org.apache.camel.processor.validation.PredicateValidatingProcessor;
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.Transformer;
+import org.apache.camel.spi.Validator;
+
+/**
+ * Represents a predicate {@link Validator} which leverages expression or predicates to
+ * perform content validation. A {@link ProcessorValidator} will be created internally
+ * with a {@link PredicateValidatingProcessor} which validates the message according to specified expression/predicates.
+ *
+ * {@see ValidatorDefinition}
+ * {@see Validator}
+ */
+@Metadata(label = "validation")
+@XmlType(name = "predicateValidator")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class PredicateValidatorDefinition extends ValidatorDefinition {
+
+ @XmlElementRef
+ private ExpressionDefinition expression;
+
+ @Override
+ protected Validator doCreateValidator(CamelContext context) throws Exception {
+ Predicate pred = getExpression().createPredicate(context);
+ PredicateValidatingProcessor processor = new PredicateValidatingProcessor(pred);
+ return new ProcessorValidator(context)
+ .setProcessor(processor)
+ .setType(getType());
+ }
+
+ public ExpressionDefinition getExpression() {
+ return expression;
+ }
+
+ public void setExpression(ExpressionDefinition expression) {
+ // favour using the helper to set the expression as it can unwrap some unwanted builders when using Java DSL
+ if (expression instanceof Expression) {
+ this.expression = ExpressionNodeHelper.toExpressionDefinition((Expression) expression);
+ } else if (expression instanceof Predicate) {
+ this.expression = ExpressionNodeHelper.toExpressionDefinition((Predicate) expression);
+ } else {
+ this.expression = expression;
+ }
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/java/org/apache/camel/model/validator/ValidatorDefinition.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/validator/ValidatorDefinition.java b/camel-core/src/main/java/org/apache/camel/model/validator/ValidatorDefinition.java
new file mode 100644
index 0000000..0a0db9f
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/model/validator/ValidatorDefinition.java
@@ -0,0 +1,80 @@
+/**
+ * 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.model.validator;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.camel.CamelContext;
+import org.apache.camel.model.InputTypeDefinition;
+import org.apache.camel.model.OutputTypeDefinition;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.Validator;
+
+/**
+ * <p>Represents a {@link Validator} which declaratively validates message content
+ * according to the input type declared by {@link InputTypeDefinition} and/or output type
+ * declared by {@link OutputTypeDefinition}.</p>
+ * <p>If you specify type='xml:ABC', the validator
+ * will be picked up when current message type is 'xml:ABC'.
+ * If you specify type='json', then it will be picked up for all of json validation.
+ *
+ * {@see Validator}
+ * {@see InputTypeDefinition}
+ * {@see OutputTypeDefinition}
+ */
+@Metadata(label = "validation")
+@XmlType(name = "validator")
+@XmlAccessorType(XmlAccessType.FIELD)
+public abstract class ValidatorDefinition {
+
+ @XmlAttribute
+ private String type;
+
+ public Validator createValidator(CamelContext context) throws Exception {
+ return doCreateValidator(context);
+ };
+
+ protected abstract Validator doCreateValidator(CamelContext context) throws Exception;
+
+ public String getType() {
+ return type;
+ }
+
+ /**
+ * Set the data type name.
+ * If you specify 'xml:XYZ', the validator will be picked up if message type is
+ * 'xml:XYZ'. If you specify just 'xml', the validator matches with all of
+ * 'xml' message type like 'xml:ABC' or 'xml:DEF'.
+ *
+ * @param type data type name
+ */
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ /**
+ * Set the data type using Java class.
+ * @param clazz Java class
+ */
+ public void setType(Class<?> clazz) {
+ this.type = new DataType(clazz).toString();
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/java/org/apache/camel/model/validator/ValidatorsDefinition.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/validator/ValidatorsDefinition.java b/camel-core/src/main/java/org/apache/camel/model/validator/ValidatorsDefinition.java
new file mode 100644
index 0000000..cb90c2c
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/model/validator/ValidatorsDefinition.java
@@ -0,0 +1,54 @@
+/**
+ * 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.model.validator;
+
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElements;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.camel.spi.Metadata;
+
+/**
+ * To configure validators.
+ */
+@Metadata(label = "validation", title = "Validations")
+@XmlRootElement(name = "validators")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class ValidatorsDefinition {
+
+ @XmlElements({
+ @XmlElement(required = false, name = "endpointValidator", type = EndpointValidatorDefinition.class),
+ @XmlElement(required = false, name = "predicateValidator", type = PredicateValidatorDefinition.class),
+ @XmlElement(required = false, name = "customValidator", type = CustomValidatorDefinition.class)}
+ )
+ private List<ValidatorDefinition> validators;
+
+ /**
+ * The configured transformers
+ */
+ public void setValidators(List<ValidatorDefinition> validators) {
+ this.validators = validators;
+ }
+
+ public List<ValidatorDefinition> getValidators() {
+ return validators;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/java/org/apache/camel/model/validator/package-info.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/validator/package-info.java b/camel-core/src/main/java/org/apache/camel/model/validator/package-info.java
new file mode 100644
index 0000000..14173ec
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/model/validator/package-info.java
@@ -0,0 +1,24 @@
+/**
+ * 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.
+ */
+
+/**
+ * The JAXB POJOs for the
+ * <a href="http://camel.apache.org/transformer.html">Transformers</a> used to transform message contents
+ * according to declared data types inside <a href="http://camel.apache.org/components.html">components</a>
+ */
+@javax.xml.bind.annotation.XmlSchema(namespace = "http://camel.apache.org/schema/spring", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
+package org.apache.camel.model.validator;
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/java/org/apache/camel/processor/ContractAdvice.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/processor/ContractAdvice.java b/camel-core/src/main/java/org/apache/camel/processor/ContractAdvice.java
index a3dad33..6a53e7b 100644
--- a/camel-core/src/main/java/org/apache/camel/processor/ContractAdvice.java
+++ b/camel-core/src/main/java/org/apache/camel/processor/ContractAdvice.java
@@ -19,9 +19,11 @@ package org.apache.camel.processor;
import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.Message;
+import org.apache.camel.ValidationException;
import org.apache.camel.spi.Contract;
import org.apache.camel.spi.DataType;
import org.apache.camel.spi.Transformer;
+import org.apache.camel.spi.Validator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -29,7 +31,6 @@ import org.slf4j.LoggerFactory;
* A {@code CamelInternalProcessorAdvice} which performs Transformation and Validation
* according to the data type Contract.
*
- * TODO add declarative validation
* @see CamelInternalProcessor, CamelInternalProcessorAdvice
*/
public class ContractAdvice implements CamelInternalProcessorAdvice {
@@ -45,58 +46,66 @@ public class ContractAdvice implements CamelInternalProcessorAdvice {
public Object before(Exchange exchange) throws Exception {
DataType from = getCurrentType(exchange, Exchange.INPUT_TYPE);
DataType to = contract.getInputType();
- if (to != null && !to.equals(from)) {
- LOG.debug("Looking for transformer for INPUT: from='{}', to='{}'", from, to);
- doTransform(exchange.getIn(), from, to);
- exchange.setProperty(Exchange.INPUT_TYPE, to);
+ if (to != null) {
+ if (!to.equals(from)) {
+ LOG.debug("Looking for transformer for INPUT: from='{}', to='{}'", from, to);
+ doTransform(exchange.getIn(), from, to);
+ exchange.setProperty(Exchange.INPUT_TYPE, to);
+ }
+ if (contract.isValidateInput()) {
+ doValidate(exchange.getIn(), to);
+ }
}
return null;
}
@Override
public void after(Exchange exchange, Object data) throws Exception {
+ if (exchange.isFailed()) {
+ // TODO can we add FAULT_TYPE processing?
+ return;
+ }
+
Message target = exchange.hasOut() ? exchange.getOut() : exchange.getIn();
if (!exchange.hasOut() && exchange.getProperty(Exchange.OUTPUT_TYPE) == null) {
exchange.setProperty(Exchange.OUTPUT_TYPE, exchange.getProperty(Exchange.INPUT_TYPE));
}
DataType from = getCurrentType(exchange, Exchange.OUTPUT_TYPE);
DataType to = contract.getOutputType();
- if (to != null && !to.equals(from)) {
- LOG.debug("Looking for transformer for OUTPUT: from='{}', to='{}'", from, to);
- doTransform(target, from, to);
- exchange.setProperty(Exchange.OUTPUT_TYPE, to);
+ if (to != null) {
+ if (!to.equals(from)) {
+ LOG.debug("Looking for transformer for OUTPUT: from='{}', to='{}'", from, to);
+ doTransform(target, from, to);
+ exchange.setProperty(Exchange.OUTPUT_TYPE, to);
+ }
+ if (contract.isValidateOutput()) {
+ doValidate(target, to);
+ }
}
}
private void doTransform(Message message, DataType from, DataType to) throws Exception {
+ if (from == null) {
+ // If 'from' is null, only Java-Java convertion is performed.
+ // It means if 'to' is other than Java, it's assumed to be already in expected shape.
+ convertIfRequired(message, to);
+ return;
+ }
+
// transform into 'from' type before performing declared transformation
convertIfRequired(message, from);
- if (applyExactlyMatchedTransformer(message, from, to)) {
- // Found exactly matched transformer. Java-Java transformer is also allowed.
+ if (applyMatchedTransformer(message, from, to)) {
+ // Found matched transformer. Java-Java transformer is also allowed.
return;
- } else if (from == null || from.isJavaType()) {
+ } else if (from.isJavaType()) {
if (convertIfRequired(message, to)) {
// Java->Java transformation just relies on TypeConverter if no explicit transformer
return;
- } else if (from == null) {
- // use body class as a from type, or do nothing with assuming it's already in expected shape
- applyTransformerByClass(message, to);
- return;
- } else if (applyTransformerByToModel(message, from, to)) {
- // Java->Other transformation - found a transformer supports 'to' data model
- return;
- }
- } else if (from != null) {
- if (to.isJavaType()) {
- if (applyTransformerByFromModel(message, from, to)) {
- // Other->Java transformation - found a transformer supprts 'from' data model
- return;
- }
- } else if (applyTransformerChain(message, from, to)) {
- // Other->Other transformation - found a transformer chain
- return;
}
+ } else if (applyTransformerChain(message, from, to)) {
+ // Other->Other transformation - found a transformer chain
+ return;
}
throw new IllegalArgumentException("No Transformer found for [from='" + from + "', to='" + to + "']");
@@ -125,27 +134,11 @@ public class ContractAdvice implements CamelInternalProcessorAdvice {
}
return false;
}
- private boolean applyExactlyMatchedTransformer(Message message, DataType from, DataType to) throws Exception {
+ private boolean applyMatchedTransformer(Message message, DataType from, DataType to) throws Exception {
Transformer transformer = message.getExchange().getContext().resolveTransformer(from, to);
return applyTransformer(transformer, message, from, to);
}
- private boolean applyTransformerByClass(Message message, DataType to) throws Exception {
- DataType from = new DataType(message.getBody().getClass());
- Transformer transformer = message.getExchange().getContext().resolveTransformer(from, to);
- return applyTransformer(transformer, message, from, to);
- }
-
- private boolean applyTransformerByToModel(Message message, DataType from, DataType to) throws Exception {
- Transformer transformer = message.getExchange().getContext().resolveTransformer(to.getModel());
- return applyTransformer(transformer, message, from, to);
- }
-
- private boolean applyTransformerByFromModel(Message message, DataType from, DataType to) throws Exception {
- Transformer transformer = message.getExchange().getContext().resolveTransformer(from.getModel());
- return applyTransformer(transformer, message, from, to);
- }
-
private boolean applyTransformerChain(Message message, DataType from, DataType to) throws Exception {
CamelContext context = message.getExchange().getContext();
Transformer fromTransformer = context.resolveTransformer(from.getModel());
@@ -175,4 +168,14 @@ public class ContractAdvice implements CamelInternalProcessorAdvice {
}
return null;
}
+
+ private void doValidate(Message message, DataType type) throws ValidationException {
+ Validator validator = message.getExchange().getContext().resolveValidator(type);
+ if (validator != null) {
+ LOG.debug("Applying validator: type='{}', validator='{}'", type, validator);
+ validator.validate(message, type);
+ } else {
+ throw new ValidationException(message.getExchange(), String.format("No Validator found for '%s'", type));
+ }
+ }
}
\ 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/spi/Contract.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/spi/Contract.java b/camel-core/src/main/java/org/apache/camel/spi/Contract.java
index 8cc90c9..b9de3bf 100644
--- a/camel-core/src/main/java/org/apache/camel/spi/Contract.java
+++ b/camel-core/src/main/java/org/apache/camel/spi/Contract.java
@@ -23,6 +23,8 @@ public class Contract {
private DataType inputType;
private DataType outputType;
+ private boolean validateInput;
+ private boolean validateOutput;
private String contractString;
public DataType getInputType() {
@@ -69,6 +71,38 @@ public class Contract {
this.contractString = null;
}
+ /**
+ *
+ * @return
+ */
+ public boolean isValidateInput() {
+ return validateInput;
+ }
+
+ /**
+ *
+ * @param validate
+ */
+ public void setValidateInput(boolean validate) {
+ this.validateInput = validate;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public boolean isValidateOutput() {
+ return validateOutput;
+ }
+
+ /**
+ *
+ * @param validate
+ */
+ public void setValidateOutput(boolean validate) {
+ this.validateOutput = validate;
+ }
+
@Override
public String toString() {
if (contractString == null) {
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/java/org/apache/camel/spi/TransformerRegistry.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/spi/TransformerRegistry.java b/camel-core/src/main/java/org/apache/camel/spi/TransformerRegistry.java
index 85acd1c..c4d73d4 100644
--- a/camel-core/src/main/java/org/apache/camel/spi/TransformerRegistry.java
+++ b/camel-core/src/main/java/org/apache/camel/spi/TransformerRegistry.java
@@ -16,10 +16,12 @@
*/
package org.apache.camel.spi;
+import java.util.List;
import java.util.Map;
import org.apache.camel.Endpoint;
import org.apache.camel.StaticService;
+import org.apache.camel.model.transformer.TransformerDefinition;
/**
* Registry to cache transformers in memory.
@@ -40,6 +42,14 @@ import org.apache.camel.StaticService;
public interface TransformerRegistry<K> extends Map<K, Transformer>, StaticService {
/**
+ * Lookup a {@link Transformer} in the registry which supports the transformation for
+ * the data types represented by the key.
+ * @param key a key represents the from/to data types to transform
+ * @return {@link Transformer} if matched, otherwise null
+ */
+ Transformer resolveTransformer(K key);
+
+ /**
* Number of transformers in the static registry.
*/
int staticSize();
@@ -85,7 +95,7 @@ public interface TransformerRegistry<K> extends Map<K, Transformer>, StaticServi
boolean isDynamic(String scheme);
/**
- * Whether the given transformer is stored in the dynamic cache
+ * Whether the given {@link Transformer} is stored in the dynamic cache
*
* @param from 'from' data type
* @param to 'to' data type
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/java/org/apache/camel/spi/Validator.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/spi/Validator.java b/camel-core/src/main/java/org/apache/camel/spi/Validator.java
new file mode 100644
index 0000000..1ba2998
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/spi/Validator.java
@@ -0,0 +1,96 @@
+/**
+ * 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.spi;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.ValidationException;
+import org.apache.camel.model.InputTypeDefinition;
+import org.apache.camel.model.OutputTypeDefinition;
+import org.apache.camel.support.ServiceSupport;
+
+/**
+ * <a href="http://camel.apache.org/transformer.html">Transformer</a>
+ * performs message transformation according to the declared data type.
+ * There are two Exchange property indicates current message type, {@link Exchange#INPUT_TYPE}
+ * holds input message type and {@link Exchange#OUTPUT_TYPE} holds output message type. If the
+ * input type and/or output type declared by {@link InputTypeDefinition}
+ * and/or {@link OutputTypeDefinition} in the route definition is different from those property
+ * at runtime, camel internal processor look for a Transformer which transforms from
+ * the current message type to the expected message type.
+ *
+ * @see InputTypeDefinition
+ * @see OutputTypeDefinition
+ */
+public abstract class Validator extends ServiceSupport implements CamelContextAware {
+
+ private CamelContext camelContext;
+ private DataType type;
+
+ /**
+ * Perform data validation with specified type.
+ *
+ * @param message message to apply validation
+ * @param type the data type
+ * @throws ValidationException thrown if any validation error is detected
+ */
+ public abstract void validate(Message message, DataType type) throws ValidationException;
+
+ /**
+ * Get 'from' data type.
+ */
+ public DataType getType() {
+ return type;
+ };
+
+ /**
+ * Set data type.
+ *
+ * @param type data type
+ */
+ public Validator setType(String type) {
+ this.type = new DataType(type);
+ return this;
+ }
+
+ @Override
+ public CamelContext getCamelContext() {
+ return this.camelContext;
+ }
+
+ @Override
+ public void setCamelContext(CamelContext context) {
+ this.camelContext = context;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%s[type='%s']", this.getClass().getSimpleName(), type);
+ }
+
+ @Override
+ protected void doStart() throws Exception {
+ // no-op
+ }
+
+ @Override
+ protected void doStop() throws Exception {
+ // no-op
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/java/org/apache/camel/spi/ValidatorRegistry.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/spi/ValidatorRegistry.java b/camel-core/src/main/java/org/apache/camel/spi/ValidatorRegistry.java
new file mode 100644
index 0000000..82d1020
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/spi/ValidatorRegistry.java
@@ -0,0 +1,93 @@
+/**
+ * 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.spi;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.camel.Endpoint;
+import org.apache.camel.StaticService;
+import org.apache.camel.model.validator.ValidatorDefinition;
+
+/**
+ * Registry to cache validators in memory.
+ * <p/>
+ * The registry contains two caches:
+ * <ul>
+ * <li>static - which keeps all the validators in the cache for the entire lifecycle</li>
+ * <li>dynamic - which keeps the validators in a {@link org.apache.camel.util.LRUCache} and may evict validators which hasn't been requested recently</li>
+ * </ul>
+ * The static cache stores all the validators that are created as part of setting up and starting routes.
+ * The static cache has no upper limit.
+ * <p/>
+ * The dynamic cache stores the validators that are created and used ad-hoc, such as from custom Java code that creates new validators etc.
+ * The dynamic cache has an upper limit, that by default is 1000 entries.
+ *
+ * @param <K> validator key
+ */
+public interface ValidatorRegistry<K> extends Map<K, Validator>, StaticService {
+
+ /**
+ * Lookup a {@link Validator} in the registry which supports the validation for
+ * the data type represented by the key.
+ * @param key a key represents the data type
+ * @return {@link Validator} if matched, otherwise null
+ */
+ Validator resolveValidator(K key);
+
+ /**
+ * Number of validators in the static registry.
+ */
+ int staticSize();
+
+ /**
+ * Number of validators in the dynamic registry
+ */
+ int dynamicSize();
+
+ /**
+ * Maximum number of entries to store in the dynamic registry
+ */
+ int getMaximumCacheSize();
+
+ /**
+ * Purges the cache (removes validators from the dynamic cache)
+ */
+ void purge();
+
+ /**
+ * Whether the given {@link Validator} is stored in the static cache
+ *
+ * @param type the data type
+ * @return <tt>true</tt> if in static cache, <tt>false</tt> if not
+ */
+ boolean isStatic(DataType type);
+
+ /**
+ * Whether the given {@link Validator} is stored in the dynamic cache
+ *
+ * @param type the data type
+ * @return <tt>true</tt> if in dynamic cache, <tt>false</tt> if not
+ */
+ boolean isDynamic(DataType type);
+
+ /**
+ * Cleanup the cache (purging stale entries)
+ */
+ void cleanUp();
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/java/org/apache/camel/util/CamelContextHelper.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/util/CamelContextHelper.java b/camel-core/src/main/java/org/apache/camel/util/CamelContextHelper.java
index 8be19d7..a133b73 100644
--- a/camel-core/src/main/java/org/apache/camel/util/CamelContextHelper.java
+++ b/camel-core/src/main/java/org/apache/camel/util/CamelContextHelper.java
@@ -254,6 +254,68 @@ public final class CamelContextHelper {
}
/**
+ * Gets the maximum transformer cache size.
+ * <p/>
+ * Will use the property set on CamelContext with the key {@link Exchange#MAXIMUM_TRANSFORMER_CACHE_SIZE}.
+ * If no property has been set, then it will fallback to return a size of 1000.
+ *
+ * @param camelContext the camel context
+ * @return the maximum cache size
+ * @throws IllegalArgumentException is thrown if the property is illegal
+ */
+ public static int getMaximumTransformerCacheSize(CamelContext camelContext) throws IllegalArgumentException {
+ if (camelContext != null) {
+ String s = camelContext.getGlobalOption(Exchange.MAXIMUM_TRANSFORMER_CACHE_SIZE);
+ if (s != null) {
+ // we cannot use Camel type converters as they may not be ready this early
+ try {
+ Integer size = Integer.valueOf(s);
+ if (size == null || size <= 0) {
+ throw new IllegalArgumentException("Property " + Exchange.MAXIMUM_TRANSFORMER_CACHE_SIZE + " must be a positive number, was: " + s);
+ }
+ return size;
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Property " + Exchange.MAXIMUM_TRANSFORMER_CACHE_SIZE + " must be a positive number, was: " + s, e);
+ }
+ }
+ }
+
+ // 1000 is the default fallback
+ return 1000;
+ }
+
+ /**
+ * Gets the maximum validator cache size.
+ * <p/>
+ * Will use the property set on CamelContext with the key {@link Exchange#MAXIMUM_VALIDATOR_CACHE_SIZE}.
+ * If no property has been set, then it will fallback to return a size of 1000.
+ *
+ * @param camelContext the camel context
+ * @return the maximum cache size
+ * @throws IllegalArgumentException is thrown if the property is illegal
+ */
+ public static int getMaximumValidatorCacheSize(CamelContext camelContext) throws IllegalArgumentException {
+ if (camelContext != null) {
+ String s = camelContext.getGlobalOption(Exchange.MAXIMUM_VALIDATOR_CACHE_SIZE);
+ if (s != null) {
+ // we cannot use Camel type converters as they may not be ready this early
+ try {
+ Integer size = Integer.valueOf(s);
+ if (size == null || size <= 0) {
+ throw new IllegalArgumentException("Property " + Exchange.MAXIMUM_VALIDATOR_CACHE_SIZE + " must be a positive number, was: " + s);
+ }
+ return size;
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Property " + Exchange.MAXIMUM_VALIDATOR_CACHE_SIZE + " must be a positive number, was: " + s, e);
+ }
+ }
+ }
+
+ // 1000 is the default fallback
+ return 1000;
+ }
+
+ /**
* Parses the given text and handling property placeholders as well
*
* @param camelContext the camel context
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/main/resources/org/apache/camel/model/validator/jaxb.index
----------------------------------------------------------------------
diff --git a/camel-core/src/main/resources/org/apache/camel/model/validator/jaxb.index b/camel-core/src/main/resources/org/apache/camel/model/validator/jaxb.index
new file mode 100644
index 0000000..7cdaef6
--- /dev/null
+++ b/camel-core/src/main/resources/org/apache/camel/model/validator/jaxb.index
@@ -0,0 +1,21 @@
+## ------------------------------------------------------------------------
+## 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.
+## ------------------------------------------------------------------------
+CustomValidatorDefinition
+EndpointValidatorDefinition
+PredicateValidatorDefinition
+ValidatorDefinition
+ValidatorsDefinition
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/test/java/org/apache/camel/builder/TransformerBuilderTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/builder/TransformerBuilderTest.java b/camel-core/src/test/java/org/apache/camel/builder/TransformerBuilderTest.java
index 9a7e895..1cdd30a 100644
--- a/camel-core/src/test/java/org/apache/camel/builder/TransformerBuilderTest.java
+++ b/camel-core/src/test/java/org/apache/camel/builder/TransformerBuilderTest.java
@@ -59,9 +59,11 @@ public class TransformerBuilderTest extends TestSupport {
@Override
public void configure() throws Exception {
transformer().fromType("xml:foo").toType("json:bar").withDataFormat(new StringDataFormat());
+ from("direct:input").log("test");
}
};
ctx.addRoutes(builder);
+ ctx.start();
Transformer transformer = ctx.resolveTransformer(new DataType("xml:foo"), new DataType("json:bar"));
assertNotNull(transformer);
assertEquals(DataFormatTransformer.class, transformer.getClass());
@@ -78,10 +80,11 @@ public class TransformerBuilderTest extends TestSupport {
@Override
public void configure() throws Exception {
transformer().fromType("json:foo").toType("xml:bar").withUri("direct:transformer");
- from("direct:transformer");
+ from("direct:transformer").log("test");
}
};
ctx.addRoutes(builder);
+ ctx.start();
Transformer transformer = ctx.resolveTransformer(new DataType("json:foo"), new DataType("xml:bar"));
assertNotNull(transformer);
assertEquals(ProcessorTransformer.class, transformer.getClass());
@@ -100,9 +103,11 @@ public class TransformerBuilderTest extends TestSupport {
@Override
public void configure() throws Exception {
transformer().scheme("other").withJava(MyTransformer.class);
+ from("direct:input").log("test");
}
};
ctx.addRoutes(builder);
+ ctx.start();
Transformer transformer = ctx.resolveTransformer("other");
assertNotNull(transformer);
assertEquals(MyTransformer.class, transformer.getClass());
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/test/java/org/apache/camel/impl/MultipleLifecycleStrategyTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/impl/MultipleLifecycleStrategyTest.java b/camel-core/src/test/java/org/apache/camel/impl/MultipleLifecycleStrategyTest.java
index 2bab7f3..40ef701 100644
--- a/camel-core/src/test/java/org/apache/camel/impl/MultipleLifecycleStrategyTest.java
+++ b/camel-core/src/test/java/org/apache/camel/impl/MultipleLifecycleStrategyTest.java
@@ -51,7 +51,7 @@ public class MultipleLifecycleStrategyTest extends TestSupport {
context.stop();
List<String> expectedEvents = Arrays.asList("onContextStart", "onServiceAdd", "onServiceAdd", "onServiceAdd", "onServiceAdd", "onServiceAdd", "onServiceAdd", "onServiceAdd",
- "onServiceAdd", "onServiceAdd", "onServiceAdd", "onServiceAdd", "onServiceAdd", "onComponentAdd", "onEndpointAdd", "onComponentRemove", "onContextStop");
+ "onServiceAdd", "onServiceAdd", "onServiceAdd", "onServiceAdd", "onServiceAdd", "onServiceAdd", "onComponentAdd", "onEndpointAdd", "onComponentRemove", "onContextStop");
assertEquals(expectedEvents, dummy1.getEvents());
assertEquals(expectedEvents, dummy2.getEvents());
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/test/java/org/apache/camel/impl/validator/ValidatorContractTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/impl/validator/ValidatorContractTest.java b/camel-core/src/test/java/org/apache/camel/impl/validator/ValidatorContractTest.java
new file mode 100644
index 0000000..8633010
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/impl/validator/ValidatorContractTest.java
@@ -0,0 +1,115 @@
+/**
+ * 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 java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Converter;
+import org.apache.camel.Exchange;
+import org.apache.camel.TypeConverters;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.model.DataFormatDefinition;
+import org.apache.camel.spi.DataFormat;
+import org.apache.camel.spi.RouteContext;
+import org.junit.Test;
+
+public class ValidatorContractTest extends ContextTestSupport {
+
+ @Override
+ public boolean isUseRouteBuilder() {
+ return false;
+ }
+
+ @Test
+ public void testInputTypeOnly() throws Exception {
+ context.getTypeConverterRegistry().addTypeConverters(new MyTypeConverters());
+ context.addRoutes(new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ validator()
+ .type(A.class)
+ .withUri("direct:validator");
+ from("direct:a")
+ .inputType(A.class, true)
+ .to("mock:a");
+ from("direct:validator")
+ .to("mock:validator");
+ }
+ });
+ context.start();
+
+ MockEndpoint mocka = context.getEndpoint("mock:a", MockEndpoint.class);
+ MockEndpoint mockv = context.getEndpoint("mock:validator", MockEndpoint.class);
+ mocka.setExpectedCount(1);
+ mockv.setExpectedCount(1);
+ Object answer = template.requestBody("direct:a", "foo");
+ mocka.assertIsSatisfied();
+ mockv.assertIsSatisfied();
+ Exchange exa = mocka.getExchanges().get(0);
+ assertEquals(A.class, exa.getIn().getBody().getClass());
+ Exchange exv = mockv.getExchanges().get(0);
+ assertEquals(A.class, exv.getIn().getBody().getClass());
+ assertEquals(A.class, answer.getClass());
+ }
+
+ @Test
+ public void testOutputTypeOnly() throws Exception {
+ context.getTypeConverterRegistry().addTypeConverters(new MyTypeConverters());
+ context.addRoutes(new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ validator()
+ .type(A.class)
+ .withUri("direct:validator");
+ from("direct:a")
+ .outputType(A.class, true)
+ .to("mock:a");
+ from("direct:validator")
+ .to("mock:validator");
+ }
+ });
+ context.start();
+
+ MockEndpoint mocka = context.getEndpoint("mock:a", MockEndpoint.class);
+ MockEndpoint mockv = context.getEndpoint("mock:validator", MockEndpoint.class);
+ mocka.setExpectedCount(1);
+ mockv.setExpectedCount(1);
+ Object answer = template.requestBody("direct:a", "foo");
+ mocka.assertIsSatisfied();
+ mockv.assertIsSatisfied();
+ Exchange exa = mocka.getExchanges().get(0);
+ assertEquals("foo", exa.getIn().getBody());
+ Exchange exv = mockv.getExchanges().get(0);
+ assertEquals(A.class, exv.getIn().getBody().getClass());
+ assertEquals(A.class, answer.getClass());
+ }
+
+ public static class MyTypeConverters implements TypeConverters {
+ @Converter
+ public A toA(String in) {
+ return new A();
+ }
+ }
+
+ public static class A { }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/test/java/org/apache/camel/impl/validator/ValidatorRouteTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/impl/validator/ValidatorRouteTest.java b/camel-core/src/test/java/org/apache/camel/impl/validator/ValidatorRouteTest.java
new file mode 100644
index 0000000..3d3f7f1
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/impl/validator/ValidatorRouteTest.java
@@ -0,0 +1,187 @@
+/**
+ * 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 java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.util.Map;
+
+import org.apache.camel.AsyncCallback;
+import org.apache.camel.Consumer;
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Converter;
+import org.apache.camel.Endpoint;
+import org.apache.camel.Exchange;
+import org.apache.camel.ExchangePattern;
+import org.apache.camel.Message;
+import org.apache.camel.Processor;
+import org.apache.camel.Producer;
+import org.apache.camel.TypeConverters;
+import org.apache.camel.ValidationException;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.impl.DefaultAsyncProducer;
+import org.apache.camel.impl.DefaultComponent;
+import org.apache.camel.impl.DefaultEndpoint;
+import org.apache.camel.impl.DefaultExchange;
+import org.apache.camel.model.DataFormatDefinition;
+import org.apache.camel.spi.DataFormat;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.RouteContext;
+import org.apache.camel.spi.Transformer;
+import org.apache.camel.spi.Validator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A ValidatorRouteTest demonstrates contract based declarative validation via Java DSL.
+ */
+public class ValidatorRouteTest extends ContextTestSupport {
+
+ protected static final Logger LOG = LoggerFactory.getLogger(ValidatorRouteTest.class);
+ private static final String VALIDATOR_INVOKED = "validator-invoked";
+
+ public void testPredicateValidator() throws Exception {
+ Exchange exchange = new DefaultExchange(context, ExchangePattern.InOut);
+ exchange.getIn().setBody("{name:XOrder}");
+ Exchange answerEx = template.send("direct:predicate", exchange);
+ if (answerEx.getException() != null) {
+ throw answerEx.getException();
+ }
+ assertEquals("{name:XOrderResponse}", answerEx.getOut().getBody(String.class));
+ }
+
+ public void testEndpointValidator() throws Exception {
+ Exchange exchange = new DefaultExchange(context, ExchangePattern.InOut);
+ exchange.getIn().setBody("<XOrder/>");
+ Exchange answerEx = template.send("direct:endpoint", exchange);
+ if (answerEx.getException() != null) {
+ throw answerEx.getException();
+ }
+ assertEquals("<XOrderResponse/>", answerEx.getOut().getBody(String.class));
+ assertEquals(MyXmlEndpoint.class, answerEx.getProperty(VALIDATOR_INVOKED));
+ }
+
+ public void testCustomValidator() throws Exception {
+ Exchange exchange = new DefaultExchange(context, ExchangePattern.InOut);
+ exchange.getIn().setBody("name=XOrder");
+ Exchange answerEx = template.send("direct:custom", exchange);
+ if (answerEx.getException() != null) {
+ throw answerEx.getException();
+ }
+ assertEquals("name=XOrderResponse", answerEx.getOut().getBody(String.class));
+ assertEquals(OtherXOrderResponseValidator.class, answerEx.getProperty(VALIDATOR_INVOKED));
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+
+ validator()
+ .type("json")
+ .withExpression(bodyAs(String.class).contains("{name:XOrder}"));
+ from("direct:predicate")
+ .inputType("json:JsonXOrder", true)
+ .outputType("json:JsonXOrderResponse")
+ .setBody(simple("{name:XOrderResponse}"))
+ .setProperty(Exchange.OUTPUT_TYPE, constant("json:JsonXOrderResponse"));
+
+ context.addComponent("myxml", new MyXmlComponent());
+ validator()
+ .type("xml:XmlXOrderResponse")
+ .withUri("myxml:endpoint");
+ from("direct:endpoint")
+ .inputType("xml:XmlXOrder")
+ .outputType("xml:XmlXOrderResponse", true)
+ .validate(exchangeProperty(VALIDATOR_INVOKED).isNull())
+ .setBody(simple("<XOrderResponse/>"))
+ .setProperty(Exchange.OUTPUT_TYPE, constant("xml:XmlXOrderResponse"));
+
+ validator()
+ .type("other:OtherXOrder")
+ .withJava(OtherXOrderValidator.class);
+ validator()
+ .type("other:OtherXOrderResponse")
+ .withJava(OtherXOrderResponseValidator.class);
+ from("direct:custom")
+ .inputType("other:OtherXOrder", true)
+ .outputType("other:OtherXOrderResponse", true)
+ .validate(exchangeProperty(VALIDATOR_INVOKED).isEqualTo(OtherXOrderValidator.class))
+ .setBody(simple("name=XOrderResponse"))
+ .setProperty(Exchange.OUTPUT_TYPE, constant("other:OtherXOrderResponse"));
+ }
+ };
+ }
+
+ public static class MyXmlComponent extends DefaultComponent {
+ @Override
+ protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
+ return new MyXmlEndpoint();
+ }
+
+ }
+
+ public static class MyXmlEndpoint extends DefaultEndpoint {
+ @Override
+ public Producer createProducer() throws Exception {
+ return new DefaultAsyncProducer(this) {
+ @Override
+ public boolean process(Exchange exchange, AsyncCallback callback) {
+ exchange.setProperty(VALIDATOR_INVOKED, MyXmlEndpoint.class);
+ assertEquals("<XOrderResponse/>", exchange.getIn().getBody());
+ callback.done(true);
+ return true;
+ }
+ };
+ }
+ @Override
+ public Consumer createConsumer(Processor processor) throws Exception {
+ return null;
+ }
+ @Override
+ public boolean isSingleton() {
+ return false;
+ }
+ @Override
+ protected String createEndpointUri() {
+ return "myxml:endpoint";
+ }
+ }
+
+ public static class OtherXOrderValidator extends Validator {
+ @Override
+ public void validate(Message message, DataType type) throws ValidationException {
+ message.getExchange().setProperty(VALIDATOR_INVOKED, OtherXOrderValidator.class);
+ assertEquals("name=XOrder", message.getBody());
+ LOG.info("Java validation: other XOrder");
+ }
+ }
+
+ public static class OtherXOrderResponseValidator extends Validator {
+ @Override
+ public void validate(Message message, DataType type) throws ValidationException {
+ message.getExchange().setProperty(VALIDATOR_INVOKED, OtherXOrderResponseValidator.class);
+ assertEquals("name=XOrderResponse", message.getBody());
+ LOG.info("Java validation: other XOrderResponse");
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/test/java/org/apache/camel/management/ManagedNonManagedServiceTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/management/ManagedNonManagedServiceTest.java b/camel-core/src/test/java/org/apache/camel/management/ManagedNonManagedServiceTest.java
index c3fcaad..b24957b 100644
--- a/camel-core/src/test/java/org/apache/camel/management/ManagedNonManagedServiceTest.java
+++ b/camel-core/src/test/java/org/apache/camel/management/ManagedNonManagedServiceTest.java
@@ -48,7 +48,7 @@ public class ManagedNonManagedServiceTest extends ManagementTestSupport {
MBeanServer mbeanServer = getMBeanServer();
Set<ObjectName> set = mbeanServer.queryNames(new ObjectName("*:type=services,*"), null);
- assertEquals(10, set.size());
+ assertEquals(11, set.size());
}
public void testNonManagedService() throws Exception {
@@ -69,7 +69,7 @@ public class ManagedNonManagedServiceTest extends ManagementTestSupport {
MBeanServer mbeanServer = getMBeanServer();
Set<ObjectName> set = mbeanServer.queryNames(new ObjectName("*:type=services,*"), null);
- assertEquals(9, set.size());
+ assertEquals(10, set.size());
}
@Override
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/test/java/org/apache/camel/management/ManagedProducerRouteAddRemoveRegisterAlwaysTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/management/ManagedProducerRouteAddRemoveRegisterAlwaysTest.java b/camel-core/src/test/java/org/apache/camel/management/ManagedProducerRouteAddRemoveRegisterAlwaysTest.java
index 55bd69f..b2b58e5 100644
--- a/camel-core/src/test/java/org/apache/camel/management/ManagedProducerRouteAddRemoveRegisterAlwaysTest.java
+++ b/camel-core/src/test/java/org/apache/camel/management/ManagedProducerRouteAddRemoveRegisterAlwaysTest.java
@@ -29,7 +29,7 @@ import org.apache.camel.component.mock.MockEndpoint;
*/
public class ManagedProducerRouteAddRemoveRegisterAlwaysTest extends ManagementTestSupport {
- private int services = 9;
+ private int services = 10;
@Override
protected CamelContext createCamelContext() throws Exception {
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/test/java/org/apache/camel/management/ManagedRouteAddRemoveTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/management/ManagedRouteAddRemoveTest.java b/camel-core/src/test/java/org/apache/camel/management/ManagedRouteAddRemoveTest.java
index f00528f..f4804a6 100644
--- a/camel-core/src/test/java/org/apache/camel/management/ManagedRouteAddRemoveTest.java
+++ b/camel-core/src/test/java/org/apache/camel/management/ManagedRouteAddRemoveTest.java
@@ -33,7 +33,7 @@ import org.apache.camel.component.mock.MockEndpoint;
*/
public class ManagedRouteAddRemoveTest extends ManagementTestSupport {
- private int services = 9;
+ private int services = 10;
@Override
protected RouteBuilder createRouteBuilder() throws Exception {
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/test/java/org/apache/camel/management/ManagedTransformerRegistryTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/management/ManagedTransformerRegistryTest.java b/camel-core/src/test/java/org/apache/camel/management/ManagedTransformerRegistryTest.java
index 96918a6..e26d3c8 100644
--- a/camel-core/src/test/java/org/apache/camel/management/ManagedTransformerRegistryTest.java
+++ b/camel-core/src/test/java/org/apache/camel/management/ManagedTransformerRegistryTest.java
@@ -33,9 +33,6 @@ import org.apache.camel.spi.Transformer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-/**
- * @version
- */
public class ManagedTransformerRegistryTest extends ManagementTestSupport {
private static final Logger LOG = LoggerFactory.getLogger(ManagedTransformerRegistryTest.class);
@@ -51,11 +48,6 @@ public class ManagedTransformerRegistryTest extends ManagementTestSupport {
assertMockEndpointsSatisfied();
- // resolve transformers explicitly as the route doesn't actually use them
- context.resolveTransformer(new DataType("xml:foo"), new DataType("json:bar"));
- context.resolveTransformer(new DataType(ManagedTransformerRegistryTest.class), new DataType("xml:test"));
- context.resolveTransformer("custom");
-
// get the stats for the route
MBeanServer mbeanServer = getMBeanServer();
Set<ObjectName> set = mbeanServer.queryNames(new ObjectName("*:type=services,*"), null);
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/camel-core/src/test/java/org/apache/camel/management/ManagedValidatorRegistryTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/management/ManagedValidatorRegistryTest.java b/camel-core/src/test/java/org/apache/camel/management/ManagedValidatorRegistryTest.java
new file mode 100644
index 0000000..7ceb111
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/management/ManagedValidatorRegistryTest.java
@@ -0,0 +1,134 @@
+/**
+ * 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;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.TabularData;
+
+import org.apache.camel.Message;
+import org.apache.camel.ValidationException;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.model.dataformat.StringDataFormat;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.Validator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ManagedValidatorRegistryTest extends ManagementTestSupport {
+ private static final Logger LOG = LoggerFactory.getLogger(ManagedValidatorRegistryTest.class);
+
+ public void testManageValidatorRegistry() throws Exception {
+ // JMX tests dont work well on AIX CI servers (hangs them)
+ if (isPlatform("aix")) {
+ return;
+ }
+
+ getMockEndpoint("mock:result").expectedMessageCount(1);
+
+ template.sendBody("direct:start", "Hello World");
+
+ assertMockEndpointsSatisfied();
+
+ // get the stats for the route
+ MBeanServer mbeanServer = getMBeanServer();
+ Set<ObjectName> set = mbeanServer.queryNames(new ObjectName("*:type=services,*"), null);
+ List<ObjectName> list = new ArrayList<ObjectName>(set);
+ ObjectName on = null;
+ for (ObjectName name : list) {
+ if (name.getCanonicalName().contains("DefaultValidatorRegistry")) {
+ on = name;
+ break;
+ }
+ }
+
+ assertNotNull("Should have found ValidatorRegistry", on);
+
+ Integer max = (Integer) mbeanServer.getAttribute(on, "MaximumCacheSize");
+ assertEquals(1000, max.intValue());
+
+ Integer current = (Integer) mbeanServer.getAttribute(on, "Size");
+ assertEquals(3, current.intValue());
+
+ current = (Integer) mbeanServer.getAttribute(on, "StaticSize");
+ assertEquals(0, current.intValue());
+
+ current = (Integer) mbeanServer.getAttribute(on, "DynamicSize");
+ assertEquals(3, current.intValue());
+
+ String source = (String) mbeanServer.getAttribute(on, "Source");
+ assertTrue(source.startsWith("ValidatorRegistry"));
+ assertTrue(source.endsWith("capacity: 1000"));
+
+
+ TabularData data = (TabularData) mbeanServer.invoke(on, "listValidators", null, null);
+ for (Object row : data.values()) {
+ CompositeData composite = (CompositeData)row;
+ String type = (String)composite.get("type");
+ String description = (String)composite.get("description");
+ boolean isStatic = (boolean)composite.get("static");
+ boolean isDynamic = (boolean)composite.get("dynamic");
+ LOG.info("[{}][{}][{}][{}]", type, isStatic, isDynamic, description);
+ if (description.startsWith("ProcessorValidator")) {
+ if (description.contains("direct://transformer")) {
+ assertEquals("xml:foo", type);
+ } else if (description.contains("validate(simple{${body}} is not null")) {
+ assertEquals("json:test", type);
+ } else {
+ fail("Unexpected validator:" + description);
+ }
+ } else if (description.startsWith("MyValidator")) {
+ assertEquals("custom", type);
+ } else {
+ fail("Unexpected validator:" + description);
+ }
+ }
+ assertEquals(3, data.size());
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ validator()
+ .type("xml:foo")
+ .withUri("direct:transformer");
+ validator()
+ .type("json:test")
+ .withExpression(body().isNotNull());
+ validator()
+ .type("custom")
+ .withJava(MyValidator.class);
+
+ from("direct:start").to("mock:result");
+ }
+ };
+ }
+
+ public static class MyValidator extends Validator {
+ @Override
+ public void validate(Message message, DataType type) throws ValidationException {
+ // empty
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java
----------------------------------------------------------------------
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java
index 717665a..31b54de 100644
--- a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java
@@ -64,6 +64,7 @@ import org.apache.camel.model.dataformat.DataFormatsDefinition;
import org.apache.camel.model.rest.RestConfigurationDefinition;
import org.apache.camel.model.rest.RestDefinition;
import org.apache.camel.model.transformer.TransformersDefinition;
+import org.apache.camel.model.validator.ValidatorsDefinition;
import org.apache.camel.spi.PackageScanFilter;
import org.apache.camel.spi.Registry;
import org.osgi.framework.BundleContext;
@@ -177,6 +178,8 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Blu
private DataFormatsDefinition dataFormats;
@XmlElement(name = "transformers")
private TransformersDefinition transformers;
+ @XmlElement(name = "validators")
+ private ValidatorsDefinition validators;
@XmlElement(name = "redeliveryPolicyProfile")
private List<CamelRedeliveryPolicyFactoryBean> redeliveryPolicies;
@XmlElement(name = "onException")
@@ -696,6 +699,14 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Blu
return transformers;
}
+ public void setValidators(ValidatorsDefinition validators) {
+ this.validators = validators;
+ }
+
+ public ValidatorsDefinition getValidators() {
+ return validators;
+ }
+
public List<OnExceptionDefinition> getOnExceptions() {
return onExceptions;
}
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/components/camel-cdi/src/main/java/org/apache/camel/cdi/xml/CamelContextFactoryBean.java
----------------------------------------------------------------------
diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/xml/CamelContextFactoryBean.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/xml/CamelContextFactoryBean.java
index d5336ed..d91605b 100644
--- a/components/camel-cdi/src/main/java/org/apache/camel/cdi/xml/CamelContextFactoryBean.java
+++ b/components/camel-cdi/src/main/java/org/apache/camel/cdi/xml/CamelContextFactoryBean.java
@@ -64,6 +64,7 @@ import org.apache.camel.model.dataformat.DataFormatsDefinition;
import org.apache.camel.model.rest.RestConfigurationDefinition;
import org.apache.camel.model.rest.RestDefinition;
import org.apache.camel.model.transformer.TransformersDefinition;
+import org.apache.camel.model.validator.ValidatorsDefinition;
import org.apache.camel.spi.PackageScanFilter;
@XmlRootElement(name = "camelContext")
@@ -208,6 +209,9 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Def
@XmlElement(name = "transformers")
private TransformersDefinition transformers;
+ @XmlElement(name = "validators")
+ private ValidatorsDefinition validators;
+
@XmlElement(name = "redeliveryPolicyProfile")
private List<RedeliveryPolicyFactoryBean> redeliveryPolicies;
@@ -702,6 +706,14 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Def
this.transformers = transformers;
}
+ public ValidatorsDefinition getValidators() {
+ return validators;
+ }
+
+ public void setValidators(ValidatorsDefinition validators) {
+ this.validators = validators;
+ }
+
public List<OnExceptionDefinition> getOnExceptions() {
return onExceptions;
}
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
----------------------------------------------------------------------
diff --git a/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java b/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
index 0c2c8b9..1b89a39 100644
--- a/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
+++ b/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
@@ -75,6 +75,7 @@ import org.apache.camel.model.rest.RestConfigurationDefinition;
import org.apache.camel.model.rest.RestContainer;
import org.apache.camel.model.rest.RestDefinition;
import org.apache.camel.model.transformer.TransformersDefinition;
+import org.apache.camel.model.validator.ValidatorsDefinition;
import org.apache.camel.processor.interceptor.BacklogTracer;
import org.apache.camel.processor.interceptor.HandleFault;
import org.apache.camel.processor.interceptor.TraceFormatter;
@@ -776,6 +777,8 @@ public abstract class AbstractCamelContextFactoryBean<T extends ModelCamelContex
public abstract TransformersDefinition getTransformers();
+ public abstract ValidatorsDefinition getValidators();
+
public abstract List<OnExceptionDefinition> getOnExceptions();
public abstract List<OnCompletionDefinition> getOnCompletions();
@@ -858,7 +861,10 @@ public abstract class AbstractCamelContextFactoryBean<T extends ModelCamelContex
ctx.setDataFormats(getDataFormats().asMap());
}
if (getTransformers() != null) {
- ctx.setTransformers(getTransformers().getTransforms());
+ ctx.setTransformers(getTransformers().getTransformers());
+ }
+ if (getValidators() != null) {
+ ctx.setValidators(getValidators().getValidators());
}
if (getTypeConverterStatisticsEnabled() != null) {
ctx.setTypeConverterStatisticsEnabled(getTypeConverterStatisticsEnabled());
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/components/camel-spring/src/main/java/org/apache/camel/spring/CamelContextFactoryBean.java
----------------------------------------------------------------------
diff --git a/components/camel-spring/src/main/java/org/apache/camel/spring/CamelContextFactoryBean.java b/components/camel-spring/src/main/java/org/apache/camel/spring/CamelContextFactoryBean.java
index 6c2f2d0..e0a3f07 100644
--- a/components/camel-spring/src/main/java/org/apache/camel/spring/CamelContextFactoryBean.java
+++ b/components/camel-spring/src/main/java/org/apache/camel/spring/CamelContextFactoryBean.java
@@ -63,6 +63,7 @@ import org.apache.camel.model.dataformat.DataFormatsDefinition;
import org.apache.camel.model.rest.RestConfigurationDefinition;
import org.apache.camel.model.rest.RestDefinition;
import org.apache.camel.model.transformer.TransformersDefinition;
+import org.apache.camel.model.validator.ValidatorsDefinition;
import org.apache.camel.spi.Metadata;
import org.apache.camel.spi.PackageScanFilter;
import org.apache.camel.spi.Registry;
@@ -186,6 +187,8 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Spr
private DataFormatsDefinition dataFormats;
@XmlElement(name = "transformers")
private TransformersDefinition transformers;
+ @XmlElement(name = "validators")
+ private ValidatorsDefinition validators;
@XmlElement(name = "redeliveryPolicyProfile")
private List<CamelRedeliveryPolicyFactoryBean> redeliveryPolicies;
@XmlElement(name = "onException")
@@ -908,6 +911,17 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Spr
}
/**
+ * Configuration of validators.
+ */
+ public void setValidators(ValidatorsDefinition validators) {
+ this.validators = validators;
+ }
+
+ public ValidatorsDefinition getValidators() {
+ return validators;
+ }
+
+ /**
* Configuration of redelivery settings.
*/
public void setRedeliveryPolicies(List<CamelRedeliveryPolicyFactoryBean> redeliveryPolicies) {
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/components/camel-spring/src/main/java/org/apache/camel/spring/handler/CamelNamespaceHandler.java
----------------------------------------------------------------------
diff --git a/components/camel-spring/src/main/java/org/apache/camel/spring/handler/CamelNamespaceHandler.java b/components/camel-spring/src/main/java/org/apache/camel/spring/handler/CamelNamespaceHandler.java
index e0ef322..04737cf 100644
--- a/components/camel-spring/src/main/java/org/apache/camel/spring/handler/CamelNamespaceHandler.java
+++ b/components/camel-spring/src/main/java/org/apache/camel/spring/handler/CamelNamespaceHandler.java
@@ -384,6 +384,7 @@ public class CamelNamespaceHandler extends NamespaceHandlerSupport {
builder.addPropertyValue("interceptSendToEndpoints", factoryBean.getInterceptSendToEndpoints());
builder.addPropertyValue("dataFormats", factoryBean.getDataFormats());
builder.addPropertyValue("transformers", factoryBean.getTransformers());
+ builder.addPropertyValue("validators", factoryBean.getValidators());
builder.addPropertyValue("onCompletions", factoryBean.getOnCompletions());
builder.addPropertyValue("onExceptions", factoryBean.getOnExceptions());
builder.addPropertyValue("builderRefs", factoryBean.getBuilderRefs());
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/components/camel-spring/src/test/java/org/apache/camel/spring/impl/validator/SpringValidatorRouteTest.java
----------------------------------------------------------------------
diff --git a/components/camel-spring/src/test/java/org/apache/camel/spring/impl/validator/SpringValidatorRouteTest.java b/components/camel-spring/src/test/java/org/apache/camel/spring/impl/validator/SpringValidatorRouteTest.java
new file mode 100644
index 0000000..56cb106
--- /dev/null
+++ b/components/camel-spring/src/test/java/org/apache/camel/spring/impl/validator/SpringValidatorRouteTest.java
@@ -0,0 +1,35 @@
+/**
+ * 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.spring.impl.validator;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.impl.validator.ValidatorRouteTest;
+
+import static org.apache.camel.spring.processor.SpringTestHelper.createSpringCamelContext;
+
+/**
+ * A SpringValidatorRouteTest demonstrates contract based declarative validation via Spring DSL.
+ */
+public class SpringValidatorRouteTest extends ValidatorRouteTest {
+
+ protected CamelContext createCamelContext() throws Exception {
+ return createSpringCamelContext(this, "org/apache/camel/spring/impl/validator/SpringValidatorRouteTest.xml");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/f9946b2e/components/camel-spring/src/test/resources/org/apache/camel/spring/impl/validator/SpringValidatorRouteTest.xml
----------------------------------------------------------------------
diff --git a/components/camel-spring/src/test/resources/org/apache/camel/spring/impl/validator/SpringValidatorRouteTest.xml b/components/camel-spring/src/test/resources/org/apache/camel/spring/impl/validator/SpringValidatorRouteTest.xml
new file mode 100644
index 0000000..4e6c090
--- /dev/null
+++ b/components/camel-spring/src/test/resources/org/apache/camel/spring/impl/validator/SpringValidatorRouteTest.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
+ ">
+
+ <bean id="myxml" class="org.apache.camel.impl.validator.ValidatorRouteTest.MyXmlComponent"/>
+
+ <camelContext xmlns="http://camel.apache.org/schema/spring">
+
+ <validators>
+ <predicateValidator type="json"><simple>${body} contains '{name:XOrder'</simple></predicateValidator>
+ <endpointValidator type="xml:XmlXOrderResponse" uri="myxml:endpoint"/>
+ <customValidator type="other:OtherXOrder" className="org.apache.camel.impl.validator.ValidatorRouteTest$OtherXOrderValidator"/>
+ <customValidator type="other:OtherXOrderResponse" className="org.apache.camel.impl.validator.ValidatorRouteTest$OtherXOrderResponseValidator"/>
+ </validators>
+
+ <route>
+ <from uri="direct:predicate"/>
+ <inputType urn="json:JsonXOrder" validate="true"/>
+ <outputType urn="json:JsonXOrderResponse"/>
+ <setBody><constant>{name:XOrderResponse}</constant></setBody>
+ <setProperty propertyName="CamelOutputType"><constant>json:JsonXOrderResponse</constant></setProperty>
+ </route>
+
+ <route>
+ <from uri="direct:endpoint"/>
+ <inputType urn="xml:XmlXOrder"/>
+ <outputType urn="xml:XmlXOrderResponse" validate="true"/>
+ <validate>
+ <simple>${exchangeProperty.validator-invoked} == null</simple>
+ </validate>
+ <setBody><constant><XOrderResponse/></constant></setBody>
+ <setProperty propertyName="CamelOutputType"><constant>xml:XmlXOrderResponse</constant></setProperty>
+ </route>
+
+ <route>
+ <from uri="direct:custom"/>
+ <inputType urn="other:OtherXOrder" validate="true"/>
+ <outputType urn="other:OtherXOrderResponse" validate="true"/>
+ <validate>
+ <simple>${exchangeProperty.validator-invoked} == 'org.apache.camel.impl.validator.ValidatorRouteTest$OtherXOrderValidator'</simple>
+ </validate>
+ <setBody><constant>name=XOrderResponse</constant></setBody>
+ <setProperty propertyName="CamelOutputType"><constant>other:OtherXOrderResponse</constant></setProperty>
+ </route>
+
+ </camelContext>
+
+</beans>
[4/4] camel git commit: CAMEL-10538 Add declarative validator
according to input/output type
Posted by da...@apache.org.
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;
}
}