camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From lburgazz...@apache.org
Subject [2/3] camel git commit: CAMEL-10575: snakeyaml: add an option to filter classes the yaml parser can construct
Date Fri, 09 Dec 2016 14:54:36 GMT
CAMEL-10575: snakeyaml: add an option to filter classes the yaml parser can construct

(cherry picked from commit 20e26226107f3133c87d0f5c845e02f824823f69)


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

Branch: refs/heads/camel-2.18.x
Commit: 2f19ce59cc4d89f21455f47604915fab6a22233b
Parents: 6c2db21
Author: lburgazzoli <lburgazzoli@gmail.com>
Authored: Thu Dec 8 16:28:14 2016 +0100
Committer: lburgazzoli <lburgazzoli@gmail.com>
Committed: Fri Dec 9 14:19:52 2016 +0100

----------------------------------------------------------------------
 .../camel/model/dataformat/YAMLDataFormat.java  |  51 +++++++
 .../dataformat/YAMLTypeFilterDefinition.java    |  47 ++++++
 .../model/dataformat/YAMLTypeFilterType.java    |  26 ++++
 components/camel-snakeyaml/pom.xml              |   6 +-
 .../main/docs/yaml-snakeyaml-dataformat.adoc    | 145 ++++++++++---------
 .../snakeyaml/SnakeYAMLDataFormat.java          | 145 +++++++++++++++----
 .../camel/component/snakeyaml/TypeFilter.java   |  23 +++
 .../camel/component/snakeyaml/TypeFilters.java  | 119 +++++++++++++++
 .../SnakeYAMLBlueprintTypeFilterTest.java       |  48 ++++++
 .../snakeyaml/SnakeYAMLMarshalTest.java         | 100 -------------
 .../snakeyaml/SnakeYAMLMarshalTestHelper.java   |  84 -----------
 .../snakeyaml/SnakeYAMLSpringMarshalTest.java   |  73 ----------
 .../snakeyaml/SnakeYAMLSpringTest.java          |  73 ++++++++++
 .../SnakeYAMLSpringTypeFilterTest.java          |  51 +++++++
 .../component/snakeyaml/SnakeYAMLTest.java      | 100 +++++++++++++
 .../snakeyaml/SnakeYAMLTestHelper.java          |  90 ++++++++++++
 .../snakeyaml/SnakeYAMLTypeFilterHelper.java    | 117 +++++++++++++++
 .../snakeyaml/SnakeYAMLTypeFilterTest.java      |  85 +++++++++++
 .../snakeyaml/SnakeYAMLUnmarshalTypeTest.java   |  46 ++++++
 .../component/snakeyaml/model/RexPojo.java      |  63 ++++++++
 .../component/snakeyaml/model/TestPojo.java     |  17 ++-
 .../component/snakeyaml/model/UnsafePojo.java   |  63 ++++++++
 .../OSGI-INF/blueprint/blueprint-typefilter.xml |  71 +++++++++
 .../snakeyaml/SnakeYAMLSpringMarshalTest.xml    |  76 ----------
 .../component/snakeyaml/SnakeYAMLSpringTest.xml |  76 ++++++++++
 .../snakeyaml/SnakeYAMLSpringTypeFilterTest.xml |  60 ++++++++
 26 files changed, 1425 insertions(+), 430 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/2f19ce59/camel-core/src/main/java/org/apache/camel/model/dataformat/YAMLDataFormat.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/dataformat/YAMLDataFormat.java b/camel-core/src/main/java/org/apache/camel/model/dataformat/YAMLDataFormat.java
index 9b06c1c..d97f9cc 100644
--- a/camel-core/src/main/java/org/apache/camel/model/dataformat/YAMLDataFormat.java
+++ b/camel-core/src/main/java/org/apache/camel/model/dataformat/YAMLDataFormat.java
@@ -16,9 +16,12 @@
  */
 package org.apache.camel.model.dataformat;
 
+import java.util.ArrayList;
+import java.util.List;
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlTransient;
 
@@ -58,6 +61,10 @@ public class YAMLDataFormat extends DataFormatDefinition {
     private Boolean useApplicationContextClassLoader = true;
     @XmlAttribute @Metadata(defaultValue = "false")
     private Boolean prettyFlow = false;
+    @XmlAttribute @Metadata(defaultValue = "false")
+    private Boolean allowAnyType = false;
+    @XmlElement(name = "typeFilter")
+    private List<YAMLTypeFilterDefinition> typeFilters;
 
     public YAMLDataFormat() {
         this(YAMLLibrary.SnakeYAML);
@@ -188,6 +195,28 @@ public class YAMLDataFormat extends DataFormatDefinition {
         this.prettyFlow = prettyFlow;
     }
 
+    public boolean isAllowAnyType() {
+        return allowAnyType;
+    }
+
+    /**
+     * Allow any class to be un-marshaled
+     */
+    public void setAllowAnyType(boolean allowAnyType) {
+        this.allowAnyType = allowAnyType;
+    }
+
+    public List<YAMLTypeFilterDefinition> getTypeFilters() {
+        return typeFilters;
+    }
+
+    /**
+     * Set the types SnakeYAML is allowed to un-marshall
+     */
+    public void setTypeFilters(List<YAMLTypeFilterDefinition> typeFilters) {
+        this.typeFilters = typeFilters;
+    }
+
     @Override
     protected DataFormat createDataFormat(RouteContext routeContext) {
         if (library == YAMLLibrary.SnakeYAML) {
@@ -218,6 +247,27 @@ public class YAMLDataFormat extends DataFormatDefinition {
         setProperty(dataFormat, camelContext, "classLoader", classLoader);
         setProperty(dataFormat, camelContext, "useApplicationContextClassLoader", useApplicationContextClassLoader);
         setProperty(dataFormat, camelContext, "prettyFlow", prettyFlow);
+        setProperty(dataFormat, camelContext, "allowAnyType", allowAnyType);
+
+        if (typeFilters != null && !typeFilters.isEmpty()) {
+            List<String> typeFilterDefinitions = new ArrayList<>(typeFilters.size());
+            for (YAMLTypeFilterDefinition definition : typeFilters) {
+                String value = definition.getValue();
+
+                if (!value.startsWith("type") && !value.startsWith("regexp")) {
+                    YAMLTypeFilterType type = definition.getType();
+                    if (type == null) {
+                        type = YAMLTypeFilterType.type;
+                    }
+
+                    value = type.name() + ":" + value;
+                }
+
+                typeFilterDefinitions.add(value);
+            }
+
+            setProperty(dataFormat, camelContext, "typeFilterDefinitions", typeFilterDefinitions);
+        }
 
         setPropertyRef(dataFormat, camelContext, "constructor", constructor);
         setPropertyRef(dataFormat, camelContext, "representer", representer);
@@ -238,4 +288,5 @@ public class YAMLDataFormat extends DataFormatDefinition {
             setProperty(camelContext, dataFormat, propertyName, ref);
         }
     }
+
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/2f19ce59/camel-core/src/main/java/org/apache/camel/model/dataformat/YAMLTypeFilterDefinition.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/dataformat/YAMLTypeFilterDefinition.java b/camel-core/src/main/java/org/apache/camel/model/dataformat/YAMLTypeFilterDefinition.java
new file mode 100644
index 0000000..8e4babb
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/model/dataformat/YAMLTypeFilterDefinition.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.model.dataformat;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement(name = "typeFilter")
+@XmlAccessorType(XmlAccessType.FIELD)
+public final class YAMLTypeFilterDefinition {
+    @XmlAttribute
+    private String value;
+    @XmlAttribute
+    private YAMLTypeFilterType type;
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public YAMLTypeFilterType getType() {
+        return type;
+    }
+
+    public void setType(YAMLTypeFilterType type) {
+        this.type = type;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/2f19ce59/camel-core/src/main/java/org/apache/camel/model/dataformat/YAMLTypeFilterType.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/dataformat/YAMLTypeFilterType.java b/camel-core/src/main/java/org/apache/camel/model/dataformat/YAMLTypeFilterType.java
new file mode 100644
index 0000000..727b2d7
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/model/dataformat/YAMLTypeFilterType.java
@@ -0,0 +1,26 @@
+/**
+ * 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.dataformat;
+
+import javax.xml.bind.annotation.XmlEnum;
+
+@XmlEnum
+public enum YAMLTypeFilterType {
+    type,
+    regexp
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/2f19ce59/components/camel-snakeyaml/pom.xml
----------------------------------------------------------------------
diff --git a/components/camel-snakeyaml/pom.xml b/components/camel-snakeyaml/pom.xml
index 1132303..24761a7 100644
--- a/components/camel-snakeyaml/pom.xml
+++ b/components/camel-snakeyaml/pom.xml
@@ -45,7 +45,6 @@
             <artifactId>snakeyaml</artifactId>
             <version>${snakeyaml-version}</version>
         </dependency>
-
         <!-- testing -->
         <dependency>
             <groupId>org.apache.camel</groupId>
@@ -53,6 +52,11 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-test-blueprint</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.apache.logging.log4j</groupId>
             <artifactId>log4j-api</artifactId>
             <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/camel/blob/2f19ce59/components/camel-snakeyaml/src/main/docs/yaml-snakeyaml-dataformat.adoc
----------------------------------------------------------------------
diff --git a/components/camel-snakeyaml/src/main/docs/yaml-snakeyaml-dataformat.adoc b/components/camel-snakeyaml/src/main/docs/yaml-snakeyaml-dataformat.adoc
index 9cba881..702a875 100644
--- a/components/camel-snakeyaml/src/main/docs/yaml-snakeyaml-dataformat.adoc
+++ b/components/camel-snakeyaml/src/main/docs/yaml-snakeyaml-dataformat.adoc
@@ -14,34 +14,12 @@ Every library requires adding the special camel component (see
 "Dependency..." paragraphs further down). By default Camel uses the
 SnakeYAML library.
 
-[[YAMLDataFormat-UsingYAMLdataformatwiththeSnakeYAMLlibrary]]
-Using YAML data format with the SnakeYAML library
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-[source,java]
-------------------------------------------------------------
-// lets turn Object messages into yaml then send to MQSeries
-from("activemq:My.Queue")
-  .marshal().yaml()
-  .to("mqseries:Another.Queue");
-------------------------------------------------------------
-
-[source,java]
-------------------------------------------------------------
-// lets turn Object messages into yaml then send to MQSeries
-from("activemq:My.Queue")
-  .marshal().yaml(YAMLLibrary.SnakeYAML)
-  .to("mqseries:Another.Queue");
-------------------------------------------------------------
-
 [[YAML-Options]]
 YAML Options
 ^^^^^^^^^^^^
 
-
-
 // dataformat options: START
-The YAML SnakeYAML dataformat supports 8 options which are listed below.
+The YAML SnakeYAML dataformat supports 10 options which are listed below.
 
 
 
@@ -57,11 +35,48 @@ The YAML SnakeYAML dataformat supports 8 options which are listed below.
 | resolver |  | String | Resolver to detect implicit type
 | useApplicationContextClassLoader | true | Boolean | Use ApplicationContextClassLoader as custom ClassLoader
 | prettyFlow | false | Boolean | Force the emitter to produce a pretty YAML document when using the flow style.
+| allowAnyType | false | Boolean | Allow any class to be un-marshaled
+| typeFilter |  | List | Set the types SnakeYAML is allowed to un-marshall
 |=======================================================================
 {% endraw %}
 // dataformat options: END
 
+WARNING: SnakeYAML can load any class from YAML definition which may lead to security breach so by default, SnakeYAML DataForma restrict the object it can load to standard Java objects like List or Long. If you want to load custom POJOs you need to add theirs type to SnakeYAML DataFormat type filter list. If your source is trusted, you can set the property allowAnyType to true so SnakeYAML DataForma won't perform any filter on the types.
 
+[[YAMLDataFormat-UsingYAMLdataformatwiththeSnakeYAMLlibrary]]
+Using YAML data format with the SnakeYAML library
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- Turn Object messages into yaml then send to MQSeries
++
+[source,java]
+------------------------------------------------------------
+from("activemq:My.Queue")
+  .marshal().yaml()
+  .to("mqseries:Another.Queue");
+------------------------------------------------------------
++
+[source,java]
+------------------------------------------------------------
+from("activemq:My.Queue")
+  .marshal().yaml(YAMLLibrary.SnakeYAML)
+  .to("mqseries:Another.Queue");
+------------------------------------------------------------
+
+- Restrict classes to be loaded from YAML
++
+[source,java]
+------------------------------------------------------------
+// Creat a SnakeYAMLDataFormat instance
+SnakeYAMLDataFormat yaml = new SnakeYAMLDataFormat();
+
+// Restrict classes to be loaded from YAML
+yaml.addTypeFilters(TypeFilters.types(MyPojo.class, MyOtherPojo.class));
+
+from("activemq:My.Queue")
+  .unmarshal(yaml)
+  .to("mqseries:Another.Queue");
+------------------------------------------------------------
 
 [[YAMLDataFormat-UsingYAMLinSpringDSL]]
 Using YAML in Spring DSL
@@ -72,56 +87,50 @@ declare the data formats first. This is done in the *DataFormats* XML
 tag.
 
 [source,xml]
-----------------------------------------------------------------------------------------------------------------------------------
-        <dataFormats>
-            <!-- here we define a YAML data format with the id snak and that it should use the TestPojo as the class type when
-                 doing unmarshal. The unmarshalTypeName is optional, if not provided Camel will use a Object.class as the type -->
-            <yaml id="snake" library="SnakeYAML" unmarshalTypeName="org.apache.camel.component.yaml.model.TestPojo"/>
-        </dataFormats>
-----------------------------------------------------------------------------------------------------------------------------------
-
-And then you can refer to this id in the route:
+--------------------------------------------------------------------------------
+<dataFormats>
+  <!--
+    here we define a YAML data format with the id snake and that it should use
+    the TestPojo as the class type when doing unmarshal. The unmarshalTypeName
+    is optional
+  -->
+  <yaml
+    id="snake"
+    library="SnakeYAML"
+    unmarshalTypeName="org.apache.camel.component.yaml.model.TestPojo"/>
+
+  <!--
+    here we define a YAML data format with the id snake-safe which restricts the
+    classes to be loaded from YAML to TestPojo and those belonging to package
+    com.mycompany
+  -->
+  <yaml id="snake-safe">
+    <typeFilter value="org.apache.camel.component.yaml.model.TestPojo"/>
+    <typeFilter value="com.mycompany\..*" type="regexp"/>
+  </yaml>
+</dataFormats>
+--------------------------------------------------------------------------------
+
+And then you can refer to those ids in the route:
 
 [source,xml]
 -------------------------------------
-       <route>
-            <from uri="direct:back"/>
-            <unmarshal ref="snake"/>
-            <to uri="mock:reverse"/>
-        </route>
+  <route>
+    <from uri="direct:unmarshal"/>
+    <unmarshal>
+      <custom ref="snake"/>
+    </unmarshal>
+    <to uri="mock:unmarshal"/>
+  </route>
+  <route>
+    <from uri="direct:unmarshal-safe"/>
+    <unmarshal>
+      <custom ref="snake-safe"/>
+    </unmarshal>
+    <to uri="mock:unmarshal-safe"/>
+  </route>
 -------------------------------------
 
- 
-
-[[YAMLDataFormat-OptionsforSnakeYAMLDataFormat]]
-Options for SnakeYAML Data Format
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-[width="100%",cols="<25%,<25%,<25%,<25%",options="header",]
-|=======================================================================
-|Name |Type |Default |Description
-|unmarshalType |`Class` |`Object.class` |Class of the object to be created
-
-|classLoader |ClassLoader |null |The classloader to use to
-instantiate objects
-
-|constructor |String |null |A reference to an 
-org.yaml.snakeyaml.constructor.BaseConstructor instance in the registry
-
-|representer |String |null |A reference to an 
-org.yaml.snakeyaml.representer.Representer instance in the registry
-
-|dumperOptions |String |null |A reference to an 
-org.yaml.snakeyaml.DumperOptions instance in the registry
-
-|resolver |String |null |A reference to an 
-org.yaml.snakeyaml.resolver.Resolver instance in the registry
-
-|useApplicationContextClassLoader | Boolean |true  |To use CamelContext's ApplicationContextClassLoader if no custom class loader is set and
-ApplicationContextClassLoader is provided
-
-|prettyFlow | Boolean |false  |Force the emitter to produce a pretty YAML document when using the flow style
-|=======================================================================
 
 [[YAMLDataFormat-DependenciesforSnakeYAML]]
 Dependencies for SnakeYAML

http://git-wip-us.apache.org/repos/asf/camel/blob/2f19ce59/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/SnakeYAMLDataFormat.java
----------------------------------------------------------------------
diff --git a/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/SnakeYAMLDataFormat.java b/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/SnakeYAMLDataFormat.java
index 7e030bb..24fd0da 100644
--- a/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/SnakeYAMLDataFormat.java
+++ b/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/SnakeYAMLDataFormat.java
@@ -21,10 +21,14 @@ import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.lang.ref.WeakReference;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArrayList;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
@@ -38,18 +42,17 @@ import org.yaml.snakeyaml.Yaml;
 import org.yaml.snakeyaml.constructor.BaseConstructor;
 import org.yaml.snakeyaml.constructor.Constructor;
 import org.yaml.snakeyaml.constructor.CustomClassLoaderConstructor;
+import org.yaml.snakeyaml.constructor.SafeConstructor;
 import org.yaml.snakeyaml.nodes.Tag;
 import org.yaml.snakeyaml.representer.Representer;
 import org.yaml.snakeyaml.resolver.Resolver;
 
-
 /**
  * A <a href="http://camel.apache.org/data-format.html">data format</a> ({@link DataFormat})
  * using <a href="http://www.snakeyaml.org">SnakeYAML</a> to marshal to and from YAML.
  */
-public class SnakeYAMLDataFormat extends ServiceSupport implements DataFormat, DataFormatName {
-
-    private ThreadLocal<WeakReference<Yaml>> yamlCache;
+public final class SnakeYAMLDataFormat extends ServiceSupport implements DataFormat, DataFormatName {
+    private final ThreadLocal<WeakReference<Yaml>> yamlCache;
     private BaseConstructor constructor;
     private Representer representer;
     private DumperOptions dumperOptions;
@@ -57,19 +60,25 @@ public class SnakeYAMLDataFormat extends ServiceSupport implements DataFormat, D
     private ClassLoader classLoader;
     private Class<?> unmarshalType;
     private List<TypeDescription> typeDescriptions;
-    private Map<Class<?>, Tag> classTags;
+    private ConcurrentMap<Class<?>, Tag> classTags;
     private boolean useApplicationContextClassLoader;
     private boolean prettyFlow;
+    private boolean allowAnyType;
+    private List<TypeFilter> typeFilters;
 
     public SnakeYAMLDataFormat() {
-        this(Object.class);
+        this(null);
     }
 
     public SnakeYAMLDataFormat(Class<?> type) {
-        this.unmarshalType = type;
         this.yamlCache = new ThreadLocal<>();
         this.useApplicationContextClassLoader = true;
         this.prettyFlow = false;
+        this.allowAnyType = false;
+
+        if (type != null) {
+            setUnmarshalType(type);
+        }
     }
 
     @Override
@@ -79,15 +88,16 @@ public class SnakeYAMLDataFormat extends ServiceSupport implements DataFormat, D
 
     @Override
     public void marshal(final Exchange exchange, final Object graph, final OutputStream stream) throws Exception {
-        try (final OutputStreamWriter osw = new OutputStreamWriter(stream, IOHelper.getCharsetName(exchange))) {
+        try (OutputStreamWriter osw = new OutputStreamWriter(stream, IOHelper.getCharsetName(exchange))) {
             getYaml(exchange.getContext()).dump(graph, osw);
         }
     }
 
     @Override
     public Object unmarshal(final Exchange exchange, final InputStream stream) throws Exception {
-        try (final InputStreamReader isr = new InputStreamReader(stream, IOHelper.getCharsetName(exchange))) {
-            return getYaml(exchange.getContext()).loadAs(isr, unmarshalType);
+        try (InputStreamReader isr = new InputStreamReader(stream, IOHelper.getCharsetName(exchange))) {
+            Class<?> unmarshalObjectType = unmarshalType != null ? unmarshalType : Object.class;
+            return getYaml(exchange.getContext()).loadAs(isr, unmarshalObjectType);
         }
     }
 
@@ -105,17 +115,26 @@ public class SnakeYAMLDataFormat extends ServiceSupport implements DataFormat, D
             DumperOptions yamlDumperOptions = this.dumperOptions;
             Resolver yamlResolver = this.resolver;
             ClassLoader yamlClassLoader = this.classLoader;
+            Collection<TypeFilter> yamlTypeFilters = this.typeFilters;
 
             if (yamlClassLoader == null && useApplicationContextClassLoader) {
                 yamlClassLoader = context.getApplicationContextClassLoader();
             }
 
             if (yamlConstructor == null) {
-                yamlConstructor = yamlClassLoader == null
-                    ? new Constructor()
-                    : new CustomClassLoaderConstructor(yamlClassLoader);
+                if (allowAnyType) {
+                    yamlTypeFilters = Collections.singletonList(TypeFilters.allowAll());
+                }
+
+                if (yamlTypeFilters != null) {
+                    yamlConstructor = yamlClassLoader != null
+                        ? typeFilterConstructor(yamlClassLoader, yamlTypeFilters)
+                        : typeFilterConstructor(yamlTypeFilters);
+                } else {
+                    yamlConstructor = new SafeConstructor();
+                }
 
-                if (typeDescriptions != null) {
+                if (typeDescriptions != null && yamlConstructor instanceof Constructor) {
                     for (TypeDescription typeDescription : typeDescriptions) {
                         ((Constructor)yamlConstructor).addTypeDescription(typeDescription);
                     }
@@ -219,6 +238,7 @@ public class SnakeYAMLDataFormat extends ServiceSupport implements DataFormat, D
      */
     public void setUnmarshalType(Class<?> unmarshalType) {
         this.unmarshalType = unmarshalType;
+        addTypeFilters(TypeFilters.types(unmarshalType));
     }
 
     public List<TypeDescription> getTypeDescriptions() {
@@ -229,22 +249,24 @@ public class SnakeYAMLDataFormat extends ServiceSupport implements DataFormat, D
      * Make YAML aware how to parse a custom Class.
      */
     public void setTypeDescriptions(List<TypeDescription> typeDescriptions) {
-        this.typeDescriptions = typeDescriptions;
+        this.typeDescriptions = new CopyOnWriteArrayList<>(typeDescriptions);
     }
 
-    public void addTypeDescriptions(TypeDescription... typeDescriptions) {
+    public void addTypeDescriptions(Collection<TypeDescription> typeDescriptions) {
         if (this.typeDescriptions == null) {
-            this.typeDescriptions = new LinkedList<>();
+            this.typeDescriptions = new CopyOnWriteArrayList<>();
         }
 
-        for (TypeDescription typeDescription : typeDescriptions) {
-            this.typeDescriptions.add(typeDescription);
-        }
+        this.typeDescriptions.addAll(typeDescriptions);
+    }
+
+    public void addTypeDescriptions(TypeDescription... typeDescriptions) {
+        addTypeDescriptions(Arrays.asList(typeDescriptions));
     }
 
     public void addTypeDescription(Class<?> type, Tag tag) {
         if (this.typeDescriptions == null) {
-            this.typeDescriptions = new LinkedList<>();
+            this.typeDescriptions = new CopyOnWriteArrayList<>();
         }
 
         this.typeDescriptions.add(new TypeDescription(type, tag));
@@ -258,12 +280,13 @@ public class SnakeYAMLDataFormat extends ServiceSupport implements DataFormat, D
      * Define a tag for the <code>Class</code> to serialize.
      */
     public void setClassTags(Map<Class<?>, Tag> classTags) {
-        this.classTags = classTags;
+        this.classTags = new ConcurrentHashMap<>();
+        this.classTags.putAll(classTags);
     }
 
     public void addClassTags(Class<?> type, Tag tag) {
         if (this.classTags == null) {
-            this.classTags = new LinkedHashMap<>();
+            this.classTags = new ConcurrentHashMap<>();
         }
 
         this.classTags.put(type, tag);
@@ -301,4 +324,76 @@ public class SnakeYAMLDataFormat extends ServiceSupport implements DataFormat, D
         addClassTags(type, tag);
         addTypeDescription(type, tag);
     }
+
+    public List<TypeFilter> getTypeFilters() {
+        return typeFilters;
+    }
+
+    /**
+     * Set the types SnakeYAML is allowed to un-marshall
+     */
+    public void setTypeFilters(List<TypeFilter> typeFilters) {
+        this.typeFilters = new CopyOnWriteArrayList<>(typeFilters);
+    }
+
+    public void setTypeFilterDefinitions(List<String> typeFilterDefinitions) {
+        this.typeFilters = new CopyOnWriteArrayList<>();
+
+        for (String definition : typeFilterDefinitions) {
+            TypeFilters.valueOf(definition).ifPresent(this.typeFilters::add);
+        }
+    }
+
+    public void addTypeFilters(Collection<TypeFilter> typeFilters) {
+        if (this.typeFilters == null) {
+            this.typeFilters = new CopyOnWriteArrayList<>();
+        }
+
+        this.typeFilters.addAll(typeFilters);
+    }
+
+    public void addTypeFilters(TypeFilter... typeFilters) {
+        addTypeFilters(Arrays.asList(typeFilters));
+    }
+
+    public boolean isAllowAnyType() {
+        return allowAnyType;
+    }
+
+    /**
+     * Allow any class to be un-marshaled, same as setTypeFilters(TypeFilters.allowAll())
+     */
+    public void setAllowAnyType(boolean allowAnyType) {
+        this.allowAnyType = allowAnyType;
+    }
+
+    // ***************************
+    // Constructors
+    // ***************************
+
+    private static Constructor typeFilterConstructor(final Collection<TypeFilter> typeFilters) {
+        return new Constructor() {
+            @Override
+            protected Class<?> getClassForName(String name) throws ClassNotFoundException {
+                if (typeFilters.stream().noneMatch(f -> f.test(name))) {
+                    throw new IllegalArgumentException("Type " + name + " is not allowed");
+                }
+
+                return super.getClassForName(name);
+            }
+        };
+    }
+
+    private static Constructor typeFilterConstructor(final ClassLoader classLoader, final Collection<TypeFilter> typeFilters) {
+        return new CustomClassLoaderConstructor(classLoader) {
+            @Override
+            protected Class<?> getClassForName(String name) throws ClassNotFoundException {
+                if (typeFilters.stream().noneMatch(f -> f.test(name))) {
+                    throw new IllegalArgumentException("Type " + name + " is not allowed");
+                }
+
+                return super.getClassForName(name);
+            }
+        };
+    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/2f19ce59/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/TypeFilter.java
----------------------------------------------------------------------
diff --git a/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/TypeFilter.java b/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/TypeFilter.java
new file mode 100644
index 0000000..68200f7
--- /dev/null
+++ b/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/TypeFilter.java
@@ -0,0 +1,23 @@
+/**
+ * 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.component.snakeyaml;
+
+import java.util.function.Predicate;
+
+@FunctionalInterface
+public interface TypeFilter extends Predicate<String> {
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/2f19ce59/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/TypeFilters.java
----------------------------------------------------------------------
diff --git a/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/TypeFilters.java b/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/TypeFilters.java
new file mode 100644
index 0000000..61f638a
--- /dev/null
+++ b/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/TypeFilters.java
@@ -0,0 +1,119 @@
+/**
+ * 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.component.snakeyaml;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Predicate;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+import org.apache.camel.util.StringHelper;
+
+public final class TypeFilters {
+    private TypeFilters() {
+    }
+
+    public static final class RegExp implements TypeFilter {
+        private final List<Predicate<String>> predicates;
+
+        public RegExp(String pattern) {
+            this.predicates = Collections.singletonList(Pattern.compile(pattern).asPredicate());
+        }
+
+        public RegExp(Collection<String> patterns) {
+            this.predicates = patterns.stream()
+                .map(Pattern::compile)
+                .map(Pattern::asPredicate)
+                .collect(Collectors.toList());
+        }
+
+        @Override
+        public boolean test(String type) {
+            return predicates.stream().anyMatch(p -> p.test(type));
+        }
+    }
+
+    public static final class TypeName implements TypeFilter {
+        private final List<String> values;
+
+        public TypeName(String value) {
+            this.values = Collections.singletonList(value);
+        }
+
+        public TypeName(Collection<String> values) {
+            this.values = new ArrayList<>(values);
+        }
+
+        @Override
+        public boolean test(String type) {
+            return this.values.contains(type);
+        }
+    }
+
+    // ***************************
+    // Helpers
+    // ***************************
+
+    public static Optional<TypeFilter> valueOf(String definition) {
+        String type = StringHelper.before(definition, ":");
+        if (type == null || "type".equals(type)) {
+            return StringHelper.after(definition, ":", TypeName::new);
+        } else if ("regexp".equals(type)) {
+            return StringHelper.after(definition, ":", RegExp::new);
+        }
+
+        return Optional.empty();
+    }
+
+    public static TypeFilter regexp(String... patterns) {
+        return new RegExp(Arrays.asList(patterns));
+    }
+
+    public static TypeFilter regexp(Collection<String> patterns) {
+        return new RegExp(patterns);
+    }
+
+    public static TypeFilter typeNames(Collection<String> values) {
+        return new TypeName(values);
+    }
+
+    public static TypeFilter typeNames(String... values) {
+        return typeNames(Arrays.asList(values));
+    }
+
+    public static TypeFilter types(Collection<Class<?>> values) {
+        return new TypeName(values.stream().map(c -> c.getName()).collect(Collectors.toList()));
+    }
+
+    public static TypeFilter types(Class<?>... values) {
+        return types(Arrays.asList(values));
+    }
+
+    public static TypeFilter allowAll() {
+        return s -> true;
+    }
+
+    public static TypeFilter allowNone() {
+        return s -> false;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/2f19ce59/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLBlueprintTypeFilterTest.java
----------------------------------------------------------------------
diff --git a/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLBlueprintTypeFilterTest.java b/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLBlueprintTypeFilterTest.java
new file mode 100644
index 0000000..8cfa764
--- /dev/null
+++ b/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLBlueprintTypeFilterTest.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.component.snakeyaml;
+
+import org.apache.camel.test.blueprint.CamelBlueprintTestSupport;
+import org.junit.Test;
+
+public class SnakeYAMLBlueprintTypeFilterTest extends CamelBlueprintTestSupport {
+    @Test
+    public void testSafeConstructor() throws Exception {
+        SnakeYAMLTypeFilterHelper.testSafeConstructor(template);
+    }
+
+    @Test
+    public void testTypeConstructor() throws Exception {
+        SnakeYAMLTypeFilterHelper.testTypeConstructor(template);
+    }
+
+    @Test
+    public void testTypeConstructorFromDefinition() throws Exception {
+        SnakeYAMLTypeFilterHelper.testTypeConstructorFromDefinition(template);
+    }
+
+    @Test
+    public void testAllowAllConstructor() throws Exception {
+        SnakeYAMLTypeFilterHelper.testAllowAllConstructor(template);
+    }
+
+    @Override
+    protected String getBlueprintDescriptor() {
+        return "OSGI-INF/blueprint/blueprint-typefilter.xml";
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/2f19ce59/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLMarshalTest.java
----------------------------------------------------------------------
diff --git a/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLMarshalTest.java b/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLMarshalTest.java
deleted file mode 100644
index 0284386..0000000
--- a/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLMarshalTest.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/**
- * 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.component.snakeyaml;
-
-import java.util.Arrays;
-import java.util.Collection;
-
-import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.component.snakeyaml.model.TestPojo;
-import org.apache.camel.test.junit4.CamelTestSupport;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.yaml.snakeyaml.nodes.Tag;
-
-import static org.apache.camel.component.snakeyaml.SnakeYAMLMarshalTestHelper.createClassTagDataFormat;
-import static org.apache.camel.component.snakeyaml.SnakeYAMLMarshalTestHelper.createDataFormat;
-import static org.apache.camel.component.snakeyaml.SnakeYAMLMarshalTestHelper.createPrettyFlowDataFormat;
-import static org.apache.camel.component.snakeyaml.SnakeYAMLMarshalTestHelper.createTestMap;
-import static org.apache.camel.component.snakeyaml.SnakeYAMLMarshalTestHelper.createTestPojo;
-
-@RunWith(Parameterized.class)
-public class SnakeYAMLMarshalTest extends CamelTestSupport {
-
-    private final SnakeYAMLDataFormat format;
-    private final Object body;
-    private final String expected;
-
-    public SnakeYAMLMarshalTest(SnakeYAMLDataFormat format, Object body, String expected) {
-        this.format = format;
-        this.body = body;
-        this.expected = expected;
-    }
-
-    @Parameterized.Parameters
-    public static Collection yamlCases() {
-        return Arrays.asList(new Object[][] {
-            {
-                createDataFormat(null),
-                createTestMap(),
-                "{name: Camel}"
-            },
-            {
-                createDataFormat(TestPojo.class),
-                createTestPojo(),
-                "!!org.apache.camel.component.snakeyaml.model.TestPojo {name: Camel}"
-            },
-            {
-                createPrettyFlowDataFormat(TestPojo.class, true),
-                createTestPojo(),
-                "!!org.apache.camel.component.snakeyaml.model.TestPojo {\n  name: Camel\n}"
-            },
-            {
-                createClassTagDataFormat(TestPojo.class, new Tag("!tpojo")),
-                createTestPojo(),
-                "!tpojo {name: Camel}"
-            }
-        });
-    }
-
-    @Test
-    public void testMarshalAndUnmarshal() throws Exception {
-        SnakeYAMLMarshalTestHelper.marshalAndUnmarshal(
-            context(),
-            body,
-            "mock:reverse",
-            "direct:in",
-            "direct:back",
-            expected
-        );
-    }
-
-    @Override
-    protected RouteBuilder createRouteBuilder() throws Exception {
-        return new RouteBuilder() {
-            @Override
-            public void configure() throws Exception {
-                from("direct:in")
-                    .marshal(format);
-                from("direct:back")
-                    .unmarshal(format)
-                    .to("mock:reverse");
-            }
-        };
-    }
-}

http://git-wip-us.apache.org/repos/asf/camel/blob/2f19ce59/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLMarshalTestHelper.java
----------------------------------------------------------------------
diff --git a/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLMarshalTestHelper.java b/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLMarshalTestHelper.java
deleted file mode 100644
index e39d014..0000000
--- a/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLMarshalTestHelper.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
- * 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.component.snakeyaml;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.camel.CamelContext;
-import org.apache.camel.ProducerTemplate;
-import org.apache.camel.component.mock.MockEndpoint;
-import org.apache.camel.component.snakeyaml.model.TestPojo;
-import org.yaml.snakeyaml.nodes.Tag;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-public final class SnakeYAMLMarshalTestHelper  {
-
-    protected SnakeYAMLMarshalTestHelper() {
-    }
-
-    public static TestPojo createTestPojo() {
-        return new TestPojo("Camel");
-    }
-
-    public static Map<String, String> createTestMap() {
-        Map<String, String> map = new HashMap<>();
-        map.put("name", "Camel");
-
-        return map;
-    }
-
-    public static SnakeYAMLDataFormat createDataFormat(Class<?> type) {
-        return type == null ? new SnakeYAMLDataFormat() : new SnakeYAMLDataFormat(type);
-    }
-
-    public static SnakeYAMLDataFormat createPrettyFlowDataFormat(Class<?> type, boolean prettyFlow) {
-        SnakeYAMLDataFormat df = type == null ? new SnakeYAMLDataFormat() : new SnakeYAMLDataFormat(type);
-        df.setPrettyFlow(prettyFlow);
-
-        return df;
-    }
-
-    public static SnakeYAMLDataFormat createClassTagDataFormat(Class<?> type, Tag tag) {
-        SnakeYAMLDataFormat df = new SnakeYAMLDataFormat(type);
-        df.addTag(type, tag);
-
-        return df;
-    }
-
-    public static void marshalAndUnmarshal(
-            CamelContext context, Object body, String mockName, String directIn, String directBack, String expected) throws Exception {
-
-        MockEndpoint mock = context.getEndpoint(mockName, MockEndpoint.class);
-        assertNotNull(mock);
-
-        mock.expectedMessageCount(1);
-        mock.message(0).body().isInstanceOf(body.getClass());
-        mock.message(0).body().isEqualTo(body);
-
-        ProducerTemplate template = context.createProducerTemplate();
-        String result = template.requestBody(directIn, body, String.class);
-        assertNotNull(result);
-        assertEquals(expected, result.trim());
-
-        template.sendBody(directBack, result);
-
-        mock.assertIsSatisfied();
-    }
-}

http://git-wip-us.apache.org/repos/asf/camel/blob/2f19ce59/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLSpringMarshalTest.java
----------------------------------------------------------------------
diff --git a/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLSpringMarshalTest.java b/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLSpringMarshalTest.java
deleted file mode 100644
index a80b4fd..0000000
--- a/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLSpringMarshalTest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- * 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.component.snakeyaml;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.camel.test.spring.CamelSpringTestSupport;
-import org.junit.Test;
-import org.springframework.context.support.AbstractXmlApplicationContext;
-import org.springframework.context.support.ClassPathXmlApplicationContext;
-
-public class SnakeYAMLSpringMarshalTest extends CamelSpringTestSupport {
-
-    @Test
-    public void testMarshalAndUnmarshalMap() throws Exception {
-        Map<String, String> in = new HashMap<>();
-        in.put("name", "Camel");
-
-        SnakeYAMLMarshalTestHelper.marshalAndUnmarshal(
-            context(),
-            SnakeYAMLMarshalTestHelper.createTestMap(),
-            "mock:reverse",
-            "direct:in",
-            "direct:back",
-            "{name: Camel}"
-        );
-    }
-
-    @Test
-    public void testMarshalAndUnmarshalPojo() throws Exception {
-        SnakeYAMLMarshalTestHelper.marshalAndUnmarshal(
-            context(),
-            SnakeYAMLMarshalTestHelper.createTestPojo(),
-            "mock:reversePojo",
-            "direct:inPojo",
-            "direct:backPojo",
-            "!!org.apache.camel.component.snakeyaml.model.TestPojo {name: Camel}"
-        );
-    }
-
-    @Test
-    public void testMarshalAndUnmarshalPojoWithPrettyFlow() throws Exception {
-        SnakeYAMLMarshalTestHelper.marshalAndUnmarshal(
-            context(),
-            SnakeYAMLMarshalTestHelper.createTestPojo(),
-            "mock:reversePojoWithPrettyFlow",
-            "direct:inPojoWithPrettyFlow",
-            "direct:backPojoWithPrettyFlow",
-            "!!org.apache.camel.component.snakeyaml.model.TestPojo {\n  name: Camel\n}"
-        );
-    }
-
-    @Override
-    protected AbstractXmlApplicationContext createApplicationContext() {
-        return new ClassPathXmlApplicationContext("org/apache/camel/component/snakeyaml/SnakeYAMLSpringMarshalTest.xml");
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/camel/blob/2f19ce59/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLSpringTest.java
----------------------------------------------------------------------
diff --git a/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLSpringTest.java b/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLSpringTest.java
new file mode 100644
index 0000000..7034459
--- /dev/null
+++ b/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLSpringTest.java
@@ -0,0 +1,73 @@
+/**
+ * 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.component.snakeyaml;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.camel.test.spring.CamelSpringTestSupport;
+import org.junit.Test;
+import org.springframework.context.support.AbstractXmlApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+import org.springframework.test.annotation.DirtiesContext;
+
+@DirtiesContext
+public class SnakeYAMLSpringTest extends CamelSpringTestSupport {
+    @Test
+    public void testMarshalAndUnmarshalMap() throws Exception {
+        Map<String, String> in = new HashMap<>();
+        in.put("name", "Camel");
+
+        SnakeYAMLTestHelper.marshalAndUnmarshal(
+            context(),
+            SnakeYAMLTestHelper.createTestMap(),
+            "mock:reverse",
+            "direct:in",
+            "direct:back",
+            "{name: Camel}"
+        );
+    }
+
+    @Test
+    public void testMarshalAndUnmarshalPojo() throws Exception {
+        SnakeYAMLTestHelper.marshalAndUnmarshal(
+            context(),
+            SnakeYAMLTestHelper.createTestPojo(),
+            "mock:reversePojo",
+            "direct:inPojo",
+            "direct:backPojo",
+            "!!org.apache.camel.component.snakeyaml.model.TestPojo {name: Camel}"
+        );
+    }
+
+    @Test
+    public void testMarshalAndUnmarshalPojoWithPrettyFlow() throws Exception {
+        SnakeYAMLTestHelper.marshalAndUnmarshal(
+            context(),
+            SnakeYAMLTestHelper.createTestPojo(),
+            "mock:reversePojoWithPrettyFlow",
+            "direct:inPojoWithPrettyFlow",
+            "direct:backPojoWithPrettyFlow",
+            "!!org.apache.camel.component.snakeyaml.model.TestPojo {\n  name: Camel\n}"
+        );
+    }
+
+    @Override
+    protected AbstractXmlApplicationContext createApplicationContext() {
+        return new ClassPathXmlApplicationContext("org/apache/camel/component/snakeyaml/SnakeYAMLSpringTest.xml");
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/2f19ce59/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLSpringTypeFilterTest.java
----------------------------------------------------------------------
diff --git a/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLSpringTypeFilterTest.java b/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLSpringTypeFilterTest.java
new file mode 100644
index 0000000..38df35f
--- /dev/null
+++ b/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLSpringTypeFilterTest.java
@@ -0,0 +1,51 @@
+/**
+ * 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.component.snakeyaml;
+
+import org.apache.camel.test.spring.CamelSpringTestSupport;
+import org.junit.Test;
+import org.springframework.context.support.AbstractXmlApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+import org.springframework.test.annotation.DirtiesContext;
+
+@DirtiesContext
+public class SnakeYAMLSpringTypeFilterTest extends CamelSpringTestSupport {
+    @Test
+    public void testSafeConstructor() throws Exception {
+        SnakeYAMLTypeFilterHelper.testSafeConstructor(template);
+    }
+
+    @Test
+    public void testTypeConstructor() throws Exception {
+        SnakeYAMLTypeFilterHelper.testTypeConstructor(template);
+    }
+
+    @Test
+    public void testTypeConstructorFromDefinition() throws Exception {
+        SnakeYAMLTypeFilterHelper.testTypeConstructorFromDefinition(template);
+    }
+
+    @Test
+    public void testAllowAllConstructor() throws Exception {
+        SnakeYAMLTypeFilterHelper.testAllowAllConstructor(template);
+    }
+
+    @Override
+    protected AbstractXmlApplicationContext createApplicationContext() {
+        return new ClassPathXmlApplicationContext("org/apache/camel/component/snakeyaml/SnakeYAMLSpringTypeFilterTest.xml");
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/2f19ce59/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLTest.java
----------------------------------------------------------------------
diff --git a/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLTest.java b/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLTest.java
new file mode 100644
index 0000000..a276b41
--- /dev/null
+++ b/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLTest.java
@@ -0,0 +1,100 @@
+/**
+ * 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.component.snakeyaml;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.snakeyaml.model.TestPojo;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.yaml.snakeyaml.nodes.Tag;
+
+import static org.apache.camel.component.snakeyaml.SnakeYAMLTestHelper.createClassTagDataFormat;
+import static org.apache.camel.component.snakeyaml.SnakeYAMLTestHelper.createDataFormat;
+import static org.apache.camel.component.snakeyaml.SnakeYAMLTestHelper.createPrettyFlowDataFormat;
+import static org.apache.camel.component.snakeyaml.SnakeYAMLTestHelper.createTestMap;
+import static org.apache.camel.component.snakeyaml.SnakeYAMLTestHelper.createTestPojo;
+
+@RunWith(Parameterized.class)
+public class SnakeYAMLTest extends CamelTestSupport {
+
+    private final SnakeYAMLDataFormat format;
+    private final Object body;
+    private final String expected;
+
+    public SnakeYAMLTest(SnakeYAMLDataFormat format, Object body, String expected) {
+        this.format = format;
+        this.body = body;
+        this.expected = expected;
+    }
+
+    @Parameterized.Parameters
+    public static Collection yamlCases() {
+        return Arrays.asList(new Object[][] {
+            {
+                createDataFormat(null),
+                createTestMap(),
+                "{name: Camel}"
+            },
+            {
+                createDataFormat(TestPojo.class),
+                createTestPojo(),
+                "!!org.apache.camel.component.snakeyaml.model.TestPojo {name: Camel}"
+            },
+            {
+                createPrettyFlowDataFormat(TestPojo.class, true),
+                createTestPojo(),
+                "!!org.apache.camel.component.snakeyaml.model.TestPojo {\n  name: Camel\n}"
+            },
+            {
+                createClassTagDataFormat(TestPojo.class, new Tag("!tpojo")),
+                createTestPojo(),
+                "!tpojo {name: Camel}"
+            }
+        });
+    }
+
+    @Test
+    public void testMarshalAndUnmarshal() throws Exception {
+        SnakeYAMLTestHelper.marshalAndUnmarshal(
+            context(),
+            body,
+            "mock:reverse",
+            "direct:in",
+            "direct:back",
+            expected
+        );
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:in")
+                    .marshal(format);
+                from("direct:back")
+                    .unmarshal(format)
+                    .to("mock:reverse");
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/2f19ce59/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLTestHelper.java
----------------------------------------------------------------------
diff --git a/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLTestHelper.java b/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLTestHelper.java
new file mode 100644
index 0000000..86a2a83
--- /dev/null
+++ b/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLTestHelper.java
@@ -0,0 +1,90 @@
+/**
+ * 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.component.snakeyaml;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.component.snakeyaml.model.TestPojo;
+import org.yaml.snakeyaml.nodes.Tag;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public final class SnakeYAMLTestHelper {
+
+    protected SnakeYAMLTestHelper() {
+    }
+
+    public static TestPojo createTestPojo() {
+        return new TestPojo("Camel");
+    }
+
+    public static Map<String, String> createTestMap() {
+        Map<String, String> map = new HashMap<>();
+        map.put("name", "Camel");
+
+        return map;
+    }
+
+    public static SnakeYAMLDataFormat createDataFormat(final Class<?> type) {
+        SnakeYAMLDataFormat format = new SnakeYAMLDataFormat();
+        if (type != null) {
+            format.setUnmarshalType(type);
+        }
+
+        return format;
+    }
+
+    public static SnakeYAMLDataFormat createPrettyFlowDataFormat(Class<?> type, boolean prettyFlow) {
+        SnakeYAMLDataFormat format = createDataFormat(type);
+        format.setPrettyFlow(prettyFlow);
+
+        return format;
+    }
+
+    public static SnakeYAMLDataFormat createClassTagDataFormat(Class<?> type, Tag tag) {
+        SnakeYAMLDataFormat format = createDataFormat(type);
+        format.addTag(type, tag);
+
+        return format;
+    }
+
+    public static void marshalAndUnmarshal(
+            CamelContext context, Object body, String mockName, String directIn, String directBack, String expected) throws Exception {
+
+        MockEndpoint mock = context.getEndpoint(mockName, MockEndpoint.class);
+        assertNotNull(mock);
+
+        mock.expectedMessageCount(1);
+        mock.message(0).body().isInstanceOf(body.getClass());
+        mock.message(0).body().isEqualTo(body);
+
+        ProducerTemplate template = context.createProducerTemplate();
+        String result = template.requestBody(directIn, body, String.class);
+        assertNotNull(result);
+        assertEquals(expected, result.trim());
+
+        template.sendBody(directBack, result);
+
+
+        mock.assertIsSatisfied();
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/2f19ce59/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLTypeFilterHelper.java
----------------------------------------------------------------------
diff --git a/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLTypeFilterHelper.java b/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLTypeFilterHelper.java
new file mode 100644
index 0000000..6339aba
--- /dev/null
+++ b/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLTypeFilterHelper.java
@@ -0,0 +1,117 @@
+/**
+ * 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.component.snakeyaml;
+
+import org.apache.camel.CamelExecutionException;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.component.snakeyaml.model.RexPojo;
+import org.apache.camel.component.snakeyaml.model.TestPojo;
+import org.apache.camel.component.snakeyaml.model.UnsafePojo;
+import org.yaml.snakeyaml.constructor.ConstructorException;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public final class SnakeYAMLTypeFilterHelper {
+    private SnakeYAMLTypeFilterHelper() {
+    }
+
+    static void testSafeConstructor(ProducerTemplate template) throws Exception {
+        try {
+            template.sendBody(
+                "direct:safe-constructor",
+                "!!org.apache.camel.component.snakeyaml.model.TestPojo {name: Camel}");
+
+            fail("As SnakeYAML uses SafeConstructor, custom types should not be allowed");
+        } catch (CamelExecutionException e) {
+            assertTrue(e.getCause() instanceof ConstructorException);
+        }
+    }
+
+    static void testTypeConstructor(ProducerTemplate template) throws Exception {
+        Object result = template.requestBody(
+            "direct:type-constructor",
+            "!!org.apache.camel.component.snakeyaml.model.TestPojo {name: Camel}");
+
+        assertNotNull(result);
+        assertTrue(result instanceof TestPojo);
+
+        try {
+            template.sendBody(
+                "direct:type-constructor",
+                "!!org.apache.camel.component.snakeyaml.model.UnsafePojo {name: Camel}");
+
+            fail("As SnakeYAML filters class is can unmarshall, UnsafePojo should not be allowed");
+        } catch (CamelExecutionException e) {
+            // Wrapped by SnakeYAML
+            assertTrue(e.getCause() instanceof ConstructorException);
+            // Thrown by SnakeYAMLDataFormat
+            assertTrue(e.getCause().getCause() instanceof IllegalArgumentException);
+        }
+    }
+
+    static void testTypeConstructorFromDefinition(ProducerTemplate template) throws Exception {
+        Object result;
+
+        // TestPojo --> from definition type:
+        result = template.requestBody(
+            "direct:type-constructor-strdef",
+            "!!org.apache.camel.component.snakeyaml.model.TestPojo {name: Camel}");
+
+        assertNotNull(result);
+        assertTrue(result instanceof TestPojo);
+
+        // RexPojo --> from definition rex:
+        result = template.requestBody(
+            "direct:type-constructor-strdef",
+            "!!org.apache.camel.component.snakeyaml.model.RexPojo {name: Camel}");
+
+        assertNotNull(result);
+        assertTrue(result instanceof RexPojo);
+
+        try {
+            template.sendBody(
+                "direct:type-constructor-strdef",
+                "!!org.apache.camel.component.snakeyaml.model.UnsafePojo {name: Camel}");
+
+            fail("As SnakeYAML filters class is can unmarshall, UnsafePojo should not be allowed");
+        } catch (CamelExecutionException e) {
+            // Wrapped by SnakeYAML
+            assertTrue(e.getCause() instanceof ConstructorException);
+            // Thrown by SnakeYAMLDataFormat
+            assertTrue(e.getCause().getCause() instanceof IllegalArgumentException);
+        }
+    }
+
+    static void testAllowAllConstructor(ProducerTemplate template) throws Exception {
+        Object testPojo = template.requestBody(
+            "direct:all-constructor",
+            "!!org.apache.camel.component.snakeyaml.model.TestPojo {name: Camel}");
+
+        assertNotNull(testPojo);
+        assertTrue(testPojo instanceof TestPojo);
+
+        Object unsafePojo = template.requestBody(
+            "direct:all-constructor",
+            "!!org.apache.camel.component.snakeyaml.model.UnsafePojo {name: Camel}");
+
+        assertNotNull(unsafePojo);
+        assertTrue(unsafePojo instanceof UnsafePojo);
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/2f19ce59/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLTypeFilterTest.java
----------------------------------------------------------------------
diff --git a/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLTypeFilterTest.java b/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLTypeFilterTest.java
new file mode 100644
index 0000000..53e7bbd
--- /dev/null
+++ b/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLTypeFilterTest.java
@@ -0,0 +1,85 @@
+/**
+ * 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.component.snakeyaml;
+
+import java.util.Arrays;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.snakeyaml.model.TestPojo;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Test;
+
+public class SnakeYAMLTypeFilterTest extends CamelTestSupport {
+    @Test
+    public void testSafeConstructor() throws Exception {
+        SnakeYAMLTypeFilterHelper.testSafeConstructor(template);
+    }
+
+    @Test
+    public void testTypeConstructor() throws Exception {
+        SnakeYAMLTypeFilterHelper.testTypeConstructor(template);
+    }
+
+    @Test
+    public void testTypeConstructorFromDefinition() throws Exception {
+        SnakeYAMLTypeFilterHelper.testTypeConstructorFromDefinition(template);
+    }
+
+    @Test
+    public void testAllowAllConstructor() throws Exception {
+        SnakeYAMLTypeFilterHelper.testAllowAllConstructor(template);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                // SafeConstructor
+                SnakeYAMLDataFormat safeConstructorDf = new SnakeYAMLDataFormat();
+
+                from("direct:safe-constructor")
+                    .unmarshal(safeConstructorDf);
+
+                // Type filter Constructor
+                SnakeYAMLDataFormat typeConstructorDf = new SnakeYAMLDataFormat();
+                typeConstructorDf.addTypeFilters(TypeFilters.types(TestPojo.class));
+
+                from("direct:type-constructor")
+                    .unmarshal(typeConstructorDf);
+
+                // Type filter Constructor from string definitions
+                SnakeYAMLDataFormat typeConstructorStrDf = new SnakeYAMLDataFormat();
+                typeConstructorStrDf.setTypeFilterDefinitions(Arrays.asList(
+                    "type:org.apache.camel.component.snakeyaml.model.TestPojo",
+                    "regexp:org.apache.camel.component.snakeyaml.model.R.*"));
+
+                from("direct:type-constructor-strdef")
+                    .unmarshal(typeConstructorStrDf);
+
+                // Allow all Constructor
+                SnakeYAMLDataFormat allConstructorDf = new SnakeYAMLDataFormat();
+                allConstructorDf.setAllowAnyType(true);
+
+                from("direct:all-constructor")
+                    .unmarshal(allConstructorDf)
+                    .to("mock:all-constructor");
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/2f19ce59/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLUnmarshalTypeTest.java
----------------------------------------------------------------------
diff --git a/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLUnmarshalTypeTest.java b/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLUnmarshalTypeTest.java
new file mode 100644
index 0000000..5cf7c7b
--- /dev/null
+++ b/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLUnmarshalTypeTest.java
@@ -0,0 +1,46 @@
+/**
+ * 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.component.snakeyaml;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.snakeyaml.model.TestPojo;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Test;
+
+public class SnakeYAMLUnmarshalTypeTest extends CamelTestSupport {
+    @Test
+    public void testUnmarshal() throws Exception {
+        Object result = template.requestBody("direct:unmarshal", "name: Camel");
+        assertNotNull(result);
+        assertTrue(result instanceof TestPojo);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                SnakeYAMLDataFormat format = new SnakeYAMLDataFormat();
+                format.setUnmarshalType(TestPojo.class);
+
+                from("direct:unmarshal")
+                    .unmarshal(format);
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/2f19ce59/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/model/RexPojo.java
----------------------------------------------------------------------
diff --git a/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/model/RexPojo.java b/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/model/RexPojo.java
new file mode 100644
index 0000000..4f8537c
--- /dev/null
+++ b/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/model/RexPojo.java
@@ -0,0 +1,63 @@
+/**
+ * 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.component.snakeyaml.model;
+
+public class RexPojo {
+    private String name;
+
+    public RexPojo() {
+    }
+
+    public RexPojo(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        RexPojo pojo = (RexPojo) o;
+
+        return name != null ? name.equals(pojo.name) : pojo.name == null;
+    }
+
+    @Override
+    public int hashCode() {
+        return name != null ? name.hashCode() : 0;
+    }
+
+    @Override
+    public String toString() {
+        return "RexPojo {"
+            + "name='" + name + '\''
+            + '}';
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/2f19ce59/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/model/TestPojo.java
----------------------------------------------------------------------
diff --git a/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/model/TestPojo.java b/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/model/TestPojo.java
index c62c929..2e5426c 100644
--- a/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/model/TestPojo.java
+++ b/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/model/TestPojo.java
@@ -36,8 +36,17 @@ public class TestPojo {
     }
 
     @Override
-    public boolean equals(Object obj) {
-        return this.name.equals(((TestPojo) obj).getName());
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        TestPojo pojo = (TestPojo) o;
+
+        return name != null ? name.equals(pojo.name) : pojo.name == null;
     }
 
     @Override
@@ -47,6 +56,8 @@ public class TestPojo {
 
     @Override
     public String toString() {
-        return "TestPojo[" + name + "]";
+        return "TestPojo {"
+            + "name='" + name + '\''
+            + '}';
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/2f19ce59/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/model/UnsafePojo.java
----------------------------------------------------------------------
diff --git a/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/model/UnsafePojo.java b/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/model/UnsafePojo.java
new file mode 100644
index 0000000..5d180bf
--- /dev/null
+++ b/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/model/UnsafePojo.java
@@ -0,0 +1,63 @@
+/**
+ * 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.component.snakeyaml.model;
+
+public class UnsafePojo {
+    private String name;
+
+    public UnsafePojo() {
+    }
+
+    public UnsafePojo(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        UnsafePojo pojo = (UnsafePojo) o;
+
+        return name != null ? name.equals(pojo.name) : pojo.name == null;
+    }
+
+    @Override
+    public int hashCode() {
+        return name != null ? name.hashCode() : 0;
+    }
+
+    @Override
+    public String toString() {
+        return "UnsafePojo {"
+            + "name='" + name + '\''
+            + '}';
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/2f19ce59/components/camel-snakeyaml/src/test/resources/OSGI-INF/blueprint/blueprint-typefilter.xml
----------------------------------------------------------------------
diff --git a/components/camel-snakeyaml/src/test/resources/OSGI-INF/blueprint/blueprint-typefilter.xml b/components/camel-snakeyaml/src/test/resources/OSGI-INF/blueprint/blueprint-typefilter.xml
new file mode 100644
index 0000000..a0529b1
--- /dev/null
+++ b/components/camel-snakeyaml/src/test/resources/OSGI-INF/blueprint/blueprint-typefilter.xml
@@ -0,0 +1,71 @@
+<?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.
+  -->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+
+  <!-- ******************** -->
+  <!-- DataFormat           -->
+  <!-- ******************** -->
+
+  <bean id="yaml-safe-constructor" class="org.apache.camel.component.snakeyaml.SnakeYAMLDataFormat"/>
+
+  <bean id="yaml-type-constructor" class="org.apache.camel.component.snakeyaml.SnakeYAMLDataFormat">
+    <property name="typeFilterDefinitions">
+      <list>
+        <value>type:org.apache.camel.component.snakeyaml.model.TestPojo</value>
+      </list>
+    </property>
+  </bean>
+
+  <bean id="yaml-type-constructor-strdef" class="org.apache.camel.component.snakeyaml.SnakeYAMLDataFormat">
+    <property name="typeFilterDefinitions">
+      <list>
+        <value>type:org.apache.camel.component.snakeyaml.model.TestPojo</value>
+        <value>regexp:org.apache.camel.component.snakeyaml.model.Rex.*</value>
+      </list>
+    </property>
+  </bean>
+
+  <bean id="yaml-all-constructor" class="org.apache.camel.component.snakeyaml.SnakeYAMLDataFormat">
+    <property name="allowAnyType" value="true"/>
+  </bean>
+
+  <!-- ******************** -->
+  <!-- Camel Context        -->
+  <!-- ******************** -->
+
+  <camelContext id="camel" xmlns="http://camel.apache.org/schema/blueprint">
+    <route>
+      <from uri="direct:safe-constructor"/>
+      <unmarshal ref="yaml-safe-constructor"/>
+    </route>
+    <route>
+      <from uri="direct:type-constructor"/>
+      <unmarshal ref="yaml-type-constructor"/>
+    </route>
+    <route>
+      <from uri="direct:type-constructor-strdef"/>
+      <unmarshal ref="yaml-type-constructor-strdef"/>
+    </route>
+    <route>
+      <from uri="direct:all-constructor"/>
+      <unmarshal ref="yaml-all-constructor"/>
+    </route>
+
+  </camelContext>
+
+</blueprint>

http://git-wip-us.apache.org/repos/asf/camel/blob/2f19ce59/components/camel-snakeyaml/src/test/resources/org/apache/camel/component/snakeyaml/SnakeYAMLSpringMarshalTest.xml
----------------------------------------------------------------------
diff --git a/components/camel-snakeyaml/src/test/resources/org/apache/camel/component/snakeyaml/SnakeYAMLSpringMarshalTest.xml b/components/camel-snakeyaml/src/test/resources/org/apache/camel/component/snakeyaml/SnakeYAMLSpringMarshalTest.xml
deleted file mode 100644
index 78210ff..0000000
--- a/components/camel-snakeyaml/src/test/resources/org/apache/camel/component/snakeyaml/SnakeYAMLSpringMarshalTest.xml
+++ /dev/null
@@ -1,76 +0,0 @@
-<?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">
-
-    <camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
-
-        <!-- we define the yaml SnakeYAML data formats to be used -->
-        <dataFormats>
-            <yaml id="yaml"
-                  library="SnakeYAML"/>
-
-            <yaml id="yaml-pojo"
-                  library="SnakeYAML"
-                  unmarshalTypeName="org.apache.camel.component.snakeyaml.model.TestPojo"/>
-
-            <yaml id="yaml-pojo-pretty-flow"
-                  library="SnakeYAML"
-                  unmarshalTypeName="org.apache.camel.component.snakeyaml.model.TestPojo"
-                  prettyFlow="true"/>
-        </dataFormats>
-
-
-        <route>
-            <from uri="direct:in"/>
-            <marshal ref="yaml"/>
-        </route>
-
-        <route>
-            <from uri="direct:back"/>
-            <unmarshal ref="yaml"/>
-            <to uri="mock:reverse"/>
-        </route>
-
-        <route>
-            <from uri="direct:inPojo"/>
-            <marshal ref="yaml-pojo"/>
-        </route>
-
-        <route>
-            <from uri="direct:backPojo"/>
-            <unmarshal ref="yaml-pojo"/>
-            <to uri="mock:reversePojo"/>
-        </route>
-
-        <route>
-            <from uri="direct:inPojoWithPrettyFlow"/>
-            <marshal ref="yaml-pojo-pretty-flow"/>
-        </route>
-
-        <route>
-            <from uri="direct:backPojoWithPrettyFlow"/>
-            <unmarshal ref="yaml-pojo-pretty-flow"/>
-            <to uri="mock:reversePojoWithPrettyFlow"/>
-        </route>
-
-    </camelContext>
-</beans>


Mime
View raw message