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 2022/08/10 11:56:16 UTC
[camel] 02/02: CAMEL-18366: camel-yaml-dsl - Allow to configure route options in route-templates/kamelets.
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
commit a760d0e1ab30c4284515ceee83eaa6df5070289a
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed Aug 10 13:55:26 2022 +0200
CAMEL-18366: camel-yaml-dsl - Allow to configure route options in route-templates/kamelets.
---
.../dsl/yaml/common/YamlDeserializerBase.java | 8 +++
.../common/exception/InvalidRouteException.java | 30 +++++++++
.../deserializers/RouteDefinitionDeserializer.java | 12 ++++
.../RouteTemplateDefinitionDeserializer.java | 22 ++++++-
.../generated/resources/schema/camel-yaml-dsl.json | 14 ++++-
.../generated/resources/schema/camelYamlDsl.json | 14 ++++-
.../camel/dsl/yaml/KameletBindingLoaderTest.groovy | 35 +++++++++++
.../apache/camel/dsl/yaml/RouteTemplateTest.groovy | 30 +++++++++
.../kamelets/route-timer-source.kamelet.yaml | 72 ++++++++++++++++++++++
9 files changed, 233 insertions(+), 4 deletions(-)
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 118b30d041e..9ad857c5f8a 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
@@ -63,6 +63,7 @@ public abstract class YamlDeserializerBase<T> extends YamlDeserializerSupport im
target = newInstance();
onNewTarget(node, target, line);
setProperties(target, mn);
+ afterPropertiesSet(target, mn);
} else {
throw new UnsupportedNodeTypeException(node);
}
@@ -77,6 +78,13 @@ public abstract class YamlDeserializerBase<T> extends YamlDeserializerSupport im
*/
protected abstract T newInstance();
+ /**
+ * Allows custom validation after the properties has been set on the target
+ */
+ protected void afterPropertiesSet(T target, Node node) {
+ // noop
+ }
+
/**
* Creates a Java instance of the expected type from a string.
*
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/exception/InvalidRouteException.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/exception/InvalidRouteException.java
new file mode 100644
index 00000000000..fc0a9fa53b4
--- /dev/null
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/exception/InvalidRouteException.java
@@ -0,0 +1,30 @@
+/*
+ * 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.exception;
+
+import java.util.Optional;
+
+import org.snakeyaml.engine.v2.exceptions.MarkedYamlEngineException;
+import org.snakeyaml.engine.v2.nodes.Node;
+
+public class InvalidRouteException extends MarkedYamlEngineException {
+
+ public InvalidRouteException(Node node, String message) {
+ super(null, Optional.empty(), message, node.getStartMark());
+ }
+
+}
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 719829d4272..f1d3c615a24 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
@@ -45,6 +45,9 @@ import org.snakeyaml.engine.v2.nodes.NodeTuple;
@YamlProperty(name = "route-policy", type = "string"),
@YamlProperty(name = "startup-order", type = "number"),
@YamlProperty(name = "stream-caching", type = "boolean"),
+ @YamlProperty(name = "message-history", type = "boolean"),
+ @YamlProperty(name = "log-mask", type = "boolean"),
+ @YamlProperty(name = "trace", type = "boolean"),
@YamlProperty(name = "from", type = "object:org.apache.camel.model.FromDefinition", required = true)
})
public class RouteDefinitionDeserializer extends YamlDeserializerBase<RouteDefinition> {
@@ -96,6 +99,15 @@ public class RouteDefinitionDeserializer extends YamlDeserializerBase<RouteDefin
case "stream-caching":
target.setStreamCache(asText(val));
break;
+ case "log-mask":
+ target.setLogMask(asText(val));
+ break;
+ case "message-history":
+ target.setMessageHistory(asText(val));
+ break;
+ case "trace":
+ target.setTrace(asText(val));
+ break;
case "from":
val.setProperty(RouteDefinition.class.getName(), target);
target.setInput(asType(val, FromDefinition.class));
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/RouteTemplateDefinitionDeserializer.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/RouteTemplateDefinitionDeserializer.java
index aaf0417b51f..f68aaae710c 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/RouteTemplateDefinitionDeserializer.java
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/RouteTemplateDefinitionDeserializer.java
@@ -19,6 +19,7 @@ package org.apache.camel.dsl.yaml.deserializers;
import java.util.List;
import org.apache.camel.dsl.yaml.common.YamlDeserializerBase;
+import org.apache.camel.dsl.yaml.common.exception.InvalidRouteException;
import org.apache.camel.model.RouteDefinition;
import org.apache.camel.model.RouteTemplateBeanDefinition;
import org.apache.camel.model.RouteTemplateDefinition;
@@ -37,9 +38,10 @@ import org.snakeyaml.engine.v2.nodes.Node;
@YamlProperty(name = "id",
type = "string",
required = true),
+ @YamlProperty(name = "route",
+ type = "object:org.apache.camel.model.RouteDefinition"),
@YamlProperty(name = "from",
- type = "object:org.apache.camel.model.FromDefinition",
- required = true),
+ type = "object:org.apache.camel.model.FromDefinition"),
@YamlProperty(name = "parameters",
type = "array:org.apache.camel.model.RouteTemplateParameterDefinition"),
@YamlProperty(name = "beans",
@@ -64,6 +66,11 @@ public class RouteTemplateDefinitionDeserializer extends YamlDeserializerBase<Ro
target.setId(asText(node));
break;
}
+ case "route": {
+ RouteDefinition route = asType(node, RouteDefinition.class);
+ target.setRoute(route);
+ break;
+ }
case "from": {
OutputAwareFromDefinition val = asType(node, OutputAwareFromDefinition.class);
RouteDefinition route = new RouteDefinition();
@@ -88,4 +95,15 @@ public class RouteTemplateDefinitionDeserializer extends YamlDeserializerBase<Ro
}
return true;
}
+
+ @Override
+ protected void afterPropertiesSet(RouteTemplateDefinition target, Node node) {
+ // either from or route must be set
+ if (target.getRoute() == null) {
+ throw new InvalidRouteException(node, "RouteTemplate must have route or from set");
+ }
+ if (target.getRoute().getInput() == null) {
+ throw new InvalidRouteException(node, "RouteTemplate must have from set");
+ }
+ }
}
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camel-yaml-dsl.json b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camel-yaml-dsl.json
index 7630c7f567d..abb996ff519 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camel-yaml-dsl.json
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camel-yaml-dsl.json
@@ -2421,6 +2421,12 @@
"id" : {
"type" : "string"
},
+ "log-mask" : {
+ "type" : "boolean"
+ },
+ "message-history" : {
+ "type" : "boolean"
+ },
"precondition" : {
"type" : "string"
},
@@ -2435,6 +2441,9 @@
},
"stream-caching" : {
"type" : "boolean"
+ },
+ "trace" : {
+ "type" : "boolean"
}
},
"required" : [ "from" ]
@@ -2486,9 +2495,12 @@
"items" : {
"$ref" : "#/items/definitions/org.apache.camel.model.RouteTemplateParameterDefinition"
}
+ },
+ "route" : {
+ "$ref" : "#/items/definitions/org.apache.camel.model.RouteDefinition"
}
},
- "required" : [ "from", "id" ]
+ "required" : [ "id" ]
},
"org.apache.camel.model.RouteTemplateParameterDefinition" : {
"type" : "object",
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json
index 800351a0e61..9a159975e99 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json
@@ -2325,6 +2325,12 @@
"id" : {
"type" : "string"
},
+ "logMask" : {
+ "type" : "boolean"
+ },
+ "messageHistory" : {
+ "type" : "boolean"
+ },
"precondition" : {
"type" : "string"
},
@@ -2339,6 +2345,9 @@
},
"streamCaching" : {
"type" : "boolean"
+ },
+ "trace" : {
+ "type" : "boolean"
}
},
"required" : [ "from" ]
@@ -2390,9 +2399,12 @@
"items" : {
"$ref" : "#/items/definitions/org.apache.camel.model.RouteTemplateParameterDefinition"
}
+ },
+ "route" : {
+ "$ref" : "#/items/definitions/org.apache.camel.model.RouteDefinition"
}
},
- "required" : [ "from", "id" ]
+ "required" : [ "id" ]
},
"org.apache.camel.model.RouteTemplateParameterDefinition" : {
"type" : "object",
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 a4c4a97ae64..096aedf01d1 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
@@ -552,4 +552,39 @@ class KameletBindingLoaderTest extends YamlTestSupport {
}
}
+ def "kamelet start route"() {
+ 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: route-timer-source
+ properties:
+ message: "Hello world!"
+ sink:
+ ref:
+ kind: Kamelet
+ apiVersion: camel.apache.org/v1
+ name: log-sink
+ ''')
+ then:
+ context.routeDefinitions.size() == 3
+
+ // global stream caching enabled
+ context.streamCaching == true
+
+ with (context.routeDefinitions[1]) {
+ template == true
+ // stream-caching is disabled in the kamelet
+ streamCache == "false"
+ messageHistory == "true"
+ }
+ }
+
}
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/RouteTemplateTest.groovy b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/RouteTemplateTest.groovy
index 7fba412d4fa..362eb48a614 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/RouteTemplateTest.groovy
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/RouteTemplateTest.groovy
@@ -20,6 +20,7 @@ import org.apache.camel.component.mock.MockEndpoint
import org.apache.camel.dsl.yaml.support.YamlTestSupport
import org.apache.camel.dsl.yaml.support.model.MySetBody
import org.apache.camel.dsl.yaml.support.model.MyUppercaseProcessor
+import org.apache.camel.impl.engine.DefaultRoute
import org.apache.camel.model.LogDefinition
import org.apache.camel.model.RouteTemplateDefinition
import org.apache.camel.model.ToDefinition
@@ -454,4 +455,33 @@ class RouteTemplateTest extends YamlTestSupport {
}
}
+ def "create route-template with route"() {
+ setup:
+ loadRoutes """
+ - route-template:
+ id: "myTemplate"
+ parameters:
+ - name: "foo"
+ - name: "bar"
+ route:
+ stream-caching: false
+ message-history: true
+ log-mask: true
+ from:
+ uri: "direct:{{foo}}"
+ steps:
+ - to: "mock:{{bar}}"
+ """
+ when:
+ context.addRouteFromTemplate('myId', 'myTemplate', [foo: "start", bar: "result"])
+ context.start()
+
+ then:
+ with(context.routes[0], DefaultRoute) {
+ it.isStreamCaching() == false
+ it.isMessageHistory() == true
+ it.isLogMask() == true
+ }
+ }
+
}
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/resources/kamelets/route-timer-source.kamelet.yaml b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/resources/kamelets/route-timer-source.kamelet.yaml
new file mode 100644
index 00000000000..08dd0217d75
--- /dev/null
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/resources/kamelets/route-timer-source.kamelet.yaml
@@ -0,0 +1,72 @@
+# ---------------------------------------------------------------------------
+# 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: route-timer-source
+ annotations:
+ camel.apache.org/kamelet.support.level: "Preview"
+ camel.apache.org/catalog.version: "main-SNAPSHOT"
+ camel.apache.org/kamelet.icon: data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gU3ZnIFZlY3RvciBJY29ucyA6IGh0dHA6Ly93d3cub25saW5ld2ViZm9udHMuY29tL2ljb24gLS0+DQo8IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPg0KPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm9 [...]
+ camel.apache.org/provider: "Apache Software Foundation"
+ camel.apache.org/kamelet.group: "Route Timer"
+ labels:
+ camel.apache.org/kamelet.type: source
+ camel.apache.org/kamelet.verified: "true"
+spec:
+ definition:
+ title: Timer Source
+ description: Produces periodic events with a custom payload.
+ required:
+ - message
+ type: object
+ properties:
+ period:
+ title: Period
+ description: The interval between two events in milliseconds
+ type: integer
+ default: 1000
+ message:
+ title: Message
+ description: The message to generate
+ type: string
+ example: hello world
+ contentType:
+ title: Content Type
+ description: The content type of the message being generated
+ type: string
+ default: text/plain
+ dependencies:
+ - "camel:core"
+ - "camel:timer"
+ - "camel:kamelet"
+ template:
+ route:
+ stream-caching: false
+ message-history: true
+ from:
+ uri: timer:tick
+ parameters:
+ period: "{{period}}"
+ steps:
+ - set-body:
+ constant: "{{message}}"
+ - set-header:
+ name: "Content-Type"
+ constant: "{{contentType}}"
+ - to: kamelet:sink
\ No newline at end of file