This is an automated email from the ASF dual-hosted git repository. lburgazzoli 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 85aafb6 YAML DSL: support Kamelet optional parameter 85aafb6 is described below commit 85aafb6e96e9c579d12c06c2e865d8cb080e26fe Author: Luca Burgazzoli <lburgazz...@gmail.com> AuthorDate: Wed May 12 15:21:25 2021 +0200 YAML DSL: support Kamelet optional parameter --- .../dsl/yaml/common/YamlDeserializerSupport.java | 18 +++++++- .../camel/dsl/yaml/KameletRoutesBuilderLoader.java | 21 ++++++++- .../apache/camel/dsl/yaml/KameletLoaderTest.groovy | 52 ++++++++++++++++++++++ 3 files changed, 88 insertions(+), 3 deletions(-) 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 8ddd141..bceef93 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 @@ -22,6 +22,7 @@ import java.util.Base64; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -98,7 +99,7 @@ public class YamlDeserializerSupport { return null; } - List<String> answer; + final List<String> answer; if (node.getNodeType() == NodeType.SCALAR) { answer = asStringList(asText(node)); @@ -119,7 +120,20 @@ public class YamlDeserializerSupport { return null; } - return asStringSet(asText(node)); + final Set<String> answer; + + if (node.getNodeType() == NodeType.SCALAR) { + answer = asStringSet(asText(node)); + } else if (node.getNodeType() == NodeType.SEQUENCE) { + answer = new LinkedHashSet<>(); + for (Node item : asSequenceNode(node).getValue()) { + answer.add(asText(item)); + } + } else { + throw new UnsupportedNodeTypeException(node); + } + + return answer; } public static Class<?>[] asClassArray(Node node) throws YamlDeserializationException { diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/java/org/apache/camel/dsl/yaml/KameletRoutesBuilderLoader.java b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/java/org/apache/camel/dsl/yaml/KameletRoutesBuilderLoader.java index 9502a8b..c8ed68d 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/java/org/apache/camel/dsl/yaml/KameletRoutesBuilderLoader.java +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/java/org/apache/camel/dsl/yaml/KameletRoutesBuilderLoader.java @@ -16,15 +16,21 @@ */ package org.apache.camel.dsl.yaml; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Set; + import org.apache.camel.api.management.ManagedResource; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.dsl.yaml.common.YamlDeserializationContext; import org.apache.camel.model.RouteTemplateDefinition; +import org.apache.camel.model.RouteTemplateParameterDefinition; import org.apache.camel.spi.annotations.RoutesLoader; import org.snakeyaml.engine.v2.nodes.Node; import org.snakeyaml.engine.v2.nodes.NodeTuple; import static org.apache.camel.dsl.yaml.common.YamlDeserializerSupport.asMappingNode; +import static org.apache.camel.dsl.yaml.common.YamlDeserializerSupport.asStringSet; import static org.apache.camel.dsl.yaml.common.YamlDeserializerSupport.asText; import static org.apache.camel.dsl.yaml.common.YamlDeserializerSupport.nodeAt; @@ -48,6 +54,11 @@ public class KameletRoutesBuilderLoader extends YamlRoutesBuilderLoaderSupport { throw new IllegalArgumentException("No template defined"); } + Set<String> required = asStringSet(nodeAt(node, "/spec/definition/required")); + if (required == null) { + required = Collections.emptySet(); + } + final YamlDeserializationContext context = this.getDeserializationContext(); final RouteTemplateDefinition rtd = context.construct(template, RouteTemplateDefinition.class); @@ -55,11 +66,19 @@ public class KameletRoutesBuilderLoader extends YamlRoutesBuilderLoaderSupport { Node properties = nodeAt(node, "/spec/definition/properties"); if (properties != null) { + + rtd.setTemplateParameters(new ArrayList<>()); + for (NodeTuple p : asMappingNode(properties).getValue()) { final String key = asText(p.getKeyNode()); final Node def = nodeAt(p.getValueNode(), "/default"); - rtd.templateParameter(key, asText(def)); + RouteTemplateParameterDefinition rtpd = new RouteTemplateParameterDefinition(); + rtpd.setName(key); + rtpd.setDefaultValue(asText(def)); + rtpd.setRequired(required.contains(key)); + + rtd.getTemplateParameters().add(rtpd); } } diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/KameletLoaderTest.groovy b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/KameletLoaderTest.groovy index d3ae630..412bf01 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/KameletLoaderTest.groovy +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/KameletLoaderTest.groovy @@ -18,6 +18,7 @@ package org.apache.camel.dsl.yaml import org.apache.camel.component.mock.MockEndpoint import org.apache.camel.dsl.yaml.support.YamlTestSupport +import org.apache.camel.model.RouteTemplateDefinition import org.apache.camel.model.ToDefinition class KameletLoaderTest extends YamlTestSupport { @@ -174,6 +175,57 @@ class KameletLoaderTest extends YamlTestSupport { } } + def "kamelet with template and optional parameters"() { + setup: + loadKamelets """ + apiVersion: camel.apache.org/v1alpha1 + kind: Kamelet + metadata: + name: myTemplate + spec: + definition: + required: + - foo + - mockName + properties: + mockName: + type: string + foo: + type: string + bar: + type: string + template: + from: + uri: "kamelet:source" + steps: + - to: "mock:{{mockName}}?retainFirst={{?bar}}" + """ + when: + withTemplate { + to('kamelet:myTemplate?mockName=1&foo=start&bar=1').withBody('Hello 1').send() + to('kamelet:myTemplate?mockName=2&foo=start').withBody('Hello 2').send() + } + then: + with(context.routeTemplateDefinitions[0], RouteTemplateDefinition) { + id == 'myTemplate' + + templateParameters.any { + it.name == 'foo' && it.defaultValue == null && it.isRequired() + } + templateParameters.any { + it.name == 'bar' && it.defaultValue == null && !it.isRequired() + } + } + with(context.getEndpoint("mock:1?retainFirst=1", MockEndpoint)) { + expectedBodiesReceived("Hello World") + assertIsSatisfied() + } + with(context.getEndpoint("mock:2", MockEndpoint)) { + expectedBodiesReceived("Bye World") + assertIsSatisfied() + } + } + def "kamelet discovery"() { setup: def payload = UUID.randomUUID().toString()