Skip to content

Commit

Permalink
CAMEL-19130: Upgrade to snakeyaml 2.x
Browse files Browse the repository at this point in the history
In order to get the latest improvements and bug fixes, we need to upgrade to snakeyaml 2.

* Updated the version of snakeyaml
* Upgared `camel-snakeyaml` and `camel-restdsl-openapi-plugin`
* Fixed some violations raised
  • Loading branch information
essobedo committed Jun 20, 2023
1 parent e9f2b88 commit e8a39b7
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 33 deletions.
2 changes: 1 addition & 1 deletion camel-dependencies/pom.xml
Expand Up @@ -507,7 +507,7 @@
<smallrye-health-version>3.3.0</smallrye-health-version>
<smallrye-metrics-version>3.0.5</smallrye-metrics-version>
<snakeyaml-engine-version>2.3</snakeyaml-engine-version>
<snakeyaml-version>1.33</snakeyaml-version>
<snakeyaml-version>2.0</snakeyaml-version>
<snmp4j-version>2.6.3_1</snmp4j-version>
<solr-version>8.11.2</solr-version>
<solr-version-range>[8,9)</solr-version-range>
Expand Down
Expand Up @@ -16,7 +16,7 @@
"modelJavaType": "org.apache.camel.model.dataformat.YAMLDataFormat"
},
"properties": {
"library": { "kind": "attribute", "displayName": "Library", "required": false, "type": "enum", "javaType": "org.apache.camel.model.dataformat.YAMLLibrary", "enum": [ "SnakeYAML" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "SnakeYAML", "description": "Which yaml library to use. By default it is SnakeYAML" },
"library": { "kind": "attribute", "displayName": "Library", "required": false, "type": "enum", "javaType": "org.apache.camel.model.dataformat.YAMLLibrary", "enum": [ "snake-yaml" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "SnakeYAML", "description": "Which yaml library to use. By default it is SnakeYAML" },
"unmarshalType": { "kind": "attribute", "displayName": "Unmarshal Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Class name of the java type to use when unmarshalling" },
"constructor": { "kind": "attribute", "displayName": "Constructor", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "BaseConstructor to construct incoming documents." },
"representer": { "kind": "attribute", "displayName": "Representer", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Representer to emit outgoing objects." },
Expand Down
Expand Up @@ -47,6 +47,7 @@
import org.yaml.snakeyaml.constructor.BaseConstructor;
import org.yaml.snakeyaml.constructor.Constructor;
import org.yaml.snakeyaml.constructor.SafeConstructor;
import org.yaml.snakeyaml.inspector.TrustedTagInspector;
import org.yaml.snakeyaml.nodes.Tag;
import org.yaml.snakeyaml.representer.Representer;
import org.yaml.snakeyaml.resolver.Resolver;
Expand Down Expand Up @@ -142,6 +143,7 @@ protected Yaml getYaml(CamelContext context) {

if (yaml == null) {
LoaderOptions options = new LoaderOptions();
options.setTagInspector(new TrustedTagInspector());
options.setAllowRecursiveKeys(allowRecursiveKeys);
options.setMaxAliasesForCollections(maxAliasesForCollections);

Expand Down Expand Up @@ -389,6 +391,7 @@ private BaseConstructor defaultConstructor(CamelContext context) {
}

LoaderOptions options = new LoaderOptions();
options.setTagInspector(new TrustedTagInspector());
options.setAllowRecursiveKeys(allowRecursiveKeys);
options.setMaxAliasesForCollections(maxAliasesForCollections);

Expand Down Expand Up @@ -416,7 +419,7 @@ private BaseConstructor defaultConstructor(CamelContext context) {
}

private Representer defaultRepresenter(CamelContext context) {
Representer yamlRepresenter = new Representer();
Representer yamlRepresenter = new Representer(new DumperOptions());

if (classTags != null) {
for (Map.Entry<Class<?>, Tag> entry : classTags.entrySet()) {
Expand All @@ -443,7 +446,7 @@ private Resolver defaultResolver(CamelContext context) {
// ***************************

private static Constructor typeFilterConstructor(final Collection<TypeFilter> typeFilters, LoaderOptions options) {
Constructor constructor = new Constructor(options) {
return new Constructor(options) {
@Override
protected Class<?> getClassForName(String name) throws ClassNotFoundException {
if (typeFilters.stream().noneMatch(f -> f.test(name))) {
Expand All @@ -453,13 +456,12 @@ protected Class<?> getClassForName(String name) throws ClassNotFoundException {
return super.getClassForName(name);
}
};
return constructor;
}

private static Constructor typeFilterConstructor(
final ClassLoader classLoader, final Collection<TypeFilter> typeFilters,
LoaderOptions options) {
CustomClassLoaderConstructor constructor = new CustomClassLoaderConstructor(classLoader, options) {
return new CustomClassLoaderConstructor(classLoader, options) {
@Override
protected Class<?> getClassForName(String name) throws ClassNotFoundException {
if (typeFilters.stream().noneMatch(f -> f.test(name))) {
Expand All @@ -469,6 +471,5 @@ protected Class<?> getClassForName(String name) throws ClassNotFoundException {
return super.getClassForName(name);
}
};
return constructor;
}
}
Expand Up @@ -16,6 +16,8 @@
*/
package org.apache.camel.component.snakeyaml.custom;

import java.util.Objects;

import org.yaml.snakeyaml.LoaderOptions;
import org.yaml.snakeyaml.constructor.Constructor;

Expand All @@ -24,14 +26,11 @@
*/
public class CustomClassLoaderConstructor extends Constructor {

private ClassLoader loader = this.getClass().getClassLoader();
private final ClassLoader loader;

public CustomClassLoaderConstructor(ClassLoader theLoader, LoaderOptions options) {
super(Object.class, options);
if (theLoader == null) {
throw new NullPointerException("Loader must be provided.");
}
this.loader = theLoader;
this.loader = Objects.requireNonNull(theLoader, "Loader must be provided.");
}

@Override
Expand Down
Expand Up @@ -26,6 +26,7 @@
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.test.junit5.CamelTestSupport;
import org.junit.jupiter.api.Test;
import org.yaml.snakeyaml.LoaderOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.SafeConstructor;

Expand All @@ -42,14 +43,15 @@ public void testReadingDataFromFile() throws Exception {
assertNotNull(mock);
mock.expectedMessageCount(1);

InputStream is = this.getClass().getClassLoader().getResourceAsStream("data.yaml");
try (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());
ProducerTemplate template = context.createProducerTemplate();
String result = template.requestBody("direct:back", is, String.class);
assertNotNull(result);
assertEquals("{name=Colm, location=Dublin}", result.trim());

mock.assertIsSatisfied();
mock.assertIsSatisfied();
}
}

@Test
Expand All @@ -59,18 +61,19 @@ public void testAliasExpansion() throws Exception {
assertNotNull(mock);
mock.expectedMessageCount(0);

InputStream is = this.getClass().getClassLoader().getResourceAsStream("data-dos.yaml");
try (InputStream is = this.getClass().getClassLoader().getResourceAsStream("data-dos.yaml")) {

ProducerTemplate template = context.createProducerTemplate();
ProducerTemplate template = context.createProducerTemplate();

Exception ex = assertThrows(CamelExecutionException.class,
() -> template.requestBody("direct:back", is, String.class),
"Failure expected on an alias expansion attack");
Exception ex = assertThrows(CamelExecutionException.class,
() -> template.requestBody("direct:back", is, String.class),
"Failure expected on an alias expansion attack");

Throwable cause = ex.getCause();
assertEquals("Number of aliases for non-scalar nodes exceeds the specified max=50", cause.getMessage());
Throwable cause = ex.getCause();
assertEquals("Number of aliases for non-scalar nodes exceeds the specified max=50", cause.getMessage());

mock.assertIsSatisfied();
mock.assertIsSatisfied();
}
}

@Test
Expand Down Expand Up @@ -139,7 +142,7 @@ private String createDump(int size) {
f.put(f, "a");
f.put("g", root);

Yaml yaml = new Yaml(new SafeConstructor());
Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions()));
return yaml.dump(f);
}

Expand Down
2 changes: 1 addition & 1 deletion parent/pom.xml
Expand Up @@ -493,7 +493,7 @@
<smallrye-metrics-version>3.0.5</smallrye-metrics-version>
<smallrye-health-version>3.3.0</smallrye-health-version>
<smallrye-fault-tolerance-version>5.6.0</smallrye-fault-tolerance-version>
<snakeyaml-version>1.33</snakeyaml-version>
<snakeyaml-version>2.0</snakeyaml-version>
<snakeyaml-engine-version>2.3</snakeyaml-engine-version>
<snmp4j-version>2.6.3_1</snmp4j-version>
<!-- solr version aligned with lucene -->
Expand Down
Expand Up @@ -21,6 +21,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
Expand Down Expand Up @@ -56,8 +57,10 @@
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.twdata.maven.mojoexecutor.MojoExecutor;
import org.yaml.snakeyaml.LoaderOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.SafeConstructor;
import org.yaml.snakeyaml.inspector.TrustedTagInspector;

import static org.apache.commons.lang3.StringUtils.isNotEmpty;
import static org.twdata.maven.mojoexecutor.MojoExecutor.artifactId;
Expand Down Expand Up @@ -172,8 +175,8 @@ DestinationGenerator createDestinationGenerator() throws MojoExecutionException

final DestinationGenerator destinationGeneratorObject;
try {
destinationGeneratorObject = destinationGeneratorClass.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
destinationGeneratorObject = destinationGeneratorClass.getDeclaredConstructor().newInstance();
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
throw new MojoExecutionException(
"The given destinationGenerator class (" + destinationGenerator
+ ") cannot be instantiated, make sure that it is declared as public and that all dependencies are present on the COMPILE classpath scope of the project",
Expand Down Expand Up @@ -226,7 +229,7 @@ void generateDto(final String language) throws MojoExecutionException {
version(swaggerCodegenMavenPluginVersion)),
goal("generate"),
configuration(
elements.toArray(new MojoExecutor.Element[elements.size()])),
elements.toArray(new MojoExecutor.Element[0])),
executionEnvironment(
mavenProject,
mavenSession,
Expand All @@ -243,7 +246,7 @@ protected String detectRestComponentFromClasspath() {
for (final Dependency dep : mavenProject.getDependencies()) {
if ("org.apache.camel".equals(dep.getGroupId()) || "org.apache.camel.springboot".equals(dep.getGroupId())) {
final String aid = dep.getArtifactId();
final Optional<String> comp = Arrays.asList(DEFAULT_REST_CONSUMER_COMPONENTS).stream()
final Optional<String> comp = Arrays.stream(DEFAULT_REST_CONSUMER_COMPONENTS)
.filter(c -> aid.startsWith("camel-" + c)).findFirst();
if (comp.isPresent()) {
return comp.get();
Expand Down Expand Up @@ -340,7 +343,9 @@ OasDocument readOpenApiDoc(String specificationUri) throws Exception {

String suffix = ".yaml";
if (specificationUri.regionMatches(true, specificationUri.length() - suffix.length(), suffix, 0, suffix.length())) {
Yaml loader = new Yaml(new SafeConstructor());
LoaderOptions options = new LoaderOptions();
options.setTagInspector(new TrustedTagInspector());
Yaml loader = new Yaml(new SafeConstructor(options));
Map map = loader.load(is);
JsonNode node = mapper.convertValue(map, JsonNode.class);
return (OasDocument) Library.readDocument(node);
Expand Down

0 comments on commit e8a39b7

Please sign in to comment.