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

[camel] 02/02: CAMEL-17261: camel-yaml-dsl - Add support for loading Camel K KameletBinding file. WIP.

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

commit 2829e29b5950d2eb170d5d4e2299b283bc33196f
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Sat Dec 4 07:57:55 2021 +0100

    CAMEL-17261: camel-yaml-dsl - Add support for loading Camel K KameletBinding file. WIP.
---
 .../camel/dsl/yaml/YamlRoutesBuilderLoader.java    | 41 ++++++++++++++
 .../camel/dsl/yaml/KameletBindingLoaderTest.groovy | 65 ++++++++++++++++++++++
 .../camel/dsl/yaml/support/YamlTestSupport.groovy  | 10 ++++
 3 files changed, 116 insertions(+)

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 30cd3fa..9e8b359 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
@@ -24,8 +24,10 @@ import org.apache.camel.api.management.ManagedResource;
 import org.apache.camel.builder.ErrorHandlerBuilder;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.builder.RouteConfigurationBuilder;
+import org.apache.camel.dsl.yaml.common.YamlDeserializationContext;
 import org.apache.camel.dsl.yaml.common.YamlDeserializerSupport;
 import org.apache.camel.dsl.yaml.deserializers.OutputAwareFromDefinition;
+import org.apache.camel.model.FromDefinition;
 import org.apache.camel.model.OnExceptionDefinition;
 import org.apache.camel.model.RouteConfigurationDefinition;
 import org.apache.camel.model.RouteDefinition;
@@ -35,11 +37,15 @@ import org.apache.camel.model.rest.RestDefinition;
 import org.apache.camel.model.rest.VerbDefinition;
 import org.apache.camel.spi.CamelContextCustomizer;
 import org.apache.camel.spi.annotations.RoutesLoader;
+import org.snakeyaml.engine.v2.api.ConstructNode;
 import org.snakeyaml.engine.v2.nodes.MappingNode;
 import org.snakeyaml.engine.v2.nodes.Node;
 import org.snakeyaml.engine.v2.nodes.NodeTuple;
 import org.snakeyaml.engine.v2.nodes.NodeType;
+import org.snakeyaml.engine.v2.nodes.SequenceNode;
+import org.snakeyaml.engine.v2.nodes.Tag;
 
+import static org.apache.camel.dsl.yaml.common.YamlDeserializerSupport.asMappingNode;
 import static org.apache.camel.dsl.yaml.common.YamlDeserializerSupport.asSequenceNode;
 import static org.apache.camel.dsl.yaml.common.YamlDeserializerSupport.asText;
 import static org.apache.camel.dsl.yaml.common.YamlDeserializerSupport.nodeAt;
@@ -128,6 +134,9 @@ public class YamlRoutesBuilderLoader extends YamlRoutesBuilderLoaderSupport {
             final MappingNode mn = YamlDeserializerSupport.asMappingNode(root);
             boolean camelk = anyTupleMatches(mn.getValue(), "apiVersion", "camel.apache.org/v1") &&
                     anyTupleMatches(mn.getValue(), "kind", "Integration");
+            // kamelet binding are still at v1alpha1
+            boolean binding = anyTupleMatches(mn.getValue(), "apiVersion", "camel.apache.org/v1alpha1") &&
+                    anyTupleMatches(mn.getValue(), "kind", "KameletBinding");
             if (camelk) {
                 Node routes = nodeAt(root, "/spec/flows");
                 if (routes == null) {
@@ -136,6 +145,27 @@ public class YamlRoutesBuilderLoader extends YamlRoutesBuilderLoaderSupport {
                 if (routes != null) {
                     target = routes;
                 }
+            } else if (binding) {
+                MappingNode source = asMappingNode(nodeAt(root, "/spec/source/ref"));
+                MappingNode sink = asMappingNode(nodeAt(root, "/spec/sink/ref"));
+                if (source != null && sink != null) {
+                    boolean sourceKamelet = anyTupleMatches(source.getValue(), "kind", "Kamelet");
+                    boolean sinkKamelet = anyTupleMatches(sink.getValue(), "kind", "Kamelet");
+                    String from = extractTupleValue(source.getValue(), "name");
+                    String to = extractTupleValue(sink.getValue(), "name");
+                    if (sourceKamelet) {
+                        from = "kamelet:" + from;
+                    }
+                    if (sinkKamelet) {
+                        to = "kamelet:" + to;
+                    }
+                    // add directly
+                    System.out.println(from + " -> " + to);
+                    YamlDeserializationContext ydc = YamlDeserializerSupport.getDeserializationContext(source);
+                    Object route = ydc.resolve(RouteDefinition.class).construct(target);
+                    System.out.println(route);
+                }
+
             }
         }
 
@@ -156,4 +186,15 @@ public class YamlRoutesBuilderLoader extends YamlRoutesBuilderLoaderSupport {
         return false;
     }
 
+    private static String extractTupleValue(List<NodeTuple> list, String aKey) {
+        for (NodeTuple tuple : list) {
+            final String key = asText(tuple.getKeyNode());
+            final Node val = tuple.getValueNode();
+            if (Objects.equals(aKey, key) && NodeType.SCALAR.equals(val.getNodeType())) {
+                return asText(tuple.getValueNode());
+            }
+        }
+        return null;
+    }
+
 }
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
new file mode 100644
index 0000000..d474de8
--- /dev/null
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/KameletBindingLoaderTest.groovy
@@ -0,0 +1,65 @@
+/*
+ * 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
+
+import org.apache.camel.dsl.yaml.support.YamlTestSupport
+import org.apache.camel.model.ToDefinition
+
+class KameletBindingLoaderTest extends YamlTestSupport {
+    @Override
+    def doSetup() {
+        context.start()
+    }
+
+    def "kamelet binding"() {
+        when:
+            loadBindings('''
+                apiVersion: camel.apache.org/v1alpha1
+                kind: KameletBinding
+                metadata:
+                  name: timer-event-source                  
+                spec:
+                  source:
+                    ref:
+                      kind: Kamelet
+                      apiVersion: camel.apache.org/v1
+                      name: timer-source
+                    properties:
+                      message: "Hello world!"
+                  sink:
+                    ref:
+                      kind: Kamelet
+                      apiVersion: camel.apache.org/v1
+                      name: log-sink
+            ''')
+        then:
+            context.routeTemplateDefinitions.size() == 1
+
+            with (context.routeTemplateDefinitions[0]) {
+                id == 'timer-event-source'
+
+                with(route) {
+                    input.endpointUri == 'kamelet:timer-source'
+                    outputs.size() == 1
+                    with (outputs[0], ToDefinition) {
+                        endpointUri == 'kamelet:log-sink'
+                    }
+                }
+            }
+    }
+
+}
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 efd01cf..4746be8 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
@@ -94,6 +94,16 @@ class YamlTestSupport extends Specification implements HasCamelContext {
         )
     }
 
+    def loadBindings(String... resources) {
+        int index = 0
+
+        context.routesLoader.loadRoutes(
+            resources.collect {
+                it -> ResourceHelper.fromString("binding-${index++}.yaml", it.stripIndent())
+            }
+        )
+    }
+
     def withMock(
             String uri,
             @DelegatesTo(MockEndpoint) Closure<?> closure) {