You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by cd...@apache.org on 2024/01/11 14:18:37 UTC

(camel) branch main updated: Improve data type resolving in YAML Pipe loader

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

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


The following commit(s) were added to refs/heads/main by this push:
     new 45587d42dbe Improve data type resolving in YAML Pipe loader
45587d42dbe is described below

commit 45587d42dbe6d2d14ce0f6e5603fb236f073f5d4
Author: Christoph Deppisch <cd...@redhat.com>
AuthorDate: Thu Jan 11 09:39:33 2024 +0100

    Improve data type resolving in YAML Pipe loader
    
    - Support default data type prefix "camel:" when resolving transformers
    - Support for optional "scheme" property in YAML DSL on dataTypes/in and dataTypes/out nodes
---
 .../org/apache/camel/spi/TransformerResolver.java  |   9 +-
 .../ByteArrayDataTypeTransformerTest.java          |   6 ++
 .../transformer/StringDataTypeTransformerTest.java |   6 ++
 .../camel/dsl/yaml/YamlRoutesBuilderLoader.java    |  26 +++++-
 .../apache/camel/dsl/yaml/PipeLoaderTest.groovy    | 100 +++++++++++++++++++++
 5 files changed, 141 insertions(+), 6 deletions(-)

diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/TransformerResolver.java b/core/camel-api/src/main/java/org/apache/camel/spi/TransformerResolver.java
index cf03dc13012..af75c26051b 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/TransformerResolver.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/TransformerResolver.java
@@ -20,6 +20,7 @@ package org.apache.camel.spi;
 import java.util.Locale;
 
 import org.apache.camel.CamelContext;
+import org.apache.camel.util.StringHelper;
 
 /**
  * Resolves data type transformers from given transformer key. This represents the opportunity to lazy load transformers
@@ -42,13 +43,17 @@ public interface TransformerResolver<K> {
 
     /**
      * Normalize transformer key to conform with factory finder resource path. Replaces all non supported characters
-     * such as slashes and colons to dashes.
+     * such as slashes and colons to dashes. Automatically removes the default scheme prefix as it should not be part of
+     * the resource path.
      *
      * @param  key the transformer key
      * @return     normalized String representation of the key
      */
     default String normalize(K key) {
-        return key.toString().replaceAll("[^A-Za-z0-9-]", "-").toLowerCase(Locale.US);
+        String keyString = key.toString();
+        keyString = StringHelper.after(keyString, DataType.DEFAULT_SCHEME + ":", keyString);
+
+        return StringHelper.sanitize(keyString).toLowerCase(Locale.US);
     }
 
 }
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/transformer/ByteArrayDataTypeTransformerTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/transformer/ByteArrayDataTypeTransformerTest.java
index 1f5f3011f24..5142440defc 100644
--- a/core/camel-core/src/test/java/org/apache/camel/processor/transformer/ByteArrayDataTypeTransformerTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/transformer/ByteArrayDataTypeTransformerTest.java
@@ -90,6 +90,12 @@ public class ByteArrayDataTypeTransformerTest {
         DefaultTransformerRegistry transformerRegistry = new DefaultTransformerRegistry(camelContext);
         Transformer transformer = transformerRegistry.resolveTransformer(new TransformerKey("application-octet-stream"));
         Assertions.assertNotNull(transformer);
+
+        transformer = transformerRegistry.resolveTransformer(new TransformerKey("application/octet-stream"));
+        Assertions.assertNotNull(transformer);
+
+        transformer = transformerRegistry.resolveTransformer(new TransformerKey("camel:application-octet-stream"));
+        Assertions.assertNotNull(transformer);
     }
 
     private static void assertBinaryBody(Exchange exchange, String key, String content) {
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/transformer/StringDataTypeTransformerTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/transformer/StringDataTypeTransformerTest.java
index 76f44f16681..1befb255321 100644
--- a/core/camel-core/src/test/java/org/apache/camel/processor/transformer/StringDataTypeTransformerTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/transformer/StringDataTypeTransformerTest.java
@@ -78,6 +78,12 @@ public class StringDataTypeTransformerTest {
         DefaultTransformerRegistry dataTypeRegistry = new DefaultTransformerRegistry(camelContext);
         Transformer transformer = dataTypeRegistry.resolveTransformer(new TransformerKey("text-plain"));
         Assertions.assertNotNull(transformer);
+
+        transformer = dataTypeRegistry.resolveTransformer(new TransformerKey("text/plain"));
+        Assertions.assertNotNull(transformer);
+
+        transformer = dataTypeRegistry.resolveTransformer(new TransformerKey("camel:text-plain"));
+        Assertions.assertNotNull(transformer);
     }
 
     private static void assertStringBody(Exchange exchange, String key, String content) {
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 3b8bcd1b68b..2a9c7ffd224 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
@@ -722,12 +722,12 @@ public class YamlRoutesBuilderLoader extends YamlRoutesBuilderLoaderSupport {
                 if (dataTypes != null) {
                     MappingNode in = asMappingNode(nodeAt(dataTypes, "/in"));
                     if (in != null) {
-                        route.inputType(extractTupleValue(in.getValue(), "format"));
+                        route.inputType(extractDataType(in));
                     }
 
                     MappingNode out = asMappingNode(nodeAt(dataTypes, "/out"));
                     if (out != null) {
-                        route.transform(new DataType(extractTupleValue(out.getValue(), "format")));
+                        route.transform(new DataType(extractDataType(out)));
                     }
                 }
 
@@ -770,12 +770,12 @@ public class YamlRoutesBuilderLoader extends YamlRoutesBuilderLoaderSupport {
                     if (dataTypes != null) {
                         MappingNode in = asMappingNode(nodeAt(dataTypes, "/in"));
                         if (in != null) {
-                            route.transform(new DataType(extractTupleValue(in.getValue(), "format")));
+                            route.transform(new DataType(extractDataType(in)));
                         }
 
                         MappingNode out = asMappingNode(nodeAt(dataTypes, "/out"));
                         if (out != null) {
-                            route.outputType(extractTupleValue(out.getValue(), "format"));
+                            route.outputType(extractDataType(out));
                         }
                     }
 
@@ -845,6 +845,24 @@ public class YamlRoutesBuilderLoader extends YamlRoutesBuilderLoaderSupport {
         return answer;
     }
 
+    /**
+     * Extracts the data type transformer name information form nodes dataTypes/in or dataTypes/out. When scheme is set
+     * construct the transformer name with a prefix like scheme:format. Otherwise, just use the given format as a data
+     * type transformer name.
+     *
+     * @param  node
+     * @return
+     */
+    private String extractDataType(MappingNode node) {
+        String scheme = extractTupleValue(node.getValue(), "scheme");
+        String format = extractTupleValue(node.getValue(), "format");
+        if (scheme != null) {
+            return scheme + ":" + format;
+        }
+
+        return format;
+    }
+
     private String extractCamelEndpointUri(MappingNode node) {
         MappingNode mn = null;
         Node ref = nodeAt(node, "/ref");
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/PipeLoaderTest.groovy b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/PipeLoaderTest.groovy
index f2581179ce1..da3cbd39252 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/PipeLoaderTest.groovy
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/PipeLoaderTest.groovy
@@ -702,6 +702,52 @@ class PipeLoaderTest extends YamlTestSupport {
         }
     }
 
+    def "Pipe with input/output data types and schemes"() {
+        when:
+        loadBindings('''
+                apiVersion: camel.apache.org/v1
+                kind: Pipe
+                metadata:
+                  name: timer-event-source                  
+                spec:
+                  source:
+                    ref:
+                      kind: Kamelet
+                      apiVersion: camel.apache.org/v1
+                      name: timer-source
+                    dataTypes:
+                      in:
+                        scheme: camel
+                        format: plain/text
+                    properties:
+                      message: "Hello world!"
+                  sink:
+                    ref:
+                      kind: Kamelet
+                      apiVersion: camel.apache.org/v1
+                      name: log-sink
+                    dataTypes:
+                      out:
+                        scheme: camel
+                        format: application/octet-stream   
+            ''')
+        then:
+        context.routeDefinitions.size() == 3
+
+        with (context.routeDefinitions[0]) {
+            routeId == 'timer-event-source'
+            input.endpointUri == 'kamelet:timer-source?message=Hello+world%21'
+            input.lineNumber == 7
+            inputType.urn == 'camel:plain/text'
+            outputType.urn == 'camel:application/octet-stream'
+            outputs.size() == 1
+            with (outputs[0], ToDefinition) {
+                endpointUri == 'kamelet:log-sink'
+                lineNumber == 18
+            }
+        }
+    }
+
     def "Pipe with data type transformation"() {
         when:
         loadBindings('''
@@ -754,4 +800,58 @@ class PipeLoaderTest extends YamlTestSupport {
         }
     }
 
+    def "Pipe with data type scheme transformation"() {
+        when:
+        loadBindings('''
+                apiVersion: camel.apache.org/v1
+                kind: Pipe
+                metadata:
+                  name: timer-event-source                  
+                spec:
+                  source:
+                    ref:
+                      kind: Kamelet
+                      apiVersion: camel.apache.org/v1
+                      name: timer-source
+                    dataTypes:
+                      out:
+                        scheme: camel
+                        format: application/octet-stream    
+                    properties:
+                      message: "Hello world!"
+                  sink:
+                    ref:
+                      kind: Kamelet
+                      apiVersion: camel.apache.org/v1
+                      name: log-sink
+                    dataTypes:
+                      in:
+                        scheme: camel
+                        format: plain/text
+            ''')
+        then:
+        context.routeDefinitions.size() == 3
+
+        with (context.routeDefinitions[0]) {
+            routeId == 'timer-event-source'
+            input.endpointUri == 'kamelet:timer-source?message=Hello+world%21'
+            input.lineNumber == 7
+            outputs.size() == 3
+            with (outputs[0], TransformDefinition) {
+                fromType == 'camel:any'
+                toType == 'camel:application/octet-stream'
+                lineNumber == -1
+            }
+            with (outputs[1], TransformDefinition) {
+                fromType == 'camel:any'
+                toType == 'camel:plain/text'
+                lineNumber == -1
+            }
+            with (outputs[2], ToDefinition) {
+                endpointUri == 'kamelet:log-sink'
+                lineNumber == 18
+            }
+        }
+    }
+
 }