This is an automated email from the ASF dual-hosted git repository. lburgazzoli pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel.git
commit 910f142ce013234868fc6da5eda7cffb80b45b2b Author: Luca Burgazzoli <[email protected]> AuthorDate: Wed Apr 14 19:06:29 2021 +0200 [CAMEL-16504] YAML Dsl : support for "flow" like route definition --- .../yaml/common/YamlDeserializationContext.java | 10 ++ .../dsl/yaml/common/YamlDeserializationMode.java | 73 ++++++++++ .../dsl/yaml/common/YamlDeserializerBase.java | 2 +- .../dsl/yaml/common/YamlDeserializerSupport.java | 21 +++ .../dsl/yaml/deserializers/ModelDeserializers.java | 149 +++++---------------- .../deserializers/RouteDefinitionDeserializer.java | 5 +- .../RouteFromDefinitionDeserializer.java | 5 +- .../dsl/yaml/GenerateYamlDeserializersMojo.java | 4 +- .../camel/dsl/yaml/YamlRoutesBuilderLoader.java | 33 +++-- .../org/apache/camel/dsl/yaml/AggregateTest.groovy | 64 ++++++++- .../org/apache/camel/dsl/yaml/LoopTest.groovy | 29 ++++ .../org/apache/camel/dsl/yaml/SplitTest.groovy | 44 ++++++ .../camel/dsl/yaml/support/YamlTestSupport.groovy | 5 + 13 files changed, 307 insertions(+), 137 deletions(-) diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlDeserializationContext.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlDeserializationContext.java index 769d779..cb20da3 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlDeserializationContext.java +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlDeserializationContext.java @@ -46,6 +46,7 @@ public class YamlDeserializationContext extends StandardConstructor implements C private final Set<YamlDeserializerResolver> resolvers; private final Map<String, ConstructNode> constructors; + private YamlDeserializationMode deserializationMode; private ExtendedCamelContext camelContext; public YamlDeserializationContext(LoadSettings settings) { @@ -53,6 +54,7 @@ public class YamlDeserializationContext extends StandardConstructor implements C this.resolvers = new TreeSet<>(Comparator.comparing(Ordered::getOrder)); this.constructors = new HashMap<>(); + this.deserializationMode = YamlDeserializationMode.CLASSIC; } public void addResolver(YamlDeserializerResolver resolver) { @@ -67,6 +69,14 @@ public class YamlDeserializationContext extends StandardConstructor implements C this.resolvers.addAll(resolvers); } + public void setDeserializationMode(YamlDeserializationMode deserializationMode) { + this.deserializationMode = deserializationMode; + } + + public YamlDeserializationMode getDeserializationMode() { + return deserializationMode; + } + @Override public CamelContext getCamelContext() { return camelContext; diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlDeserializationMode.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlDeserializationMode.java new file mode 100644 index 0000000..1fdfa41 --- /dev/null +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlDeserializationMode.java @@ -0,0 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.dsl.yaml.common; + +public enum YamlDeserializationMode { + /** + * This option configure the deserialization engine to strictly respect the model definition. + * + * </p> + * As example, a Split step is expected to have it's own steps to process the result of the split. + * + * <pre> + * {@code + * - from: + * uri: "direct:a" + * steps: + * - split: + * tokenize: \n" + * steps: + * - log: "${body}" + * } + * </pre> + */ + CLASSIC, + + /** + * Mimics the Java Dsl. + * </p> + * When the deserializer is configured to use this mode, a route can be defined using a syntax that is closed to the + * Java DSL, as example, the following Java route: + * + * <pre> + * {@code + * from("direct:a") + * .split().tokenize("\n")) + * .log("${body}"); + * } + * </pre> + * + * Can be represented by the following YAML: + * + * <pre> + * {@code + * - from: + * uri: "direct:a" + * steps: + * - split: + * tokenize: \n" + * - log: "${body}" + * } + * </pre> + * + * As you may have noticed, there's no need to define the split's specific steps as the subsequent log processor is + * automatically added to the step's outputs. + * </p> + * See https://issues.apache.org/jira/browse/CAMEL-16504 + */ + FLOW; +} diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlDeserializerBase.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlDeserializerBase.java index 128ed36..02ec14a 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlDeserializerBase.java +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlDeserializerBase.java @@ -91,7 +91,7 @@ public abstract class YamlDeserializerBase<T> extends YamlDeserializerSupport im * @param target the target object */ protected void setProperties(T target, MappingNode node) { - org.apache.camel.dsl.yaml.common.YamlDeserializationContext dc = getDeserializationContext(node); + YamlDeserializationContext dc = getDeserializationContext(node); for (NodeTuple tuple : node.getValue()) { final ScalarNode key = (ScalarNode) tuple.getKeyNode(); diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlDeserializerSupport.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlDeserializerSupport.java index 56430ba..48cade8 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlDeserializerSupport.java +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlDeserializerSupport.java @@ -30,7 +30,11 @@ import org.apache.camel.CamelContext; import org.apache.camel.dsl.yaml.common.exception.UnsupportedFieldException; import org.apache.camel.dsl.yaml.common.exception.UnsupportedNodeTypeException; import org.apache.camel.dsl.yaml.common.exception.YamlDeserializationException; +import org.apache.camel.model.Block; +import org.apache.camel.model.OutputNode; +import org.apache.camel.model.ProcessorDefinition; import org.apache.camel.util.CollectionHelper; +import org.apache.camel.util.ObjectHelper; import org.apache.camel.util.StringHelper; import org.snakeyaml.engine.v2.api.ConstructNode; import org.snakeyaml.engine.v2.nodes.MappingNode; @@ -331,4 +335,21 @@ public class YamlDeserializerSupport { node.setProperty(YamlDeserializationContext.class.getName(), context); return node; } + + public static void setSteps(Block target, Node node) { + final YamlDeserializationContext dc = getDeserializationContext(node); + + Block block = target; + for (ProcessorDefinition<?> definition : asFlatList(node, ProcessorDefinition.class)) { + block.addOutput(definition); + + if (dc.getDeserializationMode() == YamlDeserializationMode.FLOW) { + if (definition instanceof OutputNode) { + if (ObjectHelper.isEmpty(definition.getOutputs())) { + block = definition; + } + } + } + } + } } diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java index 643afa5..f12f10d 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java @@ -54,7 +54,6 @@ import org.apache.camel.model.PipelineDefinition; import org.apache.camel.model.PolicyDefinition; import org.apache.camel.model.PollEnrichDefinition; import org.apache.camel.model.ProcessDefinition; -import org.apache.camel.model.ProcessorDefinition; import org.apache.camel.model.PropertyDefinition; import org.apache.camel.model.RecipientListDefinition; import org.apache.camel.model.RedeliveryPolicyDefinition; @@ -480,9 +479,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -1340,9 +1337,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -1394,9 +1389,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -1466,9 +1459,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -3692,9 +3683,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -4644,9 +4633,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -4695,9 +4682,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -4927,9 +4912,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -5345,9 +5328,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -5851,9 +5832,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -6065,9 +6044,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -6119,9 +6096,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -6185,9 +6160,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -6891,9 +6864,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -7238,9 +7209,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -7408,9 +7377,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -7968,9 +7935,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -8176,9 +8141,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -8285,9 +8248,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -8333,9 +8294,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -8434,9 +8393,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -8475,9 +8432,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -8872,9 +8827,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -8914,9 +8867,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -8962,9 +8913,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -9204,9 +9153,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -9534,9 +9481,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -10209,9 +10154,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -11551,9 +11494,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -11996,9 +11937,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -13423,9 +13362,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -13521,9 +13458,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -14534,9 +14469,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -14706,9 +14639,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -15705,9 +15636,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -15807,9 +15736,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { @@ -15865,9 +15792,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { break; } case "steps": { - for (ProcessorDefinition<?> definition: asFlatList(node, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, node);; break; } default: { diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/RouteDefinitionDeserializer.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/RouteDefinitionDeserializer.java index 1379569..9170fcb 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/RouteDefinitionDeserializer.java +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/RouteDefinitionDeserializer.java @@ -21,7 +21,6 @@ import org.apache.camel.dsl.yaml.common.YamlDeserializerBase; import org.apache.camel.dsl.yaml.common.YamlDeserializerResolver; import org.apache.camel.dsl.yaml.common.exception.UnsupportedFieldException; import org.apache.camel.model.FromDefinition; -import org.apache.camel.model.ProcessorDefinition; import org.apache.camel.model.RouteDefinition; import org.apache.camel.spi.annotations.YamlIn; import org.apache.camel.spi.annotations.YamlProperty; @@ -63,9 +62,7 @@ public class RouteDefinitionDeserializer extends YamlDeserializerBase<RouteDefin switch (key) { case "steps": - for (ProcessorDefinition<?> definition : asFlatList(val, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, val); break; case "id": target.setId(asText(val)); diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/RouteFromDefinitionDeserializer.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/RouteFromDefinitionDeserializer.java index 16aee6d..0ae312c 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/RouteFromDefinitionDeserializer.java +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/RouteFromDefinitionDeserializer.java @@ -24,7 +24,6 @@ import org.apache.camel.dsl.yaml.common.YamlDeserializerResolver; import org.apache.camel.dsl.yaml.common.YamlSupport; import org.apache.camel.dsl.yaml.deserializers.model.OutputAwareFromDefinition; import org.apache.camel.model.FromDefinition; -import org.apache.camel.model.ProcessorDefinition; import org.apache.camel.spi.annotations.YamlIn; import org.apache.camel.spi.annotations.YamlProperty; import org.apache.camel.spi.annotations.YamlType; @@ -73,9 +72,7 @@ public class RouteFromDefinitionDeserializer extends YamlDeserializerBase<Output switch (key) { case "steps": - for (ProcessorDefinition<?> definition : asFlatList(val, ProcessorDefinition.class)) { - target.addOutput(definition); - } + setSteps(target, val); break; case "uri": uri = asText(val); diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-maven-plugin/src/main/java/org/apache/camel/maven/dsl/yaml/GenerateYamlDeserializersMojo.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-maven-plugin/src/main/java/org/apache/camel/maven/dsl/yaml/GenerateYamlDeserializersMojo.java index a88d4dd..a454a0e 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl-maven-plugin/src/main/java/org/apache/camel/maven/dsl/yaml/GenerateYamlDeserializersMojo.java +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-maven-plugin/src/main/java/org/apache/camel/maven/dsl/yaml/GenerateYamlDeserializersMojo.java @@ -497,9 +497,7 @@ public class GenerateYamlDeserializersMojo extends GenerateYamlSupportMojo { if (implementType(info, OUTPUT_NODE_CLASS)) { setProperty.beginControlFlow("case \"steps\":"); - setProperty.beginControlFlow("for ($T<?> definition: asFlatList(node, $T.class))", CN_PROCESSOR_DEFINITION, CN_PROCESSOR_DEFINITION); - setProperty.addStatement("target.addOutput(definition)"); - setProperty.endControlFlow(); + setProperty.addStatement("setSteps(target, node);"); setProperty.addStatement("break"); setProperty.endControlFlow(); diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/java/org/apache/camel/dsl/yaml/YamlRoutesBuilderLoader.java b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/java/org/apache/camel/dsl/yaml/YamlRoutesBuilderLoader.java index 73c1d8c..82ac857 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/java/org/apache/camel/dsl/yaml/YamlRoutesBuilderLoader.java +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/java/org/apache/camel/dsl/yaml/YamlRoutesBuilderLoader.java @@ -18,12 +18,15 @@ package org.apache.camel.dsl.yaml; import java.io.InputStream; import java.util.List; +import java.util.Locale; +import java.util.Map; import org.apache.camel.api.management.ManagedResource; import org.apache.camel.builder.ErrorHandlerBuilder; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.dsl.support.RouteBuilderLoaderSupport; import org.apache.camel.dsl.yaml.common.YamlDeserializationContext; +import org.apache.camel.dsl.yaml.common.YamlDeserializationMode; import org.apache.camel.dsl.yaml.deserializers.CustomResolver; import org.apache.camel.dsl.yaml.deserializers.EndpointProducerDeserializersResolver; import org.apache.camel.dsl.yaml.deserializers.ModelDeserializersResolver; @@ -43,10 +46,11 @@ import org.snakeyaml.engine.v2.api.LoadSettings; @ManagedResource(description = "Managed YAML RoutesBuilderLoader") @RoutesLoader(YamlRoutesBuilderLoader.EXTENSION) public class YamlRoutesBuilderLoader extends RouteBuilderLoaderSupport { + public static final String DESERIALIZATION_MODE = "CamelYamlDslDeserializationMode"; public static final String EXTENSION = "yaml"; private LoadSettings settings; - private YamlDeserializationContext constructor; + private YamlDeserializationContext deserializationContext; public YamlRoutesBuilderLoader() { super(EXTENSION); @@ -57,39 +61,46 @@ public class YamlRoutesBuilderLoader extends RouteBuilderLoaderSupport { super.doBuild(); this.settings = LoadSettings.builder().build(); - this.constructor = new YamlDeserializationContext(settings); - this.constructor.setCamelContext(getCamelContext()); - this.constructor.addResolvers(new CustomResolver()); - this.constructor.addResolvers(new ModelDeserializersResolver()); - this.constructor.addResolvers(new EndpointProducerDeserializersResolver()); + this.deserializationContext = new YamlDeserializationContext(settings); + this.deserializationContext.setCamelContext(getCamelContext()); + this.deserializationContext.addResolvers(new CustomResolver()); + this.deserializationContext.addResolvers(new ModelDeserializersResolver()); + this.deserializationContext.addResolvers(new EndpointProducerDeserializersResolver()); } @Override protected void doStart() throws Exception { super.doStart(); - ServiceHelper.startService(this.constructor); + final Map<String, String> options = getCamelContext().getGlobalOptions(); + final String mode = options.getOrDefault(DESERIALIZATION_MODE, YamlDeserializationMode.CLASSIC.name()); + if (mode != null) { + this.deserializationContext.setDeserializationMode( + YamlDeserializationMode.valueOf(mode.toUpperCase(Locale.US))); + } + + ServiceHelper.startService(this.deserializationContext); } @Override protected void doStop() throws Exception { super.doStop(); - ServiceHelper.stopService(this.constructor); + ServiceHelper.stopService(this.deserializationContext); - this.constructor = null; + this.deserializationContext = null; this.settings = null; } @Override public RouteBuilder doLoadRouteBuilder(Resource resource) throws Exception { - ObjectHelper.notNull(constructor, "constructor"); + ObjectHelper.notNull(deserializationContext, "constructor"); ObjectHelper.notNull(settings, "settings"); return new RouteBuilder() { @Override public void configure() throws Exception { - final Load load = new Load(settings, constructor); + final Load load = new Load(settings, deserializationContext); try (InputStream is = resource.getInputStream()) { for (Object item : (List<?>) load.loadFromInputStream(is)) { diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/AggregateTest.groovy b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/AggregateTest.groovy index 232eba6..1305c2a 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/AggregateTest.groovy +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/AggregateTest.groovy @@ -16,10 +16,17 @@ */ package org.apache.camel.dsl.yaml -import org.apache.camel.dsl.yaml.support.YamlTestSupport +import org.apache.camel.FailedToCreateRouteException import org.apache.camel.component.mock.MockEndpoint +import org.apache.camel.dsl.yaml.common.YamlDeserializationMode +import org.apache.camel.dsl.yaml.support.YamlTestSupport class AggregateTest extends YamlTestSupport { + @Override + def doSetup() { + context.start() + } + def 'aggregate'() { setup: loadRoutes ''' @@ -43,8 +50,40 @@ class AggregateTest extends YamlTestSupport { } when: - context.start() + withTemplate { + to('direct:route').withBody('1').withHeader('StockSymbol', 1).send() + to('direct:route').withBody('2').withHeader('StockSymbol', 1).send() + to('direct:route').withBody('3').withHeader('StockSymbol', 2).send() + to('direct:route').withBody('4').withHeader('StockSymbol', 2).send() + } + then: + MockEndpoint.assertIsSatisfied(context) + } + def 'aggregate (flow)'() { + setup: + setFlowMode(YamlDeserializationMode.FLOW) + + loadRoutes ''' + - beans: + - name: myAggregatorStrategy + type: org.apache.camel.processor.aggregate.UseLatestAggregationStrategy + - from: + uri: "direct:route" + steps: + - aggregate: + strategy-ref: "myAggregatorStrategy" + completion-size: 2 + correlation-expression: + simple: "${header.StockSymbol}" + - to: "mock:route" + ''' + + withMock('mock:route') { + expectedBodiesReceived '2', '4' + } + + when: withTemplate { to('direct:route').withBody('1').withHeader('StockSymbol', 1).send() to('direct:route').withBody('2').withHeader('StockSymbol', 1).send() @@ -54,4 +93,25 @@ class AggregateTest extends YamlTestSupport { then: MockEndpoint.assertIsSatisfied(context) } + + def 'aggregate (disabled)'() { + when: + loadRoutes ''' + - beans: + - name: myAggregatorStrategy + type: org.apache.camel.processor.aggregate.UseLatestAggregationStrategy + - from: + uri: "direct:route" + steps: + - aggregate: + strategy-ref: "myAggregatorStrategy" + completion-size: 2 + correlation-expression: + simple: "${header.StockSymbol}" + - to: "mock:route" + ''' + then: + def ex = thrown(FailedToCreateRouteException) + ex.message.contains('Failed to create route') + } } diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/LoopTest.groovy b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/LoopTest.groovy index 44f17aa..beda4b0 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/LoopTest.groovy +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/LoopTest.groovy @@ -16,6 +16,8 @@ */ package org.apache.camel.dsl.yaml +import org.apache.camel.component.mock.MockEndpoint +import org.apache.camel.dsl.yaml.common.YamlDeserializationMode import org.apache.camel.dsl.yaml.support.YamlTestSupport import org.apache.camel.model.LoopDefinition import org.apache.camel.model.language.ExpressionDefinition @@ -56,4 +58,31 @@ class LoopTest extends YamlTestSupport { ''') ] } + + def "loop (flow)"() { + setup: + setFlowMode(YamlDeserializationMode.FLOW) + + loadRoutes ''' + - from: + uri: "direct:route" + steps: + - loop: + copy: true + constant: "3" + - to: "mock:result" + ''' + + withMock('mock:result') { + expectedMessageCount 3 + } + when: + context.start() + + withTemplate { + to('direct:route').withBody('a').send() + } + then: + MockEndpoint.assertIsSatisfied(context) + } } diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/SplitTest.groovy b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/SplitTest.groovy index 31ae2c1..fe1b701 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/SplitTest.groovy +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/SplitTest.groovy @@ -16,7 +16,9 @@ */ package org.apache.camel.dsl.yaml +import org.apache.camel.FailedToCreateRouteException import org.apache.camel.component.mock.MockEndpoint +import org.apache.camel.dsl.yaml.common.YamlDeserializationMode import org.apache.camel.dsl.yaml.support.YamlTestSupport class SplitTest extends YamlTestSupport { @@ -56,4 +58,46 @@ class SplitTest extends YamlTestSupport { then: MockEndpoint.assertIsSatisfied(context) } + + def "split (flow)"() { + setup: + setFlowMode(YamlDeserializationMode.FLOW) + + loadRoutes ''' + - from: + uri: "direct:route" + steps: + - split: + tokenize: "," + - to: "mock:split" + ''' + + withMock('mock:split') { + expectedMessageCount 3 + expectedBodiesReceived 'a', 'b', 'c' + } + + when: + withTemplate { + to('direct:route').withBody('a,b,c').send() + } + + then: + MockEndpoint.assertIsSatisfied(context) + } + + def "split (flow disabled)"() { + when: + loadRoutes ''' + - from: + uri: "direct:route" + steps: + - split: + tokenize: "," + - to: "mock:split" + ''' + then: + def ex = thrown(FailedToCreateRouteException) + ex.message.contains('Failed to create route') + } } diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/support/YamlTestSupport.groovy b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/support/YamlTestSupport.groovy index 5427bc7..1aedc0d 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/support/YamlTestSupport.groovy +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/support/YamlTestSupport.groovy @@ -24,6 +24,8 @@ import groovy.util.logging.Slf4j import org.apache.camel.CamelContext import org.apache.camel.FluentProducerTemplate import org.apache.camel.component.mock.MockEndpoint +import org.apache.camel.dsl.yaml.YamlRoutesBuilderLoader +import org.apache.camel.dsl.yaml.common.YamlDeserializationMode import org.apache.camel.impl.DefaultCamelContext import org.apache.camel.spi.HasCamelContext import org.apache.camel.spi.Resource @@ -96,6 +98,9 @@ class YamlTestSupport extends Specification implements HasCamelContext { ) } + def setFlowMode(YamlDeserializationMode mode) { + context.globalOptions[YamlRoutesBuilderLoader.DESERIALIZATION_MODE] = mode.name() + } // *********************************** //
