This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch bind
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/bind by this push:
     new ec2a0ae  CAMEL-17261: camel-yaml-dsl - Add support for loading Camel K 
KameletBinding file. WIP.
ec2a0ae is described below

commit ec2a0ae4949436dab1fb0a60d0a1152881962534
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Sun Dec 5 18:05:43 2021 +0100

    CAMEL-17261: camel-yaml-dsl - Add support for loading Camel K 
KameletBinding file. WIP.
---
 .../camel/dsl/yaml/YamlRoutesBuilderLoader.java    |  89 +++++++++------
 .../camel/dsl/yaml/KameletBindingLoaderTest.groovy | 127 +++++++++++++++++++++
 .../resources/kamelets/prefix-action.kamelet.yaml  |  45 ++++++++
 3 files changed, 223 insertions(+), 38 deletions(-)

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 5782086..af26b7f 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
@@ -189,58 +189,71 @@ public class YamlRoutesBuilderLoader extends 
YamlRoutesBuilderLoaderSupport {
      * Camel K Kamelet Binding file
      */
     private static Object preConfigureKameletBinding(Node root, Object target) 
throws Exception {
+        final RouteDefinition route = new RouteDefinition();
+        String routeId = asText(nodeAt(root, "/metadata/name"));
+        if (routeId != null) {
+            route.routeId(routeId);
+        }
+
         // kamelet binding is a bit more complex, so grab the source and sink
         // and map those to Camel route definitions
         MappingNode source = asMappingNode(nodeAt(root, "/spec/source"));
         MappingNode sink = asMappingNode(nodeAt(root, "/spec/sink"));
         if (source != null && sink != null) {
-            Node sourceRef = nodeAt(source, "/ref");
-            if (sourceRef != null) {
-                source = asMappingNode(sourceRef);
-            }
-            Node sinkRef = nodeAt(sink, "/ref");
-            if (sinkRef != null) {
-                sink = asMappingNode(sinkRef);
-            }
-            boolean sourceKamelet = sourceRef != null && 
anyTupleMatches(source.getValue(), "kind", "Kamelet");
-            boolean sinkKamelet = sinkRef != null && 
anyTupleMatches(sink.getValue(), "kind", "Kamelet");
-            String from = extractTupleValue(source.getValue(), sourceKamelet ? 
"name" : "uri");
-            String to = extractTupleValue(sink.getValue(), sinkKamelet ? 
"name" : "uri");
-            if (sourceKamelet) {
-                from = "kamelet:" + from;
-            }
-            if (sinkKamelet) {
-                to = "kamelet:" + to;
-            }
+            // source at the beginning (mandatory)
+            String from = extractCamelEndpointUri(source);
+            route.from(from);
 
-            // source properties
-            MappingNode sp = asMappingNode(nodeAt(root, 
"/spec/source/properties"));
-            Map<String, Object> params = asMap(sp);
-            if (params != null && !params.isEmpty()) {
-                String query = URISupport.createQueryString(params);
-                from = from + "?" + query;
-            }
-            // sink properties
-            sp = asMappingNode(nodeAt(root, "/spec/sink/properties"));
-            params = asMap(sp);
-            if (params != null && !params.isEmpty()) {
-                String query = URISupport.createQueryString(params);
-                to = to + "?" + query;
+            // steps in the middle (optional)
+            Node steps = nodeAt(root, "/spec/steps");
+            if (steps != null) {
+                SequenceNode sn = asSequenceNode(steps);
+                for (Node node : sn.getValue()) {
+                    MappingNode step = asMappingNode(node);
+                    String uri = extractCamelEndpointUri(step);
+                    if (uri != null) {
+                        route.to(uri);
+                    }
+                }
             }
 
-            String routeId = asText(nodeAt(root, "/metadata/name"));
+            // sink is at the end (mandatory)
+            String to = extractCamelEndpointUri(sink);
+            route.to(to);
 
-            // build kamelet binding as a route
-            RouteDefinition route = new RouteDefinition();
-            if (routeId != null) {
-                route.routeId(routeId);
-            }
-            route.from(from).to(to);
             target = route;
         }
+
         return target;
     }
 
+    private static String extractCamelEndpointUri(MappingNode node) throws 
Exception {
+        MappingNode mn = null;
+        Node ref = nodeAt(node, "/ref");
+        if (ref != null) {
+            mn = asMappingNode(ref);
+        }
+
+        // extract uri is different if kamelet or not
+        boolean kamelet = mn != null && anyTupleMatches(mn.getValue(), "kind", 
"Kamelet");
+        String uri;
+        if (kamelet) {
+            uri = extractTupleValue(mn.getValue(), "name");
+        } else {
+            uri = extractTupleValue(node.getValue(), "uri");
+        }
+
+        // properties
+        MappingNode prop = asMappingNode(nodeAt(node, "/properties"));
+        Map<String, Object> params = asMap(prop);
+        if (params != null && !params.isEmpty()) {
+            String query = URISupport.createQueryString(params);
+            uri = uri + "?" + query;
+        }
+
+        return kamelet ? "kamelet:" + uri : uri;
+    }
+
     private static boolean anyTupleMatches(List<NodeTuple> list, String aKey, 
String aValue) {
         for (NodeTuple tuple : list) {
             final String key = asText(tuple.getKeyNode());
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/KameletBindingLoaderTest.groovy
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/KameletBindingLoaderTest.groovy
index fcf041a..a2a0323 100644
--- 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/KameletBindingLoaderTest.groovy
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/KameletBindingLoaderTest.groovy
@@ -114,4 +114,131 @@ class KameletBindingLoaderTest extends YamlTestSupport {
         }
     }
 
+    def "kamelet binding steps"() {
+        when:
+        loadBindings('''
+            apiVersion: camel.apache.org/v1alpha1
+            kind: KameletBinding
+            metadata:
+              name: steps-binding
+            spec:
+              source:
+                ref:
+                  kind: Kamelet
+                  apiVersion: camel.apache.org/v1alpha1
+                  name: timer-source
+                properties:
+                  message: "Camel"
+              steps:
+              - ref:
+                  kind: Kamelet
+                  apiVersion: camel.apache.org/v1alpha1
+                  name: prefix-action
+                properties:
+                  prefix: "Apache"
+              - ref:
+                  kind: Kamelet
+                  apiVersion: camel.apache.org/v1alpha1
+                  name: prefix-action
+                properties:
+                  prefix: "Hello"
+              sink:
+                uri: log:info
+                ''')
+        then:
+        context.routeDefinitions.size() == 4
+
+        with (context.routeDefinitions[0]) {
+            routeId == 'steps-binding'
+            input.endpointUri == 'kamelet:timer-source?message=Camel'
+            outputs.size() == 3
+            with (outputs[2], ToDefinition) {
+                endpointUri == 'log:info'
+            }
+        }
+    }
+
+    def "kamelet binding steps kamelet uri"() {
+        when:
+        loadBindings('''
+            apiVersion: camel.apache.org/v1alpha1
+            kind: KameletBinding
+            metadata:
+              name: steps-binding
+            spec:
+              source:
+                ref:
+                  kind: Kamelet
+                  apiVersion: camel.apache.org/v1alpha1
+                  name: timer-source
+                properties:
+                  message: "Camel"
+              steps:
+              - ref:
+                  kind: Kamelet
+                  apiVersion: camel.apache.org/v1alpha1
+                  name: prefix-action
+                properties:
+                  prefix: "Apache"
+              - uri: mock:dummy
+              sink:
+                uri: log:info
+                ''')
+        then:
+        context.routeDefinitions.size() == 3
+
+        with (context.routeDefinitions[0]) {
+            routeId == 'steps-binding'
+            input.endpointUri == 'kamelet:timer-source?message=Camel'
+            outputs.size() == 3
+            with (outputs[1], ToDefinition) {
+                endpointUri == 'mock:dummy'
+            }
+            with (outputs[2], ToDefinition) {
+                endpointUri == 'log:info'
+            }
+        }
+    }
+
+    def "kamelet binding steps uri uri"() {
+        when:
+        loadBindings('''
+            apiVersion: camel.apache.org/v1alpha1
+            kind: KameletBinding
+            metadata:
+              name: steps-binding
+            spec:
+              source:
+                ref:
+                  kind: Kamelet
+                  apiVersion: camel.apache.org/v1alpha1
+                  name: timer-source
+                properties:
+                  message: "Camel"
+              steps:
+              - uri: mock:dummy
+              - uri: mock:dummy2
+              sink:
+                uri: log:info
+                ''')
+        then:
+        context.routeDefinitions.size() == 2
+
+        with (context.routeDefinitions[0]) {
+            routeId == 'steps-binding'
+            input.endpointUri == 'kamelet:timer-source?message=Camel'
+            outputs.size() == 3
+            with (outputs[0], ToDefinition) {
+                endpointUri == 'mock:dummy'
+            }
+            with (outputs[1], ToDefinition) {
+                endpointUri == 'mock:dummy2'
+            }
+            with (outputs[2], ToDefinition) {
+                endpointUri == 'log:info'
+            }
+        }
+    }
+
+
 }
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/resources/kamelets/prefix-action.kamelet.yaml
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/resources/kamelets/prefix-action.kamelet.yaml
new file mode 100644
index 0000000..e8e9b6a
--- /dev/null
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/resources/kamelets/prefix-action.kamelet.yaml
@@ -0,0 +1,45 @@
+# ---------------------------------------------------------------------------
+# 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.
+# ---------------------------------------------------------------------------
+
+apiVersion: camel.apache.org/v1alpha1
+kind: Kamelet
+metadata:
+  name: prefix-action
+  labels:
+    camel.apache.org/kamelet.type: "step"
+spec:
+  definition:
+    title: "Prefix"
+    description: "Adds a prefix to the incoming payload"
+    required:
+      - prefix
+    properties:
+      prefix:
+        title: Prefix
+        description: The prefix to add
+        type: string
+  types:
+    in:
+      mediaType: text/plain
+    out:
+      mediaType: text/plain
+  flow:
+    from:
+      uri: "kamelet:source"
+      steps:
+        - set-body:
+            simple: "{{prefix}} ${body}"
\ No newline at end of file

Reply via email to