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 2018/08/06 18:08:45 UTC

[camel] 02/02: CAMEL-12565: Added unit tests. Fixed a little issue in validator to ensure exception is set on exchange to allow advice to keep executing the next ones.

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

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

commit cbcf30d19e30d95d3ce54a6d13805f12f80bc7f4
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Mon Aug 6 20:07:35 2018 +0200

    CAMEL-12565: Added unit tests. Fixed a little issue in validator to ensure exception is set on exchange to allow advice to keep executing the next ones.
---
 .../org/apache/camel/model/RouteDefinition.java    |   2 +-
 .../org/apache/camel/processor/ContractAdvice.java |  55 ++++++-----
 .../validator/BeanValidatorInputValidateTest.java  |  97 +++++++++++++++++++
 .../validator/BeanValidatorOutputValidateTest.java | 104 +++++++++++++++++++++
 4 files changed, 235 insertions(+), 23 deletions(-)

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 ddb3fb9..985afe7 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
@@ -756,7 +756,7 @@ public class RouteDefinition extends ProcessorDefinition<RouteDefinition> {
 
     /**
      * Declare the expected data type of the output message with content validation enabled.
-     * If the actual message type is different at runtime, camel look for a required
+     * If the actual message type is different at runtime, Camel look for a required
      * {@link Transformer} and apply if exists, and then applies {@link Validator} as well.
      * The type name consists of two parts, 'scheme' and 'name' connected with ':'. For Java type 'name'
      * is a fully qualified class name. For example {@code java:java.lang.String}, {@code json:ABCOrder}.
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 f2e792a..521ea12 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
@@ -61,19 +61,24 @@ public class ContractAdvice implements CamelInternalProcessorAdvice {
         if (!(exchange.getIn() instanceof DataTypeAware)) {
             return null;
         }
-        DataType to = contract.getInputType();
-        if (to != null) {
-            DataTypeAware target = (DataTypeAware)exchange.getIn();
-            DataType from = target.getDataType();
-            if (!to.equals(from)) {
-                LOG.debug("Looking for transformer for INPUT: from='{}', to='{}'", from, to);
-                doTransform(exchange.getIn(), from, to);
-                target.setDataType(to);
-            }
-            if (contract.isValidateInput()) {
-                doValidate(exchange.getIn(), to);
+        try {
+            DataType to = contract.getInputType();
+            if (to != null) {
+                DataTypeAware target = (DataTypeAware) exchange.getIn();
+                DataType from = target.getDataType();
+                if (!to.equals(from)) {
+                    LOG.debug("Looking for transformer for INPUT: from='{}', to='{}'", from, to);
+                    doTransform(exchange.getIn(), from, to);
+                    target.setDataType(to);
+                }
+                if (contract.isValidateInput()) {
+                    doValidate(exchange.getIn(), to);
+                }
             }
+        } catch (Exception e) {
+            exchange.setException(e);
         }
+
         return null;
     }
     
@@ -88,18 +93,22 @@ public class ContractAdvice implements CamelInternalProcessorAdvice {
         if (!(target instanceof DataTypeAware)) {
             return;
         }
-        DataType to = contract.getOutputType();
-        if (to != null) {
-            DataTypeAware typeAwareTarget = (DataTypeAware)target;
-            DataType from = typeAwareTarget.getDataType();
-            if (!to.equals(from)) {
-                LOG.debug("Looking for transformer for OUTPUT: from='{}', to='{}'", from, to);
-                doTransform(target, from, to);
-                typeAwareTarget.setDataType(to);
-            }
-            if (contract.isValidateOutput()) {
-                doValidate(target, to);
+        try {
+            DataType to = contract.getOutputType();
+            if (to != null) {
+                DataTypeAware typeAwareTarget = (DataTypeAware)target;
+                DataType from = typeAwareTarget.getDataType();
+                if (!to.equals(from)) {
+                    LOG.debug("Looking for transformer for OUTPUT: from='{}', to='{}'", from, to);
+                    doTransform(target, from, to);
+                    typeAwareTarget.setDataType(to);
+                }
+                if (contract.isValidateOutput()) {
+                    doValidate(target, to);
+                }
             }
+        } catch (Exception e) {
+            exchange.setException(e);
         }
     }
     
@@ -154,6 +163,7 @@ public class ContractAdvice implements CamelInternalProcessorAdvice {
         }
         return false;
     }
+
     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);
@@ -186,4 +196,5 @@ public class ContractAdvice implements CamelInternalProcessorAdvice {
             throw new ValidationException(message.getExchange(), String.format("No Validator found for '%s'", type));
         }
     }
+
 }
\ No newline at end of file
diff --git a/camel-core/src/test/java/org/apache/camel/impl/validator/BeanValidatorInputValidateTest.java b/camel-core/src/test/java/org/apache/camel/impl/validator/BeanValidatorInputValidateTest.java
new file mode 100644
index 0000000..886fb99
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/impl/validator/BeanValidatorInputValidateTest.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.impl.validator;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Message;
+import org.apache.camel.ValidationException;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.impl.JndiRegistry;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.Validator;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class BeanValidatorInputValidateTest extends ContextTestSupport {
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                validator()
+                    .type("toValidate")
+                    .withBean("testValidator");
+
+                onException(ValidationException.class)
+                    .handled(true)
+                    .log("Invalid validation: ${exception.message}")
+                    .to("mock:invalid");
+
+                from("direct:in")
+                    .inputTypeWithValidate("toValidate")
+                    .to("mock:out");
+            }
+        };
+    }
+
+    public static class TestValidator extends Validator {
+        private static final Logger LOG = LoggerFactory.getLogger(TestValidator.class);
+
+        @Override
+        public void validate(Message message, DataType type) throws ValidationException {
+            Object body = message.getBody();
+            LOG.info("Validating : [{}]", body);
+            if (body instanceof String && body.equals("valid")) {
+                LOG.info("OK");
+            } else {
+                throw new ValidationException(message.getExchange(), "Wrong content");
+            }
+        }
+    }
+
+
+    @Override
+    protected JndiRegistry createRegistry() throws Exception {
+        JndiRegistry registry = super.createRegistry();
+
+        registry.bind("testValidator", new TestValidator());
+
+        return registry;
+    }
+
+    @Test
+    public void testValid() throws InterruptedException {
+        getMockEndpoint("mock:out").expectedMessageCount(1);
+        getMockEndpoint("mock:invalid").expectedMessageCount(0);
+
+        template.sendBody("direct:in", "valid");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testInvalid() throws InterruptedException {
+        getMockEndpoint("mock:out").expectedMessageCount(0);
+        getMockEndpoint("mock:invalid").expectedMessageCount(1);
+
+        template.sendBody("direct:in", "wrong");
+
+        assertMockEndpointsSatisfied();
+    }
+}
diff --git a/camel-core/src/test/java/org/apache/camel/impl/validator/BeanValidatorOutputValidateTest.java b/camel-core/src/test/java/org/apache/camel/impl/validator/BeanValidatorOutputValidateTest.java
new file mode 100644
index 0000000..ac5ed49
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/impl/validator/BeanValidatorOutputValidateTest.java
@@ -0,0 +1,104 @@
+/**
+ * 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.CamelExecutionException;
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Message;
+import org.apache.camel.ValidationException;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.impl.JndiRegistry;
+import org.apache.camel.spi.DataType;
+import org.apache.camel.spi.Validator;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class BeanValidatorOutputValidateTest extends ContextTestSupport {
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                validator()
+                    .type("toValidate")
+                    .withBean("testValidator");
+
+                onException(ValidationException.class)
+                    .handled(true)
+                    .log("Invalid validation: ${exception.message}")
+                    .to("mock:invalid");
+
+                from("direct:in")
+                    .outputTypeWithValidate("toValidate")
+                    .to("mock:out");
+            }
+        };
+    }
+
+    public static class TestValidator extends Validator {
+        private static final Logger LOG = LoggerFactory.getLogger(TestValidator.class);
+
+        @Override
+        public void validate(Message message, DataType type) throws ValidationException {
+            Object body = message.getBody();
+            LOG.info("Validating : [{}]", body);
+            if (body instanceof String && body.equals("valid")) {
+                LOG.info("OK");
+            } else {
+                throw new ValidationException(message.getExchange(), "Wrong content");
+            }
+        }
+    }
+
+
+    @Override
+    protected JndiRegistry createRegistry() throws Exception {
+        JndiRegistry registry = super.createRegistry();
+
+        registry.bind("testValidator", new TestValidator());
+
+        return registry;
+    }
+
+    @Test
+    public void testValid() throws InterruptedException {
+        getMockEndpoint("mock:out").expectedMessageCount(1);
+        getMockEndpoint("mock:invalid").expectedMessageCount(0);
+
+        template.sendBody("direct:in", "valid");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testInvalid() throws InterruptedException {
+        getMockEndpoint("mock:out").expectedMessageCount(1);
+        getMockEndpoint("mock:invalid").expectedMessageCount(0);
+
+        try {
+            template.sendBody("direct:in", "wrong");
+            fail("Should have thrown exception");
+        } catch (CamelExecutionException e) {
+            assertIsInstanceOf(ValidationException.class, e.getCause());
+            assertTrue(e.getCause().getMessage().startsWith("Wrong content"));
+        }
+
+        assertMockEndpointsSatisfied();
+    }
+}