You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by lb...@apache.org on 2021/04/15 08:53:44 UTC

[camel] 01/02: [CAMEL-16504] YAML Dsl : support for "flow" like route definition

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 <lb...@gmail.com>
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()
+    }
 
     // ***********************************
     //