Skip to content

Commit c98e48a

Browse files
committed
CAMEL-10575: snakeyaml: add an option to filter classes the yaml parser can construct
(cherry picked from commit 20e2622)
1 parent 342b09e commit c98e48a

23 files changed

+1233
-98
lines changed

camel-core/src/main/java/org/apache/camel/model/dataformat/YAMLDataFormat.java

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,12 @@
1616
*/
1717
package org.apache.camel.model.dataformat;
1818

19+
import java.util.ArrayList;
20+
import java.util.List;
1921
import javax.xml.bind.annotation.XmlAccessType;
2022
import javax.xml.bind.annotation.XmlAccessorType;
2123
import javax.xml.bind.annotation.XmlAttribute;
24+
import javax.xml.bind.annotation.XmlElement;
2225
import javax.xml.bind.annotation.XmlRootElement;
2326
import javax.xml.bind.annotation.XmlTransient;
2427

@@ -58,6 +61,10 @@ public class YAMLDataFormat extends DataFormatDefinition {
5861
private Boolean useApplicationContextClassLoader = true;
5962
@XmlAttribute @Metadata(defaultValue = "false")
6063
private Boolean prettyFlow = false;
64+
@XmlAttribute @Metadata(defaultValue = "false")
65+
private Boolean allowAnyType = false;
66+
@XmlElement(name = "typeFilter")
67+
private List<YAMLTypeFilterDefinition> typeFilters;
6168

6269
public YAMLDataFormat() {
6370
this(YAMLLibrary.SnakeYAML);
@@ -188,6 +195,28 @@ public void setPrettyFlow(boolean prettyFlow) {
188195
this.prettyFlow = prettyFlow;
189196
}
190197

198+
public boolean isAllowAnyType() {
199+
return allowAnyType;
200+
}
201+
202+
/**
203+
* Allow any class to be un-marshaled
204+
*/
205+
public void setAllowAnyType(boolean allowAnyType) {
206+
this.allowAnyType = allowAnyType;
207+
}
208+
209+
public List<YAMLTypeFilterDefinition> getTypeFilters() {
210+
return typeFilters;
211+
}
212+
213+
/**
214+
* Set the types SnakeYAML is allowed to un-marshall
215+
*/
216+
public void setTypeFilters(List<YAMLTypeFilterDefinition> typeFilters) {
217+
this.typeFilters = typeFilters;
218+
}
219+
191220
@Override
192221
protected DataFormat createDataFormat(RouteContext routeContext) {
193222
if (library == YAMLLibrary.SnakeYAML) {
@@ -218,6 +247,27 @@ protected void configureSnakeDataFormat(DataFormat dataFormat, CamelContext came
218247
setProperty(dataFormat, camelContext, "classLoader", classLoader);
219248
setProperty(dataFormat, camelContext, "useApplicationContextClassLoader", useApplicationContextClassLoader);
220249
setProperty(dataFormat, camelContext, "prettyFlow", prettyFlow);
250+
setProperty(dataFormat, camelContext, "allowAnyType", allowAnyType);
251+
252+
if (typeFilters != null && !typeFilters.isEmpty()) {
253+
List<String> typeFilterDefinitions = new ArrayList<>(typeFilters.size());
254+
for (YAMLTypeFilterDefinition definition : typeFilters) {
255+
String value = definition.getValue();
256+
257+
if (!value.startsWith("type") && !value.startsWith("regexp")) {
258+
YAMLTypeFilterType type = definition.getType();
259+
if (type == null) {
260+
type = YAMLTypeFilterType.type;
261+
}
262+
263+
value = type.name() + ":" + value;
264+
}
265+
266+
typeFilterDefinitions.add(value);
267+
}
268+
269+
setProperty(dataFormat, camelContext, "typeFilterDefinitions", typeFilterDefinitions);
270+
}
221271

222272
setPropertyRef(dataFormat, camelContext, "constructor", constructor);
223273
setPropertyRef(dataFormat, camelContext, "representer", representer);
@@ -238,4 +288,5 @@ protected void setPropertyRef(DataFormat dataFormat, CamelContext camelContext,
238288
setProperty(camelContext, dataFormat, propertyName, ref);
239289
}
240290
}
291+
241292
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.camel.model.dataformat;
18+
19+
import javax.xml.bind.annotation.XmlAccessType;
20+
import javax.xml.bind.annotation.XmlAccessorType;
21+
import javax.xml.bind.annotation.XmlAttribute;
22+
import javax.xml.bind.annotation.XmlRootElement;
23+
24+
@XmlRootElement(name = "typeFilter")
25+
@XmlAccessorType(XmlAccessType.FIELD)
26+
public final class YAMLTypeFilterDefinition {
27+
@XmlAttribute
28+
private String value;
29+
@XmlAttribute
30+
private YAMLTypeFilterType type;
31+
32+
public String getValue() {
33+
return value;
34+
}
35+
36+
public void setValue(String value) {
37+
this.value = value;
38+
}
39+
40+
public YAMLTypeFilterType getType() {
41+
return type;
42+
}
43+
44+
public void setType(YAMLTypeFilterType type) {
45+
this.type = type;
46+
}
47+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.camel.model.dataformat;
19+
20+
import javax.xml.bind.annotation.XmlEnum;
21+
22+
@XmlEnum
23+
public enum YAMLTypeFilterType {
24+
type,
25+
regexp
26+
}

components/camel-snakeyaml/pom.xml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,17 @@
4545
<artifactId>snakeyaml</artifactId>
4646
<version>${snakeyaml-version}</version>
4747
</dependency>
48-
4948
<!-- testing -->
5049
<dependency>
5150
<groupId>org.apache.camel</groupId>
5251
<artifactId>camel-test-spring</artifactId>
5352
<scope>test</scope>
5453
</dependency>
54+
<dependency>
55+
<groupId>org.apache.camel</groupId>
56+
<artifactId>camel-test-blueprint</artifactId>
57+
<scope>test</scope>
58+
</dependency>
5559
<dependency>
5660
<groupId>org.slf4j</groupId>
5761
<artifactId>slf4j-log4j12</artifactId>

components/camel-snakeyaml/src/main/docs/hessian.adoc

Lines changed: 0 additions & 42 deletions
This file was deleted.
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
[[YAMLDataFormat-YAML]]
2+
YAML
3+
~~~~
4+
5+
YAML is a link:data-format.html[Data Format] to marshal and unmarshal
6+
Java objects to and from http://www.yaml.org/[YAML].
7+
8+
For YAML to object marshalling, Camel provides integration with three
9+
popular YAML libraries:
10+
11+
* The http://www.snakeyaml.org/[SnakeYAML] library
12+
13+
Every library requires adding the special camel component (see
14+
"Dependency..." paragraphs further down). By default Camel uses the
15+
SnakeYAML library.
16+
17+
[[YAML-Options]]
18+
YAML Options
19+
^^^^^^^^^^^^
20+
21+
// dataformat options: START
22+
The YAML SnakeYAML dataformat supports 10 options which are listed below.
23+
24+
25+
26+
{% raw %}
27+
[width="100%",cols="2s,1m,1m,6",options="header"]
28+
|=======================================================================
29+
| Name | Default | Java Type | Description
30+
| library | SnakeYAML | YAMLLibrary | Which yaml library to use such. Is by default SnakeYAML
31+
| unmarshalTypeName | | String | Class name of the java type to use when unarmshalling
32+
| constructor | | String | BaseConstructor to construct incoming documents.
33+
| representer | | String | Representer to emit outgoing objects.
34+
| dumperOptions | | String | DumperOptions to configure outgoing objects.
35+
| resolver | | String | Resolver to detect implicit type
36+
| useApplicationContextClassLoader | true | Boolean | Use ApplicationContextClassLoader as custom ClassLoader
37+
| prettyFlow | false | Boolean | Force the emitter to produce a pretty YAML document when using the flow style.
38+
| allowAnyType | false | Boolean | Allow any class to be un-marshaled
39+
| typeFilter | | List | Set the types SnakeYAML is allowed to un-marshall
40+
|=======================================================================
41+
{% endraw %}
42+
// dataformat options: END
43+
44+
WARNING: SnakeYAML can load any class from YAML definition which may lead to security breach so by default, SnakeYAML DataForma restrict the object it can load to standard Java objects like List or Long. If you want to load custom POJOs you need to add theirs type to SnakeYAML DataFormat type filter list. If your source is trusted, you can set the property allowAnyType to true so SnakeYAML DataForma won't perform any filter on the types.
45+
46+
[[YAMLDataFormat-UsingYAMLdataformatwiththeSnakeYAMLlibrary]]
47+
Using YAML data format with the SnakeYAML library
48+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
49+
50+
- Turn Object messages into yaml then send to MQSeries
51+
+
52+
[source,java]
53+
------------------------------------------------------------
54+
from("activemq:My.Queue")
55+
.marshal().yaml()
56+
.to("mqseries:Another.Queue");
57+
------------------------------------------------------------
58+
+
59+
[source,java]
60+
------------------------------------------------------------
61+
from("activemq:My.Queue")
62+
.marshal().yaml(YAMLLibrary.SnakeYAML)
63+
.to("mqseries:Another.Queue");
64+
------------------------------------------------------------
65+
66+
- Restrict classes to be loaded from YAML
67+
+
68+
[source,java]
69+
------------------------------------------------------------
70+
// Creat a SnakeYAMLDataFormat instance
71+
SnakeYAMLDataFormat yaml = new SnakeYAMLDataFormat();
72+
73+
// Restrict classes to be loaded from YAML
74+
yaml.addTypeFilters(TypeFilters.types(MyPojo.class, MyOtherPojo.class));
75+
76+
from("activemq:My.Queue")
77+
.unmarshal(yaml)
78+
.to("mqseries:Another.Queue");
79+
------------------------------------------------------------
80+
81+
[[YAMLDataFormat-UsingYAMLinSpringDSL]]
82+
Using YAML in Spring DSL
83+
^^^^^^^^^^^^^^^^^^^^^^^^
84+
85+
When using link:data-format.html[Data Format] in Spring DSL you need to
86+
declare the data formats first. This is done in the *DataFormats* XML
87+
tag.
88+
89+
[source,xml]
90+
--------------------------------------------------------------------------------
91+
<dataFormats>
92+
<!--
93+
here we define a YAML data format with the id snake and that it should use
94+
the TestPojo as the class type when doing unmarshal. The unmarshalTypeName
95+
is optional
96+
-->
97+
<yaml
98+
id="snake"
99+
library="SnakeYAML"
100+
unmarshalTypeName="org.apache.camel.component.yaml.model.TestPojo"/>
101+
102+
<!--
103+
here we define a YAML data format with the id snake-safe which restricts the
104+
classes to be loaded from YAML to TestPojo and those belonging to package
105+
com.mycompany
106+
-->
107+
<yaml id="snake-safe">
108+
<typeFilter value="org.apache.camel.component.yaml.model.TestPojo"/>
109+
<typeFilter value="com.mycompany\..*" type="regexp"/>
110+
</yaml>
111+
</dataFormats>
112+
--------------------------------------------------------------------------------
113+
114+
And then you can refer to those ids in the route:
115+
116+
[source,xml]
117+
-------------------------------------
118+
<route>
119+
<from uri="direct:unmarshal"/>
120+
<unmarshal>
121+
<custom ref="snake"/>
122+
</unmarshal>
123+
<to uri="mock:unmarshal"/>
124+
</route>
125+
<route>
126+
<from uri="direct:unmarshal-safe"/>
127+
<unmarshal>
128+
<custom ref="snake-safe"/>
129+
</unmarshal>
130+
<to uri="mock:unmarshal-safe"/>
131+
</route>
132+
-------------------------------------
133+
134+
135+
[[YAMLDataFormat-DependenciesforSnakeYAML]]
136+
Dependencies for SnakeYAML
137+
^^^^^^^^^^^^^^^^^^^^^^^^^^
138+
139+
To use YAML in your camel routes you need to add the a dependency
140+
on *camel-snakeyaml* which implements this data format.
141+
142+
If you use maven you could just add the following to your pom.xml,
143+
substituting the version number for the latest & greatest release
144+
(see link:download.html[the download page for the latest versions]).
145+
146+
[source,xml]
147+
------------------------------------------
148+
<dependency>
149+
<groupId>org.apache.camel</groupId>
150+
<artifactId>camel-snakeyaml</artifactId>
151+
<version>${camel-version}</version>
152+
</dependency>
153+
------------------------------------------
154+
155+
 
156+
157+
 

0 commit comments

Comments
 (0)