Skip to content

Commit

Permalink
CAMEL-10575: snakeyaml: add an option to filter classes the yaml pars…
Browse files Browse the repository at this point in the history
…er can construct

(cherry picked from commit 20e2622)
  • Loading branch information
lburgazzoli committed Dec 9, 2016
1 parent 342b09e commit c98e48a
Show file tree
Hide file tree
Showing 23 changed files with 1,233 additions and 98 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@
*/
package org.apache.camel.model.dataformat;

import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

Expand Down Expand Up @@ -58,6 +61,10 @@ public class YAMLDataFormat extends DataFormatDefinition {
private Boolean useApplicationContextClassLoader = true;
@XmlAttribute @Metadata(defaultValue = "false")
private Boolean prettyFlow = false;
@XmlAttribute @Metadata(defaultValue = "false")
private Boolean allowAnyType = false;
@XmlElement(name = "typeFilter")
private List<YAMLTypeFilterDefinition> typeFilters;

public YAMLDataFormat() {
this(YAMLLibrary.SnakeYAML);
Expand Down Expand Up @@ -188,6 +195,28 @@ public void setPrettyFlow(boolean prettyFlow) {
this.prettyFlow = prettyFlow;
}

public boolean isAllowAnyType() {
return allowAnyType;
}

/**
* Allow any class to be un-marshaled
*/
public void setAllowAnyType(boolean allowAnyType) {
this.allowAnyType = allowAnyType;
}

public List<YAMLTypeFilterDefinition> getTypeFilters() {
return typeFilters;
}

/**
* Set the types SnakeYAML is allowed to un-marshall
*/
public void setTypeFilters(List<YAMLTypeFilterDefinition> typeFilters) {
this.typeFilters = typeFilters;
}

@Override
protected DataFormat createDataFormat(RouteContext routeContext) {
if (library == YAMLLibrary.SnakeYAML) {
Expand Down Expand Up @@ -218,6 +247,27 @@ protected void configureSnakeDataFormat(DataFormat dataFormat, CamelContext came
setProperty(dataFormat, camelContext, "classLoader", classLoader);
setProperty(dataFormat, camelContext, "useApplicationContextClassLoader", useApplicationContextClassLoader);
setProperty(dataFormat, camelContext, "prettyFlow", prettyFlow);
setProperty(dataFormat, camelContext, "allowAnyType", allowAnyType);

if (typeFilters != null && !typeFilters.isEmpty()) {
List<String> typeFilterDefinitions = new ArrayList<>(typeFilters.size());
for (YAMLTypeFilterDefinition definition : typeFilters) {
String value = definition.getValue();

if (!value.startsWith("type") && !value.startsWith("regexp")) {
YAMLTypeFilterType type = definition.getType();
if (type == null) {
type = YAMLTypeFilterType.type;
}

value = type.name() + ":" + value;
}

typeFilterDefinitions.add(value);
}

setProperty(dataFormat, camelContext, "typeFilterDefinitions", typeFilterDefinitions);
}

setPropertyRef(dataFormat, camelContext, "constructor", constructor);
setPropertyRef(dataFormat, camelContext, "representer", representer);
Expand All @@ -238,4 +288,5 @@ protected void setPropertyRef(DataFormat dataFormat, CamelContext camelContext,
setProperty(camelContext, dataFormat, propertyName, ref);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.model.dataformat;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "typeFilter")
@XmlAccessorType(XmlAccessType.FIELD)
public final class YAMLTypeFilterDefinition {
@XmlAttribute
private String value;
@XmlAttribute
private YAMLTypeFilterType type;

public String getValue() {
return value;
}

public void setValue(String value) {
this.value = value;
}

public YAMLTypeFilterType getType() {
return type;
}

public void setType(YAMLTypeFilterType type) {
this.type = type;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.camel.model.dataformat;

import javax.xml.bind.annotation.XmlEnum;

@XmlEnum
public enum YAMLTypeFilterType {
type,
regexp
}
6 changes: 5 additions & 1 deletion components/camel-snakeyaml/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,17 @@
<artifactId>snakeyaml</artifactId>
<version>${snakeyaml-version}</version>
</dependency>

<!-- testing -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-test-spring</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-test-blueprint</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
Expand Down
42 changes: 0 additions & 42 deletions components/camel-snakeyaml/src/main/docs/hessian.adoc

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
[[YAMLDataFormat-YAML]]
YAML
~~~~

YAML is a link:data-format.html[Data Format] to marshal and unmarshal
Java objects to and from http://www.yaml.org/[YAML].

For YAML to object marshalling, Camel provides integration with three
popular YAML libraries:

* The http://www.snakeyaml.org/[SnakeYAML] library
Every library requires adding the special camel component (see
"Dependency..." paragraphs further down). By default Camel uses the
SnakeYAML library.

[[YAML-Options]]
YAML Options
^^^^^^^^^^^^

// dataformat options: START
The YAML SnakeYAML dataformat supports 10 options which are listed below.



{% raw %}
[width="100%",cols="2s,1m,1m,6",options="header"]
|=======================================================================
| Name | Default | Java Type | Description
| library | SnakeYAML | YAMLLibrary | Which yaml library to use such. Is by default SnakeYAML
| unmarshalTypeName | | String | Class name of the java type to use when unarmshalling
| constructor | | String | BaseConstructor to construct incoming documents.
| representer | | String | Representer to emit outgoing objects.
| dumperOptions | | String | DumperOptions to configure outgoing objects.
| resolver | | String | Resolver to detect implicit type
| useApplicationContextClassLoader | true | Boolean | Use ApplicationContextClassLoader as custom ClassLoader
| prettyFlow | false | Boolean | Force the emitter to produce a pretty YAML document when using the flow style.
| allowAnyType | false | Boolean | Allow any class to be un-marshaled
| typeFilter | | List | Set the types SnakeYAML is allowed to un-marshall
|=======================================================================
{% endraw %}
// dataformat options: END

WARNING: SnakeYAML can load any class from YAML definition which may lead to security breach so by default, SnakeYAML DataForma restrict the object it can load to standard Java objects like List or Long. If you want to load custom POJOs you need to add theirs type to SnakeYAML DataFormat type filter list. If your source is trusted, you can set the property allowAnyType to true so SnakeYAML DataForma won't perform any filter on the types.

[[YAMLDataFormat-UsingYAMLdataformatwiththeSnakeYAMLlibrary]]
Using YAML data format with the SnakeYAML library
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

- Turn Object messages into yaml then send to MQSeries
+
[source,java]
------------------------------------------------------------
from("activemq:My.Queue")
.marshal().yaml()
.to("mqseries:Another.Queue");
------------------------------------------------------------
+
[source,java]
------------------------------------------------------------
from("activemq:My.Queue")
.marshal().yaml(YAMLLibrary.SnakeYAML)
.to("mqseries:Another.Queue");
------------------------------------------------------------
- Restrict classes to be loaded from YAML
+
[source,java]
------------------------------------------------------------
// Creat a SnakeYAMLDataFormat instance
SnakeYAMLDataFormat yaml = new SnakeYAMLDataFormat();
// Restrict classes to be loaded from YAML
yaml.addTypeFilters(TypeFilters.types(MyPojo.class, MyOtherPojo.class));

from("activemq:My.Queue")
.unmarshal(yaml)
.to("mqseries:Another.Queue");
------------------------------------------------------------

[[YAMLDataFormat-UsingYAMLinSpringDSL]]
Using YAML in Spring DSL
^^^^^^^^^^^^^^^^^^^^^^^^

When using link:data-format.html[Data Format] in Spring DSL you need to
declare the data formats first. This is done in the *DataFormats* XML
tag.

[source,xml]
--------------------------------------------------------------------------------
<dataFormats>
<!--
here we define a YAML data format with the id snake and that it should use
the TestPojo as the class type when doing unmarshal. The unmarshalTypeName
is optional
-->
<yaml
id="snake"
library="SnakeYAML"
unmarshalTypeName="org.apache.camel.component.yaml.model.TestPojo"/>
<!--
here we define a YAML data format with the id snake-safe which restricts the
classes to be loaded from YAML to TestPojo and those belonging to package
com.mycompany
-->
<yaml id="snake-safe">
<typeFilter value="org.apache.camel.component.yaml.model.TestPojo"/>
<typeFilter value="com.mycompany\..*" type="regexp"/>
</yaml>
</dataFormats>
--------------------------------------------------------------------------------

And then you can refer to those ids in the route:

[source,xml]
-------------------------------------
<route>
<from uri="direct:unmarshal"/>
<unmarshal>
<custom ref="snake"/>
</unmarshal>
<to uri="mock:unmarshal"/>
</route>
<route>
<from uri="direct:unmarshal-safe"/>
<unmarshal>
<custom ref="snake-safe"/>
</unmarshal>
<to uri="mock:unmarshal-safe"/>
</route>
-------------------------------------


[[YAMLDataFormat-DependenciesforSnakeYAML]]
Dependencies for SnakeYAML
^^^^^^^^^^^^^^^^^^^^^^^^^^

To use YAML in your camel routes you need to add the a dependency
on *camel-snakeyaml* which implements this data format.

If you use maven you could just add the following to your pom.xml,
substituting the version number for the latest & greatest release
(see link:download.html[the download page for the latest versions]).

[source,xml]
------------------------------------------
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-snakeyaml</artifactId>
<version>${camel-version}</version>
</dependency>
------------------------------------------




Loading

0 comments on commit c98e48a

Please sign in to comment.