You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by co...@apache.org on 2020/02/18 15:24:09 UTC

[camel] branch camel-3.0.x updated (2deab6f -> 1a04b47)

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

coheigea pushed a change to branch camel-3.0.x
in repository https://gitbox.apache.org/repos/asf/camel.git.


    from 2deab6f  CAMEL-14414: for aggregation group completion setting and removal is handled through methods to enforce code cohesion and avoid repetitions. fixed issue for CURRENT_GROUP and ALL_GROUPS flag removal. adapted tests and documentation (#3554)
     new 9bb3f9b  CAMEL-14532 - Fix issues with camel-snakeyaml
     new 1a64407  CAMEL-14532 - Fixing up docs
     new b00d36c  CAMEL-14532 - In xml model the types must be String
     new 70afca5  CAMEL-14532 - Fix checkstyle warnings
     new 1a04b47  CAMEL-14532 - Changing method signature

The 5 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../src/main/docs/yaml-snakeyaml-dataformat.adoc   |   8 +-
 .../component/snakeyaml/SnakeYAMLDataFormat.java   |  66 +-
 .../custom/CustomClassLoaderConstructor.java       |  90 +++
 .../component/snakeyaml/custom/CustomComposer.java | 276 ++++++++
 .../snakeyaml/custom/CustomConstructor.java        |  83 +++
 .../snakeyaml/custom/CustomSafeConstructor.java    |  83 +++
 .../camel/component/snakeyaml/custom/Yaml.java     | 715 +++++++++++++++++++++
 .../component/snakeyaml/SnakeYAMLDoSTest.java      | 159 +++++
 .../src/test/resources/data-dos.yaml               |  11 +
 .../camel-snakeyaml/src/test/resources/data.yaml   |   2 +
 .../camel/model/dataformat/YAMLDataFormat.java     |  27 +
 .../reifier/dataformat/YAMLDataFormatReifier.java  |   2 +
 .../ROOT/pages/yaml-snakeyaml-dataformat.adoc      |   8 +-
 .../modules/ROOT/pages/aggregate-eip.adoc          |   2 +-
 .../SnakeYAMLDataFormatConfiguration.java          |  24 +
 15 files changed, 1534 insertions(+), 22 deletions(-)
 create mode 100644 components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/CustomClassLoaderConstructor.java
 create mode 100644 components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/CustomComposer.java
 create mode 100644 components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/CustomConstructor.java
 create mode 100644 components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/CustomSafeConstructor.java
 create mode 100644 components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/Yaml.java
 create mode 100644 components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLDoSTest.java
 create mode 100644 components/camel-snakeyaml/src/test/resources/data-dos.yaml
 create mode 100644 components/camel-snakeyaml/src/test/resources/data.yaml


[camel] 03/05: CAMEL-14532 - In xml model the types must be String

Posted by co...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit b00d36ca0e9b9297a3592da620a40901a8594738
Author: Andrea Cosentino <an...@gmail.com>
AuthorDate: Tue Feb 18 14:07:26 2020 +0100

    CAMEL-14532 - In xml model the types must be String
---
 .../org/apache/camel/model/dataformat/YAMLDataFormat.java  | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/model/dataformat/YAMLDataFormat.java b/core/camel-core-engine/src/main/java/org/apache/camel/model/dataformat/YAMLDataFormat.java
index 951b1a6..33e86de 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/model/dataformat/YAMLDataFormat.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/model/dataformat/YAMLDataFormat.java
@@ -65,10 +65,10 @@ public class YAMLDataFormat extends DataFormatDefinition {
     private List<YAMLTypeFilterDefinition> typeFilters;
     @XmlAttribute
     @Metadata(javaType = "java.lang.Integer", defaultValue = "50")
-    private int maxAliasesForCollections = 50;
+    private String maxAliasesForCollections = "50";
     @XmlAttribute
-    @Metadata(javaType = "java.lang.Boolean", defaultValue = "false")
-    private boolean allowRecursiveKeys;
+    @Metadata(javaType = "java.lang.Boolean")
+    private String allowRecursiveKeys;
 
     public YAMLDataFormat() {
         this(YAMLLibrary.SnakeYAML);
@@ -221,25 +221,25 @@ public class YAMLDataFormat extends DataFormatDefinition {
         this.typeFilters = typeFilters;
     }
 
-    public int getMaxAliasesForCollections() {
+    public String getMaxAliasesForCollections() {
         return maxAliasesForCollections;
     }
 
     /**
      * Set the maximum amount of aliases allowed for collections.
      */
-    public void setMaxAliasesForCollections(int maxAliasesForCollections) {
+    public void setMaxAliasesForCollections(String maxAliasesForCollections) {
         this.maxAliasesForCollections = maxAliasesForCollections;
     }
 
-    public boolean isAllowRecursiveKeys() {
+    public String isAllowRecursiveKeys() {
         return allowRecursiveKeys;
     }
 
     /**
      * Set whether recursive keys are allowed.
      */
-    public void setAllowRecursiveKeys(boolean allowRecursiveKeys) {
+    public void setAllowRecursiveKeys(String allowRecursiveKeys) {
         this.allowRecursiveKeys = allowRecursiveKeys;
     }
 }


[camel] 05/05: CAMEL-14532 - Changing method signature

Posted by co...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 1a04b477ed63988cef709d785730c9641b2c5a46
Author: Colm O hEigeartaigh <co...@apache.org>
AuthorDate: Tue Feb 18 13:42:05 2020 +0000

    CAMEL-14532 - Changing method signature
---
 .../src/main/docs/yaml-snakeyaml-dataformat.adoc             |  8 +++++---
 .../org/apache/camel/model/dataformat/YAMLDataFormat.java    |  2 +-
 .../camel/reifier/dataformat/YAMLDataFormatReifier.java      |  2 +-
 .../modules/ROOT/pages/yaml-snakeyaml-dataformat.adoc        |  8 ++++++--
 docs/user-manual/modules/ROOT/pages/aggregate-eip.adoc       |  2 +-
 .../springboot/SnakeYAMLDataFormatConfiguration.java         | 12 ++++++------
 6 files changed, 20 insertions(+), 14 deletions(-)

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 ffa0c29..8843fa8 100644
--- a/components/camel-snakeyaml/src/main/docs/yaml-snakeyaml-dataformat.adoc
+++ b/components/camel-snakeyaml/src/main/docs/yaml-snakeyaml-dataformat.adoc
@@ -35,8 +35,8 @@ The YAML SnakeYAML dataformat supports 13 options, which are listed below.
 | 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
-| maxAliasesForCollections | 50 | int | Set the maximum amount of aliases allowed for collections.
-| allowRecursiveKeys | false | boolean | Set whether recursive keys are allowed.
+| maxAliasesForCollections | 50 | String | Set the maximum amount of aliases allowed for collections.
+| allowRecursiveKeys |  | String | Set whether recursive keys are allowed.
 | contentTypeHeader | false | Boolean | Whether the data format should set the Content-Type header with the type from the data format if the data format is capable of doing so. For example application/xml for data formats marshalling to XML, or application/json for data formats marshalling to JSon etc.
 |===
 // dataformat options: END
@@ -56,7 +56,7 @@ When using Spring Boot make sure to use the following Maven dependency to have s
 ----
 
 
-The component supports 10 options, which are listed below.
+The component supports 12 options, which are listed below.
 
 
 
@@ -64,10 +64,12 @@ The component supports 10 options, which are listed below.
 |===
 | Name | Description | Default | Type
 | *camel.dataformat.yaml-snakeyaml.allow-any-type* | Allow any class to be un-marshaled | false | Boolean
+| *camel.dataformat.yaml-snakeyaml.allow-recursive-keys* | Set whether recursive keys are allowed. |  | String
 | *camel.dataformat.yaml-snakeyaml.constructor* | BaseConstructor to construct incoming documents. |  | String
 | *camel.dataformat.yaml-snakeyaml.content-type-header* | Whether the data format should set the Content-Type header with the type from the data format if the data format is capable of doing so. For example application/xml for data formats marshalling to XML, or application/json for data formats marshalling to JSon etc. | false | Boolean
 | *camel.dataformat.yaml-snakeyaml.dumper-options* | DumperOptions to configure outgoing objects. |  | String
 | *camel.dataformat.yaml-snakeyaml.enabled* | Whether to enable auto configuration of the yaml-snakeyaml data format. This is enabled by default. |  | Boolean
+| *camel.dataformat.yaml-snakeyaml.max-aliases-for-collections* | Set the maximum amount of aliases allowed for collections. | 50 | String
 | *camel.dataformat.yaml-snakeyaml.pretty-flow* | Force the emitter to produce a pretty YAML document when using the flow style. | false | Boolean
 | *camel.dataformat.yaml-snakeyaml.representer* | Representer to emit outgoing objects. |  | String
 | *camel.dataformat.yaml-snakeyaml.resolver* | Resolver to detect implicit type |  | String
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/model/dataformat/YAMLDataFormat.java b/core/camel-core-engine/src/main/java/org/apache/camel/model/dataformat/YAMLDataFormat.java
index 33e86de..3c82c99 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/model/dataformat/YAMLDataFormat.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/model/dataformat/YAMLDataFormat.java
@@ -232,7 +232,7 @@ public class YAMLDataFormat extends DataFormatDefinition {
         this.maxAliasesForCollections = maxAliasesForCollections;
     }
 
-    public String isAllowRecursiveKeys() {
+    public String getAllowRecursiveKeys() {
         return allowRecursiveKeys;
     }
 
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/dataformat/YAMLDataFormatReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/dataformat/YAMLDataFormatReifier.java
index 033134a..bbb4cec 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/dataformat/YAMLDataFormatReifier.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/dataformat/YAMLDataFormatReifier.java
@@ -67,7 +67,7 @@ public class YAMLDataFormatReifier extends DataFormatReifier<YAMLDataFormat> {
         setProperty(dataFormat, camelContext, "prettyFlow", definition.isPrettyFlow());
         setProperty(dataFormat, camelContext, "allowAnyType", definition.isAllowAnyType());
         setProperty(dataFormat, camelContext, "maxAliasesForCollections", definition.getMaxAliasesForCollections());
-        setProperty(dataFormat, camelContext, "allowRecursiveKeys", definition.isAllowRecursiveKeys());
+        setProperty(dataFormat, camelContext, "allowRecursiveKeys", definition.getAllowRecursiveKeys());
 
         if (definition.getTypeFilters() != null && !definition.getTypeFilters().isEmpty()) {
             List<String> typeFilterDefinitions = new ArrayList<>(definition.getTypeFilters().size());
diff --git a/docs/components/modules/ROOT/pages/yaml-snakeyaml-dataformat.adoc b/docs/components/modules/ROOT/pages/yaml-snakeyaml-dataformat.adoc
index e566551..a18df01 100644
--- a/docs/components/modules/ROOT/pages/yaml-snakeyaml-dataformat.adoc
+++ b/docs/components/modules/ROOT/pages/yaml-snakeyaml-dataformat.adoc
@@ -19,7 +19,7 @@ SnakeYAML library.
 == YAML Options
 
 // dataformat options: START
-The YAML SnakeYAML dataformat supports 11 options, which are listed below.
+The YAML SnakeYAML dataformat supports 13 options, which are listed below.
 
 
 
@@ -36,6 +36,8 @@ The YAML SnakeYAML dataformat supports 11 options, which are listed below.
 | 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
+| maxAliasesForCollections | 50 | String | Set the maximum amount of aliases allowed for collections.
+| allowRecursiveKeys |  | String | Set whether recursive keys are allowed.
 | contentTypeHeader | false | Boolean | Whether the data format should set the Content-Type header with the type from the data format if the data format is capable of doing so. For example application/xml for data formats marshalling to XML, or application/json for data formats marshalling to JSon etc.
 |===
 // dataformat options: END
@@ -55,7 +57,7 @@ When using Spring Boot make sure to use the following Maven dependency to have s
 ----
 
 
-The component supports 10 options, which are listed below.
+The component supports 12 options, which are listed below.
 
 
 
@@ -63,10 +65,12 @@ The component supports 10 options, which are listed below.
 |===
 | Name | Description | Default | Type
 | *camel.dataformat.yaml-snakeyaml.allow-any-type* | Allow any class to be un-marshaled | false | Boolean
+| *camel.dataformat.yaml-snakeyaml.allow-recursive-keys* | Set whether recursive keys are allowed. |  | String
 | *camel.dataformat.yaml-snakeyaml.constructor* | BaseConstructor to construct incoming documents. |  | String
 | *camel.dataformat.yaml-snakeyaml.content-type-header* | Whether the data format should set the Content-Type header with the type from the data format if the data format is capable of doing so. For example application/xml for data formats marshalling to XML, or application/json for data formats marshalling to JSon etc. | false | Boolean
 | *camel.dataformat.yaml-snakeyaml.dumper-options* | DumperOptions to configure outgoing objects. |  | String
 | *camel.dataformat.yaml-snakeyaml.enabled* | Whether to enable auto configuration of the yaml-snakeyaml data format. This is enabled by default. |  | Boolean
+| *camel.dataformat.yaml-snakeyaml.max-aliases-for-collections* | Set the maximum amount of aliases allowed for collections. | 50 | String
 | *camel.dataformat.yaml-snakeyaml.pretty-flow* | Force the emitter to produce a pretty YAML document when using the flow style. | false | Boolean
 | *camel.dataformat.yaml-snakeyaml.representer* | Representer to emit outgoing objects. |  | String
 | *camel.dataformat.yaml-snakeyaml.resolver* | Resolver to detect implicit type |  | String
diff --git a/docs/user-manual/modules/ROOT/pages/aggregate-eip.adoc b/docs/user-manual/modules/ROOT/pages/aggregate-eip.adoc
index da3d2c0..12fb296 100644
--- a/docs/user-manual/modules/ROOT/pages/aggregate-eip.adoc
+++ b/docs/user-manual/modules/ROOT/pages/aggregate-eip.adoc
@@ -279,7 +279,7 @@ setting the property `Exchange.AGGREGATION_COMPLETE_ALL_GROUPS` to `true`.
 == Manually Force the Completion of All Aggregated Exchanges Immediately
 
 You can manually trigger completion of all current aggregated exchanges
-by sending a message containing the header
+by sending an exchange containing the property
 `Exchange.AGGREGATION_COMPLETE_ALL_GROUPS` set to `true`. The message is
 considered a signal message only, the message headers/contents will not
 be processed otherwise.
diff --git a/platforms/spring-boot/components-starter/camel-snakeyaml-starter/src/main/java/org/apache/camel/component/snakeyaml/springboot/SnakeYAMLDataFormatConfiguration.java b/platforms/spring-boot/components-starter/camel-snakeyaml-starter/src/main/java/org/apache/camel/component/snakeyaml/springboot/SnakeYAMLDataFormatConfiguration.java
index f5987c9..edc3565 100644
--- a/platforms/spring-boot/components-starter/camel-snakeyaml-starter/src/main/java/org/apache/camel/component/snakeyaml/springboot/SnakeYAMLDataFormatConfiguration.java
+++ b/platforms/spring-boot/components-starter/camel-snakeyaml-starter/src/main/java/org/apache/camel/component/snakeyaml/springboot/SnakeYAMLDataFormatConfiguration.java
@@ -72,11 +72,11 @@ public class SnakeYAMLDataFormatConfiguration
     /**
      * Set the maximum amount of aliases allowed for collections.
      */
-    private Integer maxAliasesForCollections = 50;
+    private String maxAliasesForCollections = "50";
     /**
      * Set whether recursive keys are allowed.
      */
-    private Boolean allowRecursiveKeys = false;
+    private String allowRecursiveKeys;
     /**
      * Whether the data format should set the Content-Type header with the type
      * from the data format if the data format is capable of doing so. For
@@ -150,19 +150,19 @@ public class SnakeYAMLDataFormatConfiguration
         this.allowAnyType = allowAnyType;
     }
 
-    public Integer getMaxAliasesForCollections() {
+    public String getMaxAliasesForCollections() {
         return maxAliasesForCollections;
     }
 
-    public void setMaxAliasesForCollections(Integer maxAliasesForCollections) {
+    public void setMaxAliasesForCollections(String maxAliasesForCollections) {
         this.maxAliasesForCollections = maxAliasesForCollections;
     }
 
-    public Boolean getAllowRecursiveKeys() {
+    public String getAllowRecursiveKeys() {
         return allowRecursiveKeys;
     }
 
-    public void setAllowRecursiveKeys(Boolean allowRecursiveKeys) {
+    public void setAllowRecursiveKeys(String allowRecursiveKeys) {
         this.allowRecursiveKeys = allowRecursiveKeys;
     }
 


[camel] 04/05: CAMEL-14532 - Fix checkstyle warnings

Posted by co...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 70afca59fbdad6be6d9f7a46487637704be3bcf0
Author: Colm O hEigeartaigh <co...@apache.org>
AuthorDate: Tue Feb 18 13:19:48 2020 +0000

    CAMEL-14532 - Fix checkstyle warnings
---
 .../custom/CustomClassLoaderConstructor.java       | 30 +++++------
 .../component/snakeyaml/custom/CustomComposer.java | 36 ++++++-------
 .../snakeyaml/custom/CustomConstructor.java        | 30 +++++------
 .../snakeyaml/custom/CustomSafeConstructor.java    | 30 +++++------
 .../camel/component/snakeyaml/custom/Yaml.java     | 62 ++++++++++++----------
 .../component/snakeyaml/SnakeYAMLDoSTest.java      |  7 ++-
 6 files changed, 98 insertions(+), 97 deletions(-)

diff --git a/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/CustomClassLoaderConstructor.java b/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/CustomClassLoaderConstructor.java
index 7efabe1..163ebdf 100644
--- a/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/CustomClassLoaderConstructor.java
+++ b/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/CustomClassLoaderConstructor.java
@@ -1,20 +1,18 @@
-/**
- * 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
+/*
+ * 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
+ *      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.
+ * 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.custom;
 
@@ -55,7 +53,7 @@ public class CustomClassLoaderConstructor extends org.yaml.snakeyaml.constructor
             Object key = constructObject(keyNode);
             if (key != null) {
                 try {
-                    key.hashCode();// check circular dependencies
+                    key.hashCode(); // check circular dependencies
                 } catch (Exception e) {
                     throw new CustomConstructorException("while constructing a mapping",
                             node.getStartMark(), "found unacceptable key " + key,
diff --git a/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/CustomComposer.java b/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/CustomComposer.java
index 74dfcc4..b97bcdf 100644
--- a/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/CustomComposer.java
+++ b/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/CustomComposer.java
@@ -1,20 +1,18 @@
-/**
- * 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
+/*
+ * 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
+ *      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.
+ * 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.custom;
 
@@ -60,7 +58,7 @@ public class CustomComposer extends Composer {
     private final Resolver resolver;
     private final Map<String, Node> anchors;
     private final Set<Node> recursiveNodes;
-    private int nonScalarAliasesCount = 0;
+    private int nonScalarAliasesCount;
     private final int maxAliasesForCollections;
 
     public CustomComposer(Parser parser, Resolver resolver) {
@@ -128,7 +126,7 @@ public class CustomComposer extends Composer {
         // Ensure that the stream contains no more documents.
         if (!parser.checkEvent(Event.ID.StreamEnd)) {
             Event event = parser.getEvent();
-            Mark contextMark = document != null ? document.getStartMark(): null;
+            Mark contextMark = document != null ? document.getStartMark() : null;
             throw new CustomComposerException("expected a single document in the stream",
                     contextMark, "but found another document", event.getStartMark());
         }
@@ -138,7 +136,9 @@ public class CustomComposer extends Composer {
     }
 
     private Node composeNode(Node parent) {
-        if (parent != null) recursiveNodes.add(parent);
+        if (parent != null) {
+            recursiveNodes.add(parent);
+        }
         final Node node;
         if (parser.checkEvent(Event.ID.Alias)) {
             AliasEvent event = (AliasEvent) parser.getEvent();
diff --git a/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/CustomConstructor.java b/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/CustomConstructor.java
index 5257742..47aa4e7 100644
--- a/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/CustomConstructor.java
+++ b/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/CustomConstructor.java
@@ -1,20 +1,18 @@
-/**
- * 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
+/*
+ * 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
+ *      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.
+ * 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.custom;
 
@@ -48,7 +46,7 @@ public class CustomConstructor extends Constructor {
             Object key = constructObject(keyNode);
             if (key != null) {
                 try {
-                    key.hashCode();// check circular dependencies
+                    key.hashCode(); // check circular dependencies
                 } catch (Exception e) {
                     throw new CustomConstructorException("while constructing a mapping",
                             node.getStartMark(), "found unacceptable key " + key,
diff --git a/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/CustomSafeConstructor.java b/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/CustomSafeConstructor.java
index d93d6c5..129718a 100644
--- a/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/CustomSafeConstructor.java
+++ b/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/CustomSafeConstructor.java
@@ -1,20 +1,18 @@
-/**
- * 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
+/*
+ * 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
+ *      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.
+ * 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.custom;
 
@@ -48,7 +46,7 @@ public class CustomSafeConstructor extends SafeConstructor {
             Object key = constructObject(keyNode);
             if (key != null) {
                 try {
-                    key.hashCode();// check circular dependencies
+                    key.hashCode(); // check circular dependencies
                 } catch (Exception e) {
                     throw new CustomConstructorException("while constructing a mapping",
                             node.getStartMark(), "found unacceptable key " + key,
diff --git a/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/Yaml.java b/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/Yaml.java
index 65ebdf8..983e730 100644
--- a/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/Yaml.java
+++ b/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/Yaml.java
@@ -1,11 +1,12 @@
-/**
- * Copyright (c) 2008, http://www.snakeyaml.org
+/*
+ * 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
  *
- * Licensed 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
+ *      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,
@@ -13,8 +14,23 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+/*
+ * Copyright (c) 2008, http://www.snakeyaml.org
+ */
 package org.apache.camel.component.snakeyaml.custom;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.regex.Pattern;
+
 import org.yaml.snakeyaml.DumperOptions;
 import org.yaml.snakeyaml.DumperOptions.FlowStyle;
 import org.yaml.snakeyaml.LoaderOptions;
@@ -36,18 +52,6 @@ import org.yaml.snakeyaml.representer.Representer;
 import org.yaml.snakeyaml.resolver.Resolver;
 import org.yaml.snakeyaml.serializer.Serializer;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.NoSuchElementException;
-import java.util.regex.Pattern;
-
 /**
  * Public YAML interface. This class is not thread-safe. Which means that all the methods of the same
  * instance can be called only by one thread.
@@ -59,11 +63,11 @@ import java.util.regex.Pattern;
  */
 public class Yaml {
     protected final Resolver resolver;
-    private String name;
     protected BaseConstructor constructor;
     protected Representer representer;
     protected DumperOptions dumperOptions;
     protected LoaderOptions loadingConfig;
+    private String name;
     private int maxAliasesForCollections = 50;
 
 
@@ -121,15 +125,6 @@ public class Yaml {
         this(constructor, representer, initDumperOptions(representer));
     }
 
-    private static DumperOptions initDumperOptions(Representer representer) {
-        DumperOptions dumperOptions = new DumperOptions();
-        dumperOptions.setDefaultFlowStyle(representer.getDefaultFlowStyle());
-        dumperOptions.setDefaultScalarStyle(representer.getDefaultScalarStyle());
-        dumperOptions.setAllowReadOnlyProperties(representer.getPropertyUtils().isAllowReadOnlyProperties());
-        dumperOptions.setTimeZone(representer.getTimeZone());
-        return dumperOptions;
-    }
-
     /**
      * Create Yaml instance. It is safe to create a few instances and use them
      * in different Threads.
@@ -222,6 +217,15 @@ public class Yaml {
         this.name = "Yaml:" + System.identityHashCode(this);
     }
 
+    private static DumperOptions initDumperOptions(Representer representer) {
+        DumperOptions dumperOptions = new DumperOptions();
+        dumperOptions.setDefaultFlowStyle(representer.getDefaultFlowStyle());
+        dumperOptions.setDefaultScalarStyle(representer.getDefaultScalarStyle());
+        dumperOptions.setAllowReadOnlyProperties(representer.getPropertyUtils().isAllowReadOnlyProperties());
+        dumperOptions.setTimeZone(representer.getTimeZone());
+        return dumperOptions;
+    }
+
     /**
      * Serialize a Java object into a YAML String.
      *
diff --git a/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLDoSTest.java b/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLDoSTest.java
index 264b3da..6df32a6 100644
--- a/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLDoSTest.java
+++ b/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLDoSTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * 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.
@@ -91,7 +91,10 @@ public class SnakeYAMLDoSTest extends CamelTestSupport {
     // Taken from SnakeYaml test code
     private String createDump(int size) {
         Map<String, Object> root = new HashMap<>();
-        Map<String, Object> s1, s2, t1, t2;
+        Map<String, Object> s1;
+        Map<String, Object> s2;
+        Map<String, Object> t1;
+        Map<String, Object> t2;
         s1 = root;
         s2 = new HashMap<>();
         /*


[camel] 01/05: CAMEL-14532 - Fix issues with camel-snakeyaml

Posted by co...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 9bb3f9ba84ed261b0e34ef2f17a74b1e4de42013
Author: Colm O hEigeartaigh <co...@apache.org>
AuthorDate: Tue Feb 18 12:31:58 2020 +0000

    CAMEL-14532 - Fix issues with camel-snakeyaml
---
 .../component/snakeyaml/SnakeYAMLDataFormat.java   |  66 +-
 .../custom/CustomClassLoaderConstructor.java       |  92 +++
 .../component/snakeyaml/custom/CustomComposer.java | 276 ++++++++
 .../snakeyaml/custom/CustomConstructor.java        |  85 +++
 .../snakeyaml/custom/CustomSafeConstructor.java    |  85 +++
 .../camel/component/snakeyaml/custom/Yaml.java     | 711 +++++++++++++++++++++
 .../component/snakeyaml/SnakeYAMLDoSTest.java      | 156 +++++
 .../src/test/resources/data-dos.yaml               |  11 +
 .../camel-snakeyaml/src/test/resources/data.yaml   |   2 +
 9 files changed, 1467 insertions(+), 17 deletions(-)

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 01bc131..3e3b598 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
@@ -33,6 +33,10 @@ import java.util.function.Function;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
+import org.apache.camel.component.snakeyaml.custom.CustomClassLoaderConstructor;
+import org.apache.camel.component.snakeyaml.custom.CustomConstructor;
+import org.apache.camel.component.snakeyaml.custom.CustomSafeConstructor;
+import org.apache.camel.component.snakeyaml.custom.Yaml;
 import org.apache.camel.spi.DataFormat;
 import org.apache.camel.spi.DataFormatName;
 import org.apache.camel.spi.annotations.Dataformat;
@@ -40,11 +44,8 @@ import org.apache.camel.support.ExchangeHelper;
 import org.apache.camel.support.service.ServiceSupport;
 import org.yaml.snakeyaml.DumperOptions;
 import org.yaml.snakeyaml.TypeDescription;
-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;
@@ -68,6 +69,9 @@ public final class SnakeYAMLDataFormat extends ServiceSupport implements DataFor
     private boolean prettyFlow;
     private boolean allowAnyType;
     private List<TypeFilter> typeFilters;
+    private int maxAliasesForCollections = 50;
+    private boolean allowRecursiveKeys;
+
 
     public SnakeYAMLDataFormat() {
         this(null);
@@ -133,7 +137,8 @@ public final class SnakeYAMLDataFormat extends ServiceSupport implements DataFor
                 this.constructor.apply(context),
                 this.representer.apply(context),
                 this.dumperOptions.apply(context),
-                this.resolver.apply(context)
+                this.resolver.apply(context),
+                maxAliasesForCollections
             );
 
             yamlCache.set(new WeakReference<>(yaml));
@@ -335,29 +340,51 @@ public final class SnakeYAMLDataFormat extends ServiceSupport implements DataFor
         this.allowAnyType = allowAnyType;
     }
 
+    public int getMaxAliasesForCollections() {
+        return maxAliasesForCollections;
+    }
+
+    /**
+     * Set the maximum amount of aliases allowed for collections.
+     */
+    public void setMaxAliasesForCollections(int maxAliasesForCollections) {
+        this.maxAliasesForCollections = maxAliasesForCollections;
+    }
+
+    public boolean isAllowRecursiveKeys() {
+        return allowRecursiveKeys;
+    }
+
+    /**
+     * Set whether recursive keys are allowed.
+     */
+    public void setAllowRecursiveKeys(boolean allowRecursiveKeys) {
+        this.allowRecursiveKeys = allowRecursiveKeys;
+    }
+
     // ***************************
     // Defaults
     // ***************************
 
     private BaseConstructor defaultConstructor(CamelContext context) {
-        ClassLoader yamlClassLoader = this.classLoader;
         Collection<TypeFilter> yamlTypeFilters = this.typeFilters;
-
-        if (yamlClassLoader == null && useApplicationContextClassLoader) {
-            yamlClassLoader = context.getApplicationContextClassLoader();
-        }
-
         if (allowAnyType) {
             yamlTypeFilters = Collections.singletonList(TypeFilters.allowAll());
         }
 
         BaseConstructor yamlConstructor;
         if (yamlTypeFilters != null) {
+            ClassLoader yamlClassLoader = this.classLoader;
+            if (yamlClassLoader == null && useApplicationContextClassLoader) {
+                yamlClassLoader = context.getApplicationContextClassLoader();
+            }
+
             yamlConstructor = yamlClassLoader != null
-                ? typeFilterConstructor(yamlClassLoader, yamlTypeFilters)
-                : typeFilterConstructor(yamlTypeFilters);
+                ? typeFilterConstructor(yamlClassLoader, yamlTypeFilters, allowRecursiveKeys)
+                : typeFilterConstructor(yamlTypeFilters, allowRecursiveKeys);
         } else {
-            yamlConstructor = new SafeConstructor();
+            yamlConstructor = new CustomSafeConstructor();
+            ((CustomSafeConstructor)yamlConstructor).setAllowRecursiveKeys(allowRecursiveKeys);
         }
 
         if (typeDescriptions != null && yamlConstructor instanceof Constructor) {
@@ -396,8 +423,8 @@ public final class SnakeYAMLDataFormat extends ServiceSupport implements DataFor
     // Constructors
     // ***************************
 
-    private static Constructor typeFilterConstructor(final Collection<TypeFilter> typeFilters) {
-        return new Constructor() {
+    private static Constructor typeFilterConstructor(final Collection<TypeFilter> typeFilters, boolean allowRecursiveKeys) {
+        CustomConstructor constructor = new CustomConstructor() {
             @Override
             protected Class<?> getClassForName(String name) throws ClassNotFoundException {
                 if (typeFilters.stream().noneMatch(f -> f.test(name))) {
@@ -407,10 +434,13 @@ public final class SnakeYAMLDataFormat extends ServiceSupport implements DataFor
                 return super.getClassForName(name);
             }
         };
+        constructor.setAllowRecursiveKeys(allowRecursiveKeys);
+        return constructor;
     }
 
-    private static Constructor typeFilterConstructor(final ClassLoader classLoader, final Collection<TypeFilter> typeFilters) {
-        return new CustomClassLoaderConstructor(classLoader) {
+    private static Constructor typeFilterConstructor(final ClassLoader classLoader, final Collection<TypeFilter> typeFilters,
+                                                     boolean allowRecursiveKeys) {
+        CustomClassLoaderConstructor constructor = new CustomClassLoaderConstructor(classLoader) {
             @Override
             protected Class<?> getClassForName(String name) throws ClassNotFoundException {
                 if (typeFilters.stream().noneMatch(f -> f.test(name))) {
@@ -420,5 +450,7 @@ public final class SnakeYAMLDataFormat extends ServiceSupport implements DataFor
                 return super.getClassForName(name);
             }
         };
+        constructor.setAllowRecursiveKeys(allowRecursiveKeys);
+        return constructor;
     }
 }
diff --git a/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/CustomClassLoaderConstructor.java b/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/CustomClassLoaderConstructor.java
new file mode 100644
index 0000000..7efabe1
--- /dev/null
+++ b/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/CustomClassLoaderConstructor.java
@@ -0,0 +1,92 @@
+/**
+ * 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.custom;
+
+import java.util.List;
+import java.util.Map;
+
+import org.yaml.snakeyaml.constructor.ConstructorException;
+import org.yaml.snakeyaml.error.Mark;
+import org.yaml.snakeyaml.error.YAMLException;
+import org.yaml.snakeyaml.nodes.MappingNode;
+import org.yaml.snakeyaml.nodes.Node;
+import org.yaml.snakeyaml.nodes.NodeTuple;
+
+/**
+ * A CustomClassLoaderConstructor which picks up the options to disallow recursive keys
+ *
+ * NOTE - If this PR gets applied then we can remove it:
+ * https://bitbucket.org/asomov/snakeyaml/pull-requests/55/allow-configuration-for-preventing-billion/diff
+ */
+public class CustomClassLoaderConstructor extends org.yaml.snakeyaml.constructor.CustomClassLoaderConstructor {
+
+    private boolean allowRecursiveKeys;
+
+    public CustomClassLoaderConstructor(ClassLoader cLoader) {
+        super(cLoader);
+    }
+
+    public CustomClassLoaderConstructor(Class<? extends Object> theRoot, ClassLoader theLoader) {
+        super(theRoot, theLoader);
+    }
+
+    @Override
+    protected void constructMapping2ndStep(MappingNode node, Map<Object, Object> mapping) {
+        List<NodeTuple> nodeValue = node.getValue();
+        for (NodeTuple tuple : nodeValue) {
+            Node keyNode = tuple.getKeyNode();
+            Node valueNode = tuple.getValueNode();
+            Object key = constructObject(keyNode);
+            if (key != null) {
+                try {
+                    key.hashCode();// check circular dependencies
+                } catch (Exception e) {
+                    throw new CustomConstructorException("while constructing a mapping",
+                            node.getStartMark(), "found unacceptable key " + key,
+                            tuple.getKeyNode().getStartMark(), e);
+                }
+            }
+            Object value = constructObject(valueNode);
+            if (keyNode.isTwoStepsConstruction()) {
+                if (allowRecursiveKeys) {
+                    postponeMapFilling(mapping, key, value);
+                } else {
+                    throw new YAMLException("Recursive key for mapping is detected but it is not configured to be allowed.");
+                }
+            } else {
+                mapping.put(key, value);
+            }
+        }
+    }
+
+    public boolean isAllowRecursiveKeys() {
+        return allowRecursiveKeys;
+    }
+
+    public void setAllowRecursiveKeys(boolean allowRecursiveKeys) {
+        this.allowRecursiveKeys = allowRecursiveKeys;
+    }
+
+    private static class CustomConstructorException extends ConstructorException {
+        public CustomConstructorException(String context, Mark contextMark, String problem,
+                                       Mark problemMark, Throwable cause) {
+            super(context, contextMark, problem, problemMark, cause);
+        }
+    }
+}
\ No newline at end of file
diff --git a/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/CustomComposer.java b/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/CustomComposer.java
new file mode 100644
index 0000000..74dfcc4
--- /dev/null
+++ b/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/CustomComposer.java
@@ -0,0 +1,276 @@
+/**
+ * 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.custom;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.yaml.snakeyaml.composer.Composer;
+import org.yaml.snakeyaml.composer.ComposerException;
+import org.yaml.snakeyaml.error.Mark;
+import org.yaml.snakeyaml.error.YAMLException;
+import org.yaml.snakeyaml.events.AliasEvent;
+import org.yaml.snakeyaml.events.Event;
+import org.yaml.snakeyaml.events.MappingStartEvent;
+import org.yaml.snakeyaml.events.NodeEvent;
+import org.yaml.snakeyaml.events.ScalarEvent;
+import org.yaml.snakeyaml.events.SequenceStartEvent;
+import org.yaml.snakeyaml.nodes.MappingNode;
+import org.yaml.snakeyaml.nodes.Node;
+import org.yaml.snakeyaml.nodes.NodeId;
+import org.yaml.snakeyaml.nodes.NodeTuple;
+import org.yaml.snakeyaml.nodes.ScalarNode;
+import org.yaml.snakeyaml.nodes.SequenceNode;
+import org.yaml.snakeyaml.nodes.Tag;
+import org.yaml.snakeyaml.parser.Parser;
+import org.yaml.snakeyaml.resolver.Resolver;
+
+/**
+ * Creates a node graph from parser events.
+ * <p>
+ * Corresponds to the 'Compose' step as described in chapter 3.1 of the
+ * <a href="http://yaml.org/spec/1.1/">YAML Specification</a>.
+ * </p>
+ *
+ * NOTE - This is a slight port of the Composer class in SnakeYaml to specify the maxAliasesForCollections
+ * and also use CustomComposer + CustomConstructor. If this PR gets applied then we can remove it:
+ * https://bitbucket.org/asomov/snakeyaml/pull-requests/55/allow-configuration-for-preventing-billion/diff
+ */
+public class CustomComposer extends Composer {
+    private final Resolver resolver;
+    private final Map<String, Node> anchors;
+    private final Set<Node> recursiveNodes;
+    private int nonScalarAliasesCount = 0;
+    private final int maxAliasesForCollections;
+
+    public CustomComposer(Parser parser, Resolver resolver) {
+        this(parser, resolver, 50);
+    }
+
+    public CustomComposer(Parser parser, Resolver resolver, int maxAliasesForCollections) {
+        super(parser, resolver);
+        this.resolver = resolver;
+        this.anchors = new HashMap<String, Node>();
+        this.recursiveNodes = new HashSet<Node>();
+        this.maxAliasesForCollections = maxAliasesForCollections;
+    }
+
+    /**
+     * Checks if further documents are available.
+     *
+     * @return <code>true</code> if there is at least one more document.
+     */
+    public boolean checkNode() {
+        // Drop the STREAM-START event.
+        if (parser.checkEvent(Event.ID.StreamStart)) {
+            parser.getEvent();
+        }
+        // If there are more documents available?
+        return !parser.checkEvent(Event.ID.StreamEnd);
+    }
+
+    /**
+     * Reads and composes the next document.
+     *
+     * @return The root node of the document or <code>null</code> if no more
+     * documents are available.
+     */
+    public Node getNode() {
+        // Drop the DOCUMENT-START event.
+        parser.getEvent();
+        // Compose the root node.
+        Node node = composeNode(null);
+        // Drop the DOCUMENT-END event.
+        parser.getEvent();
+        //clean up resources
+        this.anchors.clear();
+        this.recursiveNodes.clear();
+        return node;
+    }
+
+    /**
+     * Reads a document from a source that contains only one document.
+     * <p>
+     * If the stream contains more than one document an exception is thrown.
+     * </p>
+     *
+     * @return The root node of the document or <code>null</code> if no document
+     * is available.
+     */
+    public Node getSingleNode() {
+        // Drop the STREAM-START event.
+        parser.getEvent();
+        // Compose a document if the stream is not empty.
+        Node document = null;
+        if (!parser.checkEvent(Event.ID.StreamEnd)) {
+            document = getNode();
+        }
+        // Ensure that the stream contains no more documents.
+        if (!parser.checkEvent(Event.ID.StreamEnd)) {
+            Event event = parser.getEvent();
+            Mark contextMark = document != null ? document.getStartMark(): null;
+            throw new CustomComposerException("expected a single document in the stream",
+                    contextMark, "but found another document", event.getStartMark());
+        }
+        // Drop the STREAM-END event.
+        parser.getEvent();
+        return document;
+    }
+
+    private Node composeNode(Node parent) {
+        if (parent != null) recursiveNodes.add(parent);
+        final Node node;
+        if (parser.checkEvent(Event.ID.Alias)) {
+            AliasEvent event = (AliasEvent) parser.getEvent();
+            String anchor = event.getAnchor();
+            if (!anchors.containsKey(anchor)) {
+                throw new CustomComposerException(null, null, "found undefined alias " + anchor,
+                        event.getStartMark());
+            }
+            node = anchors.get(anchor);
+            if (!(node instanceof ScalarNode)) {
+                this.nonScalarAliasesCount++;
+                if (this.nonScalarAliasesCount > maxAliasesForCollections) {
+                    throw new YAMLException("Number of aliases for non-scalar nodes exceeds the specified max=" + maxAliasesForCollections);
+                }
+            }
+            if (recursiveNodes.remove(node)) {
+                node.setTwoStepsConstruction(true);
+            }
+        } else {
+            NodeEvent event = (NodeEvent) parser.peekEvent();
+            String anchor = event.getAnchor();
+            // the check for duplicate anchors has been removed (issue 174)
+            if (parser.checkEvent(Event.ID.Scalar)) {
+                node = composeScalarNode(anchor);
+            } else if (parser.checkEvent(Event.ID.SequenceStart)) {
+                node = composeSequenceNode(anchor);
+            } else {
+                node = composeMappingNode(anchor);
+            }
+        }
+        recursiveNodes.remove(parent);
+        return node;
+    }
+
+    protected Node composeScalarNode(String anchor) {
+        ScalarEvent ev = (ScalarEvent) parser.getEvent();
+        String tag = ev.getTag();
+        boolean resolved = false;
+        Tag nodeTag;
+        if (tag == null || tag.equals("!")) {
+            nodeTag = resolver.resolve(NodeId.scalar, ev.getValue(),
+                    ev.getImplicit().canOmitTagInPlainScalar());
+            resolved = true;
+        } else {
+            nodeTag = new Tag(tag);
+        }
+        Node node = new ScalarNode(nodeTag, resolved, ev.getValue(), ev.getStartMark(),
+                ev.getEndMark(), ev.getScalarStyle());
+        if (anchor != null) {
+            node.setAnchor(anchor);
+            anchors.put(anchor, node);
+        }
+        return node;
+    }
+
+    protected Node composeSequenceNode(String anchor) {
+        SequenceStartEvent startEvent = (SequenceStartEvent) parser.getEvent();
+        String tag = startEvent.getTag();
+        Tag nodeTag;
+        boolean resolved = false;
+        if (tag == null || tag.equals("!")) {
+            nodeTag = resolver.resolve(NodeId.sequence, null, startEvent.getImplicit());
+            resolved = true;
+        } else {
+            nodeTag = new Tag(tag);
+        }
+        final ArrayList<Node> children = new ArrayList<Node>();
+        SequenceNode node = new SequenceNode(nodeTag, resolved, children, startEvent.getStartMark(),
+                null, startEvent.getFlowStyle());
+        if (anchor != null) {
+            node.setAnchor(anchor);
+            anchors.put(anchor, node);
+        }
+        while (!parser.checkEvent(Event.ID.SequenceEnd)) {
+            children.add(composeNode(node));
+        }
+        Event endEvent = parser.getEvent();
+        node.setEndMark(endEvent.getEndMark());
+        return node;
+    }
+
+    protected Node composeMappingNode(String anchor) {
+        MappingStartEvent startEvent = (MappingStartEvent) parser.getEvent();
+        String tag = startEvent.getTag();
+        Tag nodeTag;
+        boolean resolved = false;
+        if (tag == null || tag.equals("!")) {
+            nodeTag = resolver.resolve(NodeId.mapping, null, startEvent.getImplicit());
+            resolved = true;
+        } else {
+            nodeTag = new Tag(tag);
+        }
+
+        final List<NodeTuple> children = new ArrayList<NodeTuple>();
+        MappingNode node = new MappingNode(nodeTag, resolved, children, startEvent.getStartMark(),
+                null, startEvent.getFlowStyle());
+        if (anchor != null) {
+            node.setAnchor(anchor);
+            anchors.put(anchor, node);
+        }
+        while (!parser.checkEvent(Event.ID.MappingEnd)) {
+            composeMappingChildren(children, node);
+        }
+        Event endEvent = parser.getEvent();
+        node.setEndMark(endEvent.getEndMark());
+        return node;
+    }
+
+    protected void composeMappingChildren(List<NodeTuple> children, MappingNode node) {
+        Node itemKey = composeKeyNode(node);
+        if (itemKey.getTag().equals(Tag.MERGE)) {
+            node.setMerged(true);
+        }
+        Node itemValue = composeValueNode(node);
+        children.add(new NodeTuple(itemKey, itemValue));
+    }
+
+    protected Node composeKeyNode(MappingNode node) {
+        return composeNode(node);
+    }
+
+    protected Node composeValueNode(MappingNode node) {
+        return composeNode(node);
+    }
+
+    private static class CustomComposerException extends ComposerException {
+
+        protected CustomComposerException(String context, Mark contextMark, String problem,
+                                          Mark problemMark) {
+            super(context, contextMark, problem, problemMark);
+            // TODO Auto-generated constructor stub
+        }
+
+    }
+}
diff --git a/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/CustomConstructor.java b/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/CustomConstructor.java
new file mode 100644
index 0000000..5257742
--- /dev/null
+++ b/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/CustomConstructor.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.custom;
+
+import java.util.List;
+import java.util.Map;
+
+import org.yaml.snakeyaml.constructor.Constructor;
+import org.yaml.snakeyaml.constructor.ConstructorException;
+import org.yaml.snakeyaml.error.Mark;
+import org.yaml.snakeyaml.error.YAMLException;
+import org.yaml.snakeyaml.nodes.MappingNode;
+import org.yaml.snakeyaml.nodes.Node;
+import org.yaml.snakeyaml.nodes.NodeTuple;
+
+/**
+ * A CustomConstructor which picks up the options to disallow recursive keys
+ *
+ * NOTE - If this PR gets applied then we can remove it:
+ * https://bitbucket.org/asomov/snakeyaml/pull-requests/55/allow-configuration-for-preventing-billion/diff
+ */
+public class CustomConstructor extends Constructor {
+
+    private boolean allowRecursiveKeys;
+
+    @Override
+    protected void constructMapping2ndStep(MappingNode node, Map<Object, Object> mapping) {
+        List<NodeTuple> nodeValue = node.getValue();
+        for (NodeTuple tuple : nodeValue) {
+            Node keyNode = tuple.getKeyNode();
+            Node valueNode = tuple.getValueNode();
+            Object key = constructObject(keyNode);
+            if (key != null) {
+                try {
+                    key.hashCode();// check circular dependencies
+                } catch (Exception e) {
+                    throw new CustomConstructorException("while constructing a mapping",
+                            node.getStartMark(), "found unacceptable key " + key,
+                            tuple.getKeyNode().getStartMark(), e);
+                }
+            }
+            Object value = constructObject(valueNode);
+            if (keyNode.isTwoStepsConstruction()) {
+                if (allowRecursiveKeys) {
+                    postponeMapFilling(mapping, key, value);
+                } else {
+                    throw new YAMLException("Recursive key for mapping is detected but it is not configured to be allowed.");
+                }
+            } else {
+                mapping.put(key, value);
+            }
+        }
+    }
+
+    public boolean isAllowRecursiveKeys() {
+        return allowRecursiveKeys;
+    }
+
+    public void setAllowRecursiveKeys(boolean allowRecursiveKeys) {
+        this.allowRecursiveKeys = allowRecursiveKeys;
+    }
+
+    private static class CustomConstructorException extends ConstructorException {
+        public CustomConstructorException(String context, Mark contextMark, String problem,
+                                       Mark problemMark, Throwable cause) {
+            super(context, contextMark, problem, problemMark, cause);
+        }
+    }
+}
\ No newline at end of file
diff --git a/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/CustomSafeConstructor.java b/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/CustomSafeConstructor.java
new file mode 100644
index 0000000..d93d6c5
--- /dev/null
+++ b/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/CustomSafeConstructor.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.custom;
+
+import java.util.List;
+import java.util.Map;
+
+import org.yaml.snakeyaml.constructor.ConstructorException;
+import org.yaml.snakeyaml.constructor.SafeConstructor;
+import org.yaml.snakeyaml.error.Mark;
+import org.yaml.snakeyaml.error.YAMLException;
+import org.yaml.snakeyaml.nodes.MappingNode;
+import org.yaml.snakeyaml.nodes.Node;
+import org.yaml.snakeyaml.nodes.NodeTuple;
+
+/**
+ * A CustomSafeConstructor which picks up the options to disallow recursive keys
+ *
+ * NOTE - If this PR gets applied then we can remove it:
+ * https://bitbucket.org/asomov/snakeyaml/pull-requests/55/allow-configuration-for-preventing-billion/diff
+ */
+public class CustomSafeConstructor extends SafeConstructor {
+
+    private boolean allowRecursiveKeys;
+
+    @Override
+    protected void constructMapping2ndStep(MappingNode node, Map<Object, Object> mapping) {
+        List<NodeTuple> nodeValue = node.getValue();
+        for (NodeTuple tuple : nodeValue) {
+            Node keyNode = tuple.getKeyNode();
+            Node valueNode = tuple.getValueNode();
+            Object key = constructObject(keyNode);
+            if (key != null) {
+                try {
+                    key.hashCode();// check circular dependencies
+                } catch (Exception e) {
+                    throw new CustomConstructorException("while constructing a mapping",
+                            node.getStartMark(), "found unacceptable key " + key,
+                            tuple.getKeyNode().getStartMark(), e);
+                }
+            }
+            Object value = constructObject(valueNode);
+            if (keyNode.isTwoStepsConstruction()) {
+                if (allowRecursiveKeys) {
+                    postponeMapFilling(mapping, key, value);
+                } else {
+                    throw new YAMLException("Recursive key for mapping is detected but it is not configured to be allowed.");
+                }
+            } else {
+                mapping.put(key, value);
+            }
+        }
+    }
+
+    public boolean isAllowRecursiveKeys() {
+        return allowRecursiveKeys;
+    }
+
+    public void setAllowRecursiveKeys(boolean allowRecursiveKeys) {
+        this.allowRecursiveKeys = allowRecursiveKeys;
+    }
+
+    private static class CustomConstructorException extends ConstructorException {
+        public CustomConstructorException(String context, Mark contextMark, String problem,
+                                       Mark problemMark, Throwable cause) {
+            super(context, contextMark, problem, problemMark, cause);
+        }
+    }
+}
\ No newline at end of file
diff --git a/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/Yaml.java b/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/Yaml.java
new file mode 100644
index 0000000..65ebdf8
--- /dev/null
+++ b/components/camel-snakeyaml/src/main/java/org/apache/camel/component/snakeyaml/custom/Yaml.java
@@ -0,0 +1,711 @@
+/**
+ * Copyright (c) 2008, http://www.snakeyaml.org
+ *
+ * Licensed 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.custom;
+
+import org.yaml.snakeyaml.DumperOptions;
+import org.yaml.snakeyaml.DumperOptions.FlowStyle;
+import org.yaml.snakeyaml.LoaderOptions;
+import org.yaml.snakeyaml.TypeDescription;
+import org.yaml.snakeyaml.composer.Composer;
+import org.yaml.snakeyaml.constructor.BaseConstructor;
+import org.yaml.snakeyaml.emitter.Emitable;
+import org.yaml.snakeyaml.emitter.Emitter;
+import org.yaml.snakeyaml.error.YAMLException;
+import org.yaml.snakeyaml.events.Event;
+import org.yaml.snakeyaml.introspector.BeanAccess;
+import org.yaml.snakeyaml.nodes.Node;
+import org.yaml.snakeyaml.nodes.Tag;
+import org.yaml.snakeyaml.parser.Parser;
+import org.yaml.snakeyaml.parser.ParserImpl;
+import org.yaml.snakeyaml.reader.StreamReader;
+import org.yaml.snakeyaml.reader.UnicodeReader;
+import org.yaml.snakeyaml.representer.Representer;
+import org.yaml.snakeyaml.resolver.Resolver;
+import org.yaml.snakeyaml.serializer.Serializer;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.regex.Pattern;
+
+/**
+ * Public YAML interface. This class is not thread-safe. Which means that all the methods of the same
+ * instance can be called only by one thread.
+ * It is better to create an instance for every YAML stream.
+ *
+ * NOTE - This is a slight port of the Yaml class in SnakeYaml to specify the maxAliasesForCollections
+ * and also use CustomComposer + CustomConstructor. If this PR gets applied then we can remove it:
+ * https://bitbucket.org/asomov/snakeyaml/pull-requests/55/allow-configuration-for-preventing-billion/diff
+ */
+public class Yaml {
+    protected final Resolver resolver;
+    private String name;
+    protected BaseConstructor constructor;
+    protected Representer representer;
+    protected DumperOptions dumperOptions;
+    protected LoaderOptions loadingConfig;
+    private int maxAliasesForCollections = 50;
+
+
+    /**
+     * Create Yaml instance.
+     */
+    public Yaml() {
+        this(new CustomConstructor(), new Representer(), new DumperOptions(), new LoaderOptions(),
+                new Resolver());
+    }
+
+    /**
+     * Create Yaml instance.
+     *
+     * @param dumperOptions DumperOptions to configure outgoing objects
+     */
+    public Yaml(DumperOptions dumperOptions) {
+        this(new CustomConstructor(), new Representer(dumperOptions), dumperOptions);
+    }
+
+    /**
+     * Create Yaml instance.
+     *
+     * @param loadingConfig LoadingConfig to control load behavior
+     */
+    public Yaml(LoaderOptions loadingConfig) {
+        this(new CustomConstructor(), new Representer(), new DumperOptions(), loadingConfig);
+    }
+
+    /**
+     * Create Yaml instance.
+     *
+     * @param representer Representer to emit outgoing objects
+     */
+    public Yaml(Representer representer) {
+        this(new CustomConstructor(), representer);
+    }
+
+    /**
+     * Create Yaml instance.
+     *
+     * @param constructor BaseConstructor to construct incoming documents
+     */
+    public Yaml(BaseConstructor constructor) {
+        this(constructor, new Representer());
+    }
+
+    /**
+     * Create Yaml instance.
+     *
+     * @param constructor BaseConstructor to construct incoming documents
+     * @param representer Representer to emit outgoing objects
+     */
+    public Yaml(BaseConstructor constructor, Representer representer) {
+        this(constructor, representer, initDumperOptions(representer));
+    }
+
+    private static DumperOptions initDumperOptions(Representer representer) {
+        DumperOptions dumperOptions = new DumperOptions();
+        dumperOptions.setDefaultFlowStyle(representer.getDefaultFlowStyle());
+        dumperOptions.setDefaultScalarStyle(representer.getDefaultScalarStyle());
+        dumperOptions.setAllowReadOnlyProperties(representer.getPropertyUtils().isAllowReadOnlyProperties());
+        dumperOptions.setTimeZone(representer.getTimeZone());
+        return dumperOptions;
+    }
+
+    /**
+     * Create Yaml instance. It is safe to create a few instances and use them
+     * in different Threads.
+     *
+     * @param representer   Representer to emit outgoing objects
+     * @param dumperOptions DumperOptions to configure outgoing objects
+     */
+    public Yaml(Representer representer, DumperOptions dumperOptions) {
+        this(new CustomConstructor(), representer, dumperOptions, new LoaderOptions(), new Resolver());
+    }
+
+    /**
+     * Create Yaml instance. It is safe to create a few instances and use them
+     * in different Threads.
+     *
+     * @param constructor   BaseConstructor to construct incoming documents
+     * @param representer   Representer to emit outgoing objects
+     * @param dumperOptions DumperOptions to configure outgoing objects
+     */
+    public Yaml(BaseConstructor constructor, Representer representer, DumperOptions dumperOptions) {
+        this(constructor, representer, dumperOptions, new LoaderOptions(), new Resolver());
+    }
+
+    /**
+     * Create Yaml instance. It is safe to create a few instances and use them
+     * in different Threads.
+     *
+     * @param constructor   BaseConstructor to construct incoming documents
+     * @param representer   Representer to emit outgoing objects
+     * @param dumperOptions DumperOptions to configure outgoing objects
+     * @param loadingConfig LoadingConfig to control load behavior
+     */
+    public Yaml(BaseConstructor constructor, Representer representer, DumperOptions dumperOptions,
+                LoaderOptions loadingConfig) {
+        this(constructor, representer, dumperOptions, loadingConfig, new Resolver());
+    }
+
+    /**
+     * Create Yaml instance. It is safe to create a few instances and use them
+     * in different Threads.
+     *
+     * @param constructor   BaseConstructor to construct incoming documents
+     * @param representer   Representer to emit outgoing objects
+     * @param dumperOptions DumperOptions to configure outgoing objects
+     * @param resolver      Resolver to detect implicit type
+     */
+    public Yaml(BaseConstructor constructor, Representer representer, DumperOptions dumperOptions,
+                Resolver resolver) {
+        this(constructor, representer, dumperOptions, new LoaderOptions(), resolver);
+    }
+
+    public Yaml(BaseConstructor constructor, Representer representer, DumperOptions dumperOptions,
+                Resolver resolver, int maxAliasesForCollections) {
+        this(constructor, representer, dumperOptions, new LoaderOptions(), resolver);
+        this.maxAliasesForCollections = maxAliasesForCollections;
+    }
+
+    /**
+     * Create Yaml instance. It is safe to create a few instances and use them
+     * in different Threads.
+     *
+     * @param constructor   BaseConstructor to construct incoming documents
+     * @param representer   Representer to emit outgoing objects
+     * @param dumperOptions DumperOptions to configure outgoing objects
+     * @param loadingConfig LoadingConfig to control load behavior
+     * @param resolver      Resolver to detect implicit type
+     */
+    public Yaml(BaseConstructor constructor, Representer representer, DumperOptions dumperOptions,
+                LoaderOptions loadingConfig, Resolver resolver) {
+        if (!constructor.isExplicitPropertyUtils()) {
+            constructor.setPropertyUtils(representer.getPropertyUtils());
+        } else if (!representer.isExplicitPropertyUtils()) {
+            representer.setPropertyUtils(constructor.getPropertyUtils());
+        }
+        this.constructor = constructor;
+        this.constructor.setAllowDuplicateKeys(loadingConfig.isAllowDuplicateKeys());
+        this.constructor.setWrappedToRootException(loadingConfig.isWrappedToRootException());
+        if (dumperOptions.getIndent() <= dumperOptions.getIndicatorIndent()) {
+            throw new YAMLException("Indicator indent must be smaller then indent.");
+        }
+        representer.setDefaultFlowStyle(dumperOptions.getDefaultFlowStyle());
+        representer.setDefaultScalarStyle(dumperOptions.getDefaultScalarStyle());
+        representer.getPropertyUtils()
+                .setAllowReadOnlyProperties(dumperOptions.isAllowReadOnlyProperties());
+        representer.setTimeZone(dumperOptions.getTimeZone());
+        this.representer = representer;
+        this.dumperOptions = dumperOptions;
+        this.loadingConfig = loadingConfig;
+        this.resolver = resolver;
+        this.name = "Yaml:" + System.identityHashCode(this);
+    }
+
+    /**
+     * Serialize a Java object into a YAML String.
+     *
+     * @param data Java object to be Serialized to YAML
+     * @return YAML String
+     */
+    public String dump(Object data) {
+        List<Object> list = new ArrayList<Object>(1);
+        list.add(data);
+        return dumpAll(list.iterator());
+    }
+
+    /**
+     * Produce the corresponding representation tree for a given Object.
+     *
+     * @param data instance to build the representation tree for
+     * @return representation tree
+     * @see <a href="http://yaml.org/spec/1.1/#id859333">Figure 3.1. Processing
+     * Overview</a>
+     */
+    public Node represent(Object data) {
+        return representer.represent(data);
+    }
+
+    /**
+     * Serialize a sequence of Java objects into a YAML String.
+     *
+     * @param data Iterator with Objects
+     * @return YAML String with all the objects in proper sequence
+     */
+    public String dumpAll(Iterator<? extends Object> data) {
+        StringWriter buffer = new StringWriter();
+        dumpAll(data, buffer, null);
+        return buffer.toString();
+    }
+
+    /**
+     * Serialize a Java object into a YAML stream.
+     *
+     * @param data   Java object to be serialized to YAML
+     * @param output stream to write to
+     */
+    public void dump(Object data, Writer output) {
+        List<Object> list = new ArrayList<Object>(1);
+        list.add(data);
+        dumpAll(list.iterator(), output, null);
+    }
+
+    /**
+     * Serialize a sequence of Java objects into a YAML stream.
+     *
+     * @param data   Iterator with Objects
+     * @param output stream to write to
+     */
+    public void dumpAll(Iterator<? extends Object> data, Writer output) {
+        dumpAll(data, output, null);
+    }
+
+    private void dumpAll(Iterator<? extends Object> data, Writer output, Tag rootTag) {
+        Serializer serializer = new Serializer(new Emitter(output, dumperOptions), resolver,
+                dumperOptions, rootTag);
+        try {
+            serializer.open();
+            while (data.hasNext()) {
+                Node node = representer.represent(data.next());
+                serializer.serialize(node);
+            }
+            serializer.close();
+        } catch (IOException e) {
+            throw new YAMLException(e);
+        }
+    }
+
+    /**
+     * <p>
+     * Serialize a Java object into a YAML string. Override the default root tag
+     * with <code>rootTag</code>.
+     * </p>
+     *
+     * <p>
+     * This method is similar to <code>Yaml.dump(data)</code> except that the
+     * root tag for the whole document is replaced with the given tag. This has
+     * two main uses.
+     * </p>
+     *
+     * <p>
+     * First, if the root tag is replaced with a standard YAML tag, such as
+     * <code>Tag.MAP</code>, then the object will be dumped as a map. The root
+     * tag will appear as <code>!!map</code>, or blank (implicit !!map).
+     * </p>
+     *
+     * <p>
+     * Second, if the root tag is replaced by a different custom tag, then the
+     * document appears to be a different type when loaded. For example, if an
+     * instance of MyClass is dumped with the tag !!YourClass, then it will be
+     * handled as an instance of YourClass when loaded.
+     * </p>
+     *
+     * @param data      Java object to be serialized to YAML
+     * @param rootTag   the tag for the whole YAML document. The tag should be Tag.MAP
+     *                  for a JavaBean to make the tag disappear (to use implicit tag
+     *                  !!map). If <code>null</code> is provided then the standard tag
+     *                  with the full class name is used.
+     * @param flowStyle flow style for the whole document. See Chapter 10. Collection
+     *                  Styles http://yaml.org/spec/1.1/#id930798. If
+     *                  <code>null</code> is provided then the flow style from
+     *                  DumperOptions is used.
+     * @return YAML String
+     */
+    public String dumpAs(Object data, Tag rootTag, FlowStyle flowStyle) {
+        FlowStyle oldStyle = representer.getDefaultFlowStyle();
+        if (flowStyle != null) {
+            representer.setDefaultFlowStyle(flowStyle);
+        }
+        List<Object> list = new ArrayList<Object>(1);
+        list.add(data);
+        StringWriter buffer = new StringWriter();
+        dumpAll(list.iterator(), buffer, rootTag);
+        representer.setDefaultFlowStyle(oldStyle);
+        return buffer.toString();
+    }
+
+    /**
+     * <p>
+     * Serialize a Java object into a YAML string. Override the default root tag
+     * with <code>Tag.MAP</code>.
+     * </p>
+     * <p>
+     * This method is similar to <code>Yaml.dump(data)</code> except that the
+     * root tag for the whole document is replaced with <code>Tag.MAP</code> tag
+     * (implicit !!map).
+     * </p>
+     * <p>
+     * Block Mapping is used as the collection style. See 10.2.2. Block Mappings
+     * (http://yaml.org/spec/1.1/#id934537)
+     * </p>
+     *
+     * @param data Java object to be serialized to YAML
+     * @return YAML String
+     */
+    public String dumpAsMap(Object data) {
+        return dumpAs(data, Tag.MAP, FlowStyle.BLOCK);
+    }
+
+    /**
+     * Serialize the representation tree into Events.
+     *
+     * @param data representation tree
+     * @return Event list
+     * @see <a href="http://yaml.org/spec/1.1/#id859333">Processing Overview</a>
+     */
+    public List<Event> serialize(Node data) {
+        SilentEmitter emitter = new SilentEmitter();
+        Serializer serializer = new Serializer(emitter, resolver, dumperOptions, null);
+        try {
+            serializer.open();
+            serializer.serialize(data);
+            serializer.close();
+        } catch (IOException e) {
+            throw new YAMLException(e);
+        }
+        return emitter.getEvents();
+    }
+
+    private static class SilentEmitter implements Emitable {
+        private List<Event> events = new ArrayList<Event>(100);
+
+        public List<Event> getEvents() {
+            return events;
+        }
+
+        @Override
+        public void emit(Event event) throws IOException {
+            events.add(event);
+        }
+    }
+
+    /**
+     * Parse the only YAML document in a String and produce the corresponding
+     * Java object. (Because the encoding in known BOM is not respected.)
+     *
+     * @param yaml YAML data to load from (BOM must not be present)
+     * @param <T>  the class of the instance to be created
+     * @return parsed object
+     */
+    @SuppressWarnings("unchecked")
+    public <T> T load(String yaml) {
+        return (T) loadFromReader(new StreamReader(yaml), Object.class);
+    }
+
+    /**
+     * Parse the only YAML document in a stream and produce the corresponding
+     * Java object.
+     *
+     * @param io  data to load from (BOM is respected to detect encoding and removed from the data)
+     * @param <T> the class of the instance to be created
+     * @return parsed object
+     */
+    @SuppressWarnings("unchecked")
+    public <T> T load(InputStream io) {
+        return (T) loadFromReader(new StreamReader(new UnicodeReader(io)), Object.class);
+    }
+
+    /**
+     * Parse the only YAML document in a stream and produce the corresponding
+     * Java object.
+     *
+     * @param io  data to load from (BOM must not be present)
+     * @param <T> the class of the instance to be created
+     * @return parsed object
+     */
+    @SuppressWarnings("unchecked")
+    public <T> T load(Reader io) {
+        return (T) loadFromReader(new StreamReader(io), Object.class);
+    }
+
+    /**
+     * Parse the only YAML document in a stream and produce the corresponding
+     * Java object.
+     *
+     * @param <T>  Class is defined by the second argument
+     * @param io   data to load from (BOM must not be present)
+     * @param type Class of the object to be created
+     * @return parsed object
+     */
+    @SuppressWarnings("unchecked")
+    public <T> T loadAs(Reader io, Class<T> type) {
+        return (T) loadFromReader(new StreamReader(io), type);
+    }
+
+    /**
+     * Parse the only YAML document in a String and produce the corresponding
+     * Java object. (Because the encoding in known BOM is not respected.)
+     *
+     * @param <T>  Class is defined by the second argument
+     * @param yaml YAML data to load from (BOM must not be present)
+     * @param type Class of the object to be created
+     * @return parsed object
+     */
+    @SuppressWarnings("unchecked")
+    public <T> T loadAs(String yaml, Class<T> type) {
+        return (T) loadFromReader(new StreamReader(yaml), type);
+    }
+
+    /**
+     * Parse the only YAML document in a stream and produce the corresponding
+     * Java object.
+     *
+     * @param <T>   Class is defined by the second argument
+     * @param input data to load from (BOM is respected to detect encoding and removed from the data)
+     * @param type  Class of the object to be created
+     * @return parsed object
+     */
+    @SuppressWarnings("unchecked")
+    public <T> T loadAs(InputStream input, Class<T> type) {
+        return (T) loadFromReader(new StreamReader(new UnicodeReader(input)), type);
+    }
+
+    private Object loadFromReader(StreamReader sreader, Class<?> type) {
+        Composer composer = new CustomComposer(new ParserImpl(sreader), resolver, maxAliasesForCollections);
+        constructor.setComposer(composer);
+        return constructor.getSingleData(type);
+    }
+
+    /**
+     * Parse all YAML documents in the Reader and produce corresponding Java
+     * objects. The documents are parsed only when the iterator is invoked.
+     *
+     * @param yaml YAML data to load from (BOM must not be present)
+     * @return an Iterable over the parsed Java objects in this String in proper
+     * sequence
+     */
+    public Iterable<Object> loadAll(Reader yaml) {
+        Composer composer = new CustomComposer(new ParserImpl(new StreamReader(yaml)), resolver, maxAliasesForCollections);
+        constructor.setComposer(composer);
+        Iterator<Object> result = new Iterator<Object>() {
+            @Override
+            public boolean hasNext() {
+                return constructor.checkData();
+            }
+
+            @Override
+            public Object next() {
+                return constructor.getData();
+            }
+
+            @Override
+            public void remove() {
+                throw new UnsupportedOperationException();
+            }
+        };
+        return new YamlIterable(result);
+    }
+
+    private static class YamlIterable implements Iterable<Object> {
+        private Iterator<Object> iterator;
+
+        public YamlIterable(Iterator<Object> iterator) {
+            this.iterator = iterator;
+        }
+
+        @Override
+        public Iterator<Object> iterator() {
+            return iterator;
+        }
+    }
+
+    /**
+     * Parse all YAML documents in a String and produce corresponding Java
+     * objects. (Because the encoding in known BOM is not respected.) The
+     * documents are parsed only when the iterator is invoked.
+     *
+     * @param yaml YAML data to load from (BOM must not be present)
+     * @return an Iterable over the parsed Java objects in this String in proper
+     * sequence
+     */
+    public Iterable<Object> loadAll(String yaml) {
+        return loadAll(new StringReader(yaml));
+    }
+
+    /**
+     * Parse all YAML documents in a stream and produce corresponding Java
+     * objects. The documents are parsed only when the iterator is invoked.
+     *
+     * @param yaml YAML data to load from (BOM is respected to detect encoding and removed from the data)
+     * @return an Iterable over the parsed Java objects in this stream in proper
+     * sequence
+     */
+    public Iterable<Object> loadAll(InputStream yaml) {
+        return loadAll(new UnicodeReader(yaml));
+    }
+
+    /**
+     * Parse the first YAML document in a stream and produce the corresponding
+     * representation tree. (This is the opposite of the represent() method)
+     *
+     * @param yaml YAML document
+     * @return parsed root Node for the specified YAML document
+     * @see <a href="http://yaml.org/spec/1.1/#id859333">Figure 3.1. Processing
+     * Overview</a>
+     */
+    public Node compose(Reader yaml) {
+        Composer composer = new CustomComposer(new ParserImpl(new StreamReader(yaml)), resolver, maxAliasesForCollections);
+        return composer.getSingleNode();
+    }
+
+    /**
+     * Parse all YAML documents in a stream and produce corresponding
+     * representation trees.
+     *
+     * @param yaml stream of YAML documents
+     * @return parsed root Nodes for all the specified YAML documents
+     * @see <a href="http://yaml.org/spec/1.1/#id859333">Processing Overview</a>
+     */
+    public Iterable<Node> composeAll(Reader yaml) {
+        final Composer composer = new CustomComposer(new ParserImpl(new StreamReader(yaml)), resolver, maxAliasesForCollections);
+        Iterator<Node> result = new Iterator<Node>() {
+            @Override
+            public boolean hasNext() {
+                return composer.checkNode();
+            }
+
+            @Override
+            public Node next() {
+                Node node = composer.getNode();
+                if (node != null) {
+                    return node;
+                } else {
+                    throw new NoSuchElementException("No Node is available.");
+                }
+            }
+
+            @Override
+            public void remove() {
+                throw new UnsupportedOperationException();
+            }
+        };
+        return new NodeIterable(result);
+    }
+
+    private static class NodeIterable implements Iterable<Node> {
+        private Iterator<Node> iterator;
+
+        public NodeIterable(Iterator<Node> iterator) {
+            this.iterator = iterator;
+        }
+
+        @Override
+        public Iterator<Node> iterator() {
+            return iterator;
+        }
+    }
+
+    /**
+     * Add an implicit scalar detector. If an implicit scalar value matches the
+     * given regexp, the corresponding tag is assigned to the scalar.
+     *
+     * @param tag    tag to assign to the node
+     * @param regexp regular expression to match against
+     * @param first  a sequence of possible initial characters or null (which means
+     *               any).
+     */
+    public void addImplicitResolver(Tag tag, Pattern regexp, String first) {
+        resolver.addImplicitResolver(tag, regexp, first);
+    }
+
+    @Override
+    public String toString() {
+        return name;
+    }
+
+    /**
+     * Get a meaningful name. It simplifies debugging in a multi-threaded
+     * environment. If nothing is set explicitly the address of the instance is
+     * returned.
+     *
+     * @return human readable name
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Set a meaningful name to be shown in toString()
+     *
+     * @param name human readable name
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * Parse a YAML stream and produce parsing events.
+     *
+     * @param yaml YAML document(s)
+     * @return parsed events
+     * @see <a href="http://yaml.org/spec/1.1/#id859333">Processing Overview</a>
+     */
+    public Iterable<Event> parse(Reader yaml) {
+        final Parser parser = new ParserImpl(new StreamReader(yaml));
+        Iterator<Event> result = new Iterator<Event>() {
+            @Override
+            public boolean hasNext() {
+                return parser.peekEvent() != null;
+            }
+
+            @Override
+            public Event next() {
+                Event event = parser.getEvent();
+                if (event != null) {
+                    return event;
+                } else {
+                    throw new NoSuchElementException("No Event is available.");
+                }
+            }
+
+            @Override
+            public void remove() {
+                throw new UnsupportedOperationException();
+            }
+        };
+        return new EventIterable(result);
+    }
+
+    private static class EventIterable implements Iterable<Event> {
+        private Iterator<Event> iterator;
+
+        public EventIterable(Iterator<Event> iterator) {
+            this.iterator = iterator;
+        }
+
+        @Override
+        public Iterator<Event> iterator() {
+            return iterator;
+        }
+    }
+
+    public void setBeanAccess(BeanAccess beanAccess) {
+        constructor.getPropertyUtils().setBeanAccess(beanAccess);
+        representer.getPropertyUtils().setBeanAccess(beanAccess);
+    }
+
+    public void addTypeDescription(TypeDescription td) {
+        constructor.addTypeDescription(td);
+        representer.addTypeDescription(td);
+    }
+}
diff --git a/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLDoSTest.java b/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLDoSTest.java
new file mode 100644
index 0000000..264b3da
--- /dev/null
+++ b/components/camel-snakeyaml/src/test/java/org/apache/camel/component/snakeyaml/SnakeYAMLDoSTest.java
@@ -0,0 +1,156 @@
+/**
+ * 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.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.camel.CamelExecutionException;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.component.snakeyaml.custom.Yaml;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Test;
+import org.yaml.snakeyaml.constructor.SafeConstructor;
+
+public class SnakeYAMLDoSTest extends CamelTestSupport {
+
+    @Test
+    public void testReadingDataFromFile() throws Exception {
+
+        MockEndpoint mock = context.getEndpoint("mock:reverse", MockEndpoint.class);
+        assertNotNull(mock);
+        mock.expectedMessageCount(1);
+
+        InputStream is = this.getClass().getClassLoader().getResourceAsStream("data.yaml");
+
+        ProducerTemplate template = context.createProducerTemplate();
+        String result = template.requestBody("direct:back", is, String.class);
+        assertNotNull(result);
+        assertEquals("{name=Colm, location=Dublin}", result.trim());
+
+        mock.assertIsSatisfied();
+    }
+
+    @Test
+    public void testAliasExpansion() throws Exception {
+
+        MockEndpoint mock = context.getEndpoint("mock:reverse", MockEndpoint.class);
+        assertNotNull(mock);
+        mock.expectedMessageCount(0);
+
+        InputStream is = this.getClass().getClassLoader().getResourceAsStream("data-dos.yaml");
+
+        ProducerTemplate template = context.createProducerTemplate();
+        try {
+            template.requestBody("direct:back", is, String.class);
+            fail("Failure expected on an alias expansion attack");
+        } catch (CamelExecutionException ex) {
+            Throwable cause = ex.getCause();
+            assertEquals("Number of aliases for non-scalar nodes exceeds the specified max=50", cause.getMessage());
+        }
+
+        mock.assertIsSatisfied();
+    }
+
+    @Test
+    public void testReferencesWithRecursiveKeysNotAllowedByDefault() throws Exception {
+
+        MockEndpoint mock = context.getEndpoint("mock:reverse2", MockEndpoint.class);
+        assertNotNull(mock);
+        mock.expectedMessageCount(0);
+
+        ProducerTemplate template = context.createProducerTemplate();
+        try {
+            template.requestBody("direct:back2", createDump(30), String.class);
+            fail("Failure expected on an alias expansion attack");
+        } catch (CamelExecutionException ex) {
+            Throwable cause = ex.getCause();
+            assertEquals("Recursive key for mapping is detected but it is not configured to be allowed.", cause.getMessage());
+        }
+
+        mock.assertIsSatisfied();
+    }
+
+    // Taken from SnakeYaml test code
+    private String createDump(int size) {
+        Map<String, Object> root = new HashMap<>();
+        Map<String, Object> s1, s2, t1, t2;
+        s1 = root;
+        s2 = new HashMap<>();
+        /*
+        the time to parse grows very quickly
+        SIZE -> time to parse in seconds
+        25 -> 1
+        26 -> 2
+        27 -> 3
+        28 -> 8
+        29 -> 13
+        30 -> 28
+        31 -> 52
+        32 -> 113
+        33 -> 245
+        34 -> 500
+         */
+        for (int i = 0; i < size; i++) {
+
+            t1 = new HashMap<>();
+            t2 = new HashMap<>();
+            t1.put("foo", "1");
+            t2.put("bar", "2");
+
+            s1.put("a", t1);
+            s1.put("b", t2);
+            s2.put("a", t1);
+            s2.put("b", t2);
+
+            s1 = t1;
+            s2 = t2;
+        }
+
+        // this is VERY BAD code
+        // the map has itself as a key (no idea why it may be used except of a DoS attack)
+        Map<Object, Object> f = new HashMap<>();
+        f.put(f, "a");
+        f.put("g", root);
+
+        Yaml yaml = new Yaml(new SafeConstructor());
+        return yaml.dump(f);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        SnakeYAMLDataFormat dataFormat = new SnakeYAMLDataFormat();
+        dataFormat.setMaxAliasesForCollections(150);
+
+        return new RouteBuilder() {
+
+            @Override
+            public void configure() throws Exception {
+                from("direct:back")
+                    .unmarshal(new SnakeYAMLDataFormat())
+                    .to("mock:reverse");
+
+                from("direct:back2")
+                    .unmarshal(dataFormat)
+                    .to("mock:reverse2");
+            }
+        };
+    }
+}
diff --git a/components/camel-snakeyaml/src/test/resources/data-dos.yaml b/components/camel-snakeyaml/src/test/resources/data-dos.yaml
new file mode 100644
index 0000000..6747dd2
--- /dev/null
+++ b/components/camel-snakeyaml/src/test/resources/data-dos.yaml
@@ -0,0 +1,11 @@
+a: &a ["lol","lol","lol","lol","lol","lol","lol","lol","lol"]
+b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a]
+c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b]
+d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c]
+e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d]
+f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e]
+g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f]
+h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g]
+i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h]
+name: *i
+location: "Dublin"
diff --git a/components/camel-snakeyaml/src/test/resources/data.yaml b/components/camel-snakeyaml/src/test/resources/data.yaml
new file mode 100644
index 0000000..83c60e5
--- /dev/null
+++ b/components/camel-snakeyaml/src/test/resources/data.yaml
@@ -0,0 +1,2 @@
+name: "Colm"
+location: "Dublin"


[camel] 02/05: CAMEL-14532 - Fixing up docs

Posted by co...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 1a64407d1b47a8865101060e8ed72d0b495f9323
Author: Colm O hEigeartaigh <co...@apache.org>
AuthorDate: Tue Feb 18 12:48:37 2020 +0000

    CAMEL-14532 - Fixing up docs
---
 .../src/main/docs/yaml-snakeyaml-dataformat.adoc   |  4 +++-
 .../camel/model/dataformat/YAMLDataFormat.java     | 27 ++++++++++++++++++++++
 .../reifier/dataformat/YAMLDataFormatReifier.java  |  2 ++
 .../SnakeYAMLDataFormatConfiguration.java          | 24 +++++++++++++++++++
 4 files changed, 56 insertions(+), 1 deletion(-)

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 bfe9a15..ffa0c29 100644
--- a/components/camel-snakeyaml/src/main/docs/yaml-snakeyaml-dataformat.adoc
+++ b/components/camel-snakeyaml/src/main/docs/yaml-snakeyaml-dataformat.adoc
@@ -18,7 +18,7 @@ SnakeYAML library.
 == YAML Options
 
 // dataformat options: START
-The YAML SnakeYAML dataformat supports 11 options, which are listed below.
+The YAML SnakeYAML dataformat supports 13 options, which are listed below.
 
 
 
@@ -35,6 +35,8 @@ The YAML SnakeYAML dataformat supports 11 options, which are listed below.
 | 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
+| maxAliasesForCollections | 50 | int | Set the maximum amount of aliases allowed for collections.
+| allowRecursiveKeys | false | boolean | Set whether recursive keys are allowed.
 | contentTypeHeader | false | Boolean | Whether the data format should set the Content-Type header with the type from the data format if the data format is capable of doing so. For example application/xml for data formats marshalling to XML, or application/json for data formats marshalling to JSon etc.
 |===
 // dataformat options: END
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/model/dataformat/YAMLDataFormat.java b/core/camel-core-engine/src/main/java/org/apache/camel/model/dataformat/YAMLDataFormat.java
index d1b9192..951b1a6 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/model/dataformat/YAMLDataFormat.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/model/dataformat/YAMLDataFormat.java
@@ -63,6 +63,12 @@ public class YAMLDataFormat extends DataFormatDefinition {
     private Boolean allowAnyType = false;
     @XmlElement(name = "typeFilter")
     private List<YAMLTypeFilterDefinition> typeFilters;
+    @XmlAttribute
+    @Metadata(javaType = "java.lang.Integer", defaultValue = "50")
+    private int maxAliasesForCollections = 50;
+    @XmlAttribute
+    @Metadata(javaType = "java.lang.Boolean", defaultValue = "false")
+    private boolean allowRecursiveKeys;
 
     public YAMLDataFormat() {
         this(YAMLLibrary.SnakeYAML);
@@ -215,4 +221,25 @@ public class YAMLDataFormat extends DataFormatDefinition {
         this.typeFilters = typeFilters;
     }
 
+    public int getMaxAliasesForCollections() {
+        return maxAliasesForCollections;
+    }
+
+    /**
+     * Set the maximum amount of aliases allowed for collections.
+     */
+    public void setMaxAliasesForCollections(int maxAliasesForCollections) {
+        this.maxAliasesForCollections = maxAliasesForCollections;
+    }
+
+    public boolean isAllowRecursiveKeys() {
+        return allowRecursiveKeys;
+    }
+
+    /**
+     * Set whether recursive keys are allowed.
+     */
+    public void setAllowRecursiveKeys(boolean allowRecursiveKeys) {
+        this.allowRecursiveKeys = allowRecursiveKeys;
+    }
 }
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/dataformat/YAMLDataFormatReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/dataformat/YAMLDataFormatReifier.java
index 60089e4..033134a 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/dataformat/YAMLDataFormatReifier.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/dataformat/YAMLDataFormatReifier.java
@@ -66,6 +66,8 @@ public class YAMLDataFormatReifier extends DataFormatReifier<YAMLDataFormat> {
         setProperty(dataFormat, camelContext, "useApplicationContextClassLoader", definition.isUseApplicationContextClassLoader());
         setProperty(dataFormat, camelContext, "prettyFlow", definition.isPrettyFlow());
         setProperty(dataFormat, camelContext, "allowAnyType", definition.isAllowAnyType());
+        setProperty(dataFormat, camelContext, "maxAliasesForCollections", definition.getMaxAliasesForCollections());
+        setProperty(dataFormat, camelContext, "allowRecursiveKeys", definition.isAllowRecursiveKeys());
 
         if (definition.getTypeFilters() != null && !definition.getTypeFilters().isEmpty()) {
             List<String> typeFilterDefinitions = new ArrayList<>(definition.getTypeFilters().size());
diff --git a/platforms/spring-boot/components-starter/camel-snakeyaml-starter/src/main/java/org/apache/camel/component/snakeyaml/springboot/SnakeYAMLDataFormatConfiguration.java b/platforms/spring-boot/components-starter/camel-snakeyaml-starter/src/main/java/org/apache/camel/component/snakeyaml/springboot/SnakeYAMLDataFormatConfiguration.java
index b5e946d..f5987c9 100644
--- a/platforms/spring-boot/components-starter/camel-snakeyaml-starter/src/main/java/org/apache/camel/component/snakeyaml/springboot/SnakeYAMLDataFormatConfiguration.java
+++ b/platforms/spring-boot/components-starter/camel-snakeyaml-starter/src/main/java/org/apache/camel/component/snakeyaml/springboot/SnakeYAMLDataFormatConfiguration.java
@@ -70,6 +70,14 @@ public class SnakeYAMLDataFormatConfiguration
      */
     private Boolean allowAnyType = false;
     /**
+     * Set the maximum amount of aliases allowed for collections.
+     */
+    private Integer maxAliasesForCollections = 50;
+    /**
+     * Set whether recursive keys are allowed.
+     */
+    private Boolean allowRecursiveKeys = false;
+    /**
      * Whether the data format should set the Content-Type header with the type
      * from the data format if the data format is capable of doing so. For
      * example application/xml for data formats marshalling to XML, or
@@ -142,6 +150,22 @@ public class SnakeYAMLDataFormatConfiguration
         this.allowAnyType = allowAnyType;
     }
 
+    public Integer getMaxAliasesForCollections() {
+        return maxAliasesForCollections;
+    }
+
+    public void setMaxAliasesForCollections(Integer maxAliasesForCollections) {
+        this.maxAliasesForCollections = maxAliasesForCollections;
+    }
+
+    public Boolean getAllowRecursiveKeys() {
+        return allowRecursiveKeys;
+    }
+
+    public void setAllowRecursiveKeys(Boolean allowRecursiveKeys) {
+        this.allowRecursiveKeys = allowRecursiveKeys;
+    }
+
     public Boolean getContentTypeHeader() {
         return contentTypeHeader;
     }