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

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

commit 7c3f908ec5b8a62d0dbf3e967aa495a1d8340fbe
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Wed May 12 07:51:49 2021 +0200

    CAMEL-16604: route template parameter should be able to be marked explicit 
as required.
---
 .../apache/camel/catalog/models/routeTemplate.json |  2 +-
 .../camel/catalog/models/templateParameter.json    |  7 ++-
 .../java/org/apache/camel/impl/DefaultModel.java   |  6 +-
 .../org/apache/camel/model/routeTemplate.json      |  2 +-
 .../org/apache/camel/model/templateParameter.json  |  7 ++-
 .../camel/model/RouteTemplateDefinition.java       | 43 ++++++++++++++-
 .../model/RouteTemplateParameterDefinition.java    | 27 +++++++--
 .../builder/RouteTemplateOptionalValueTest.java    | 64 ++++++++++++++++++++++
 .../java/org/apache/camel/xml/in/ModelParser.java  |  1 +
 .../dsl/yaml/deserializers/ModelDeserializers.java |  8 ++-
 .../src/generated/resources/camel-yaml-dsl.json    |  3 +
 11 files changed, 151 insertions(+), 19 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/routeTemplate.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/routeTemplate.json
index 954b665..25c4d73 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/routeTemplate.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/routeTemplate.json
@@ -11,7 +11,7 @@
     "output": true
   },
   "properties": {
-    "templateParameter": { "kind": "element", "displayName": "Template 
Parameter", "required": false, "type": "array", "javaType": 
"java.util.List<org.apache.camel.model.RouteTemplateParameterDefinition>", 
"deprecated": false, "autowired": false, "secret": false, "description": "Adds 
a parameter the route template uses." },
+    "templateParameter": { "kind": "element", "displayName": "Template 
Parameter", "required": false, "type": "array", "javaType": 
"java.util.List<org.apache.camel.model.RouteTemplateParameterDefinition>", 
"deprecated": false, "autowired": false, "secret": false, "description": "Adds 
a required parameter the route template uses." },
     "templateBean": { "kind": "element", "displayName": "Template Bean", 
"required": false, "type": "array", "javaType": 
"java.util.List<org.apache.camel.model.RouteTemplateBeanDefinition>", 
"deprecated": false, "autowired": false, "secret": false, "description": "Adds 
a local bean the route template uses." },
     "route": { "kind": "element", "displayName": "Route", "required": true, 
"type": "object", "javaType": "org.apache.camel.model.RouteDefinition", 
"deprecated": false, "autowired": false, "secret": false, "description": "To 
define the route in the template" },
     "id": { "kind": "attribute", "displayName": "Id", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Sets the id of this node" 
},
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/templateParameter.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/templateParameter.json
index 61aa987..bf2a558 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/templateParameter.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/templateParameter.json
@@ -11,8 +11,9 @@
     "output": false
   },
   "properties": {
-    "name": { "kind": "attribute", "displayName": "Name", "required": true, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Parameter name" },
-    "defaultValue": { "kind": "attribute", "displayName": "Default Value", 
"required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Parameter default value" },
-    "description": { "kind": "attribute", "displayName": "Description", 
"required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Parameter description" }
+    "name": { "kind": "attribute", "displayName": "Name", "required": true, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "The name of the parameter" 
},
+    "required": { "kind": "attribute", "displayName": "Required", "required": 
false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether the parameter is required or not. A parameter is required unless this 
option is set to false or a default value has been configured." },
+    "defaultValue": { "kind": "attribute", "displayName": "Default Value", 
"required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Default value of the parameter. If a default value is provided then the 
parameter is implied not to be required." },
+    "description": { "kind": "attribute", "displayName": "Description", 
"required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Description of the parameter" }
   }
 }
diff --git 
a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java 
b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java
index a9dd0ce..53b02cc 100644
--- 
a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java
+++ 
b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModel.java
@@ -262,8 +262,8 @@ public class DefaultModel implements Model {
                 if (temp.getDefaultValue() != null) {
                     prop.put(temp.getName(), temp.getDefaultValue());
                 } else {
-                    // this is a required parameter do we have that as input
-                    if 
(!routeTemplateContext.getParameters().containsKey(temp.getName())) {
+                    if (temp.isRequired() && 
!routeTemplateContext.getParameters().containsKey(temp.getName())) {
+                        // this is a required parameter which is missing
                         templatesBuilder.add(temp.getName());
                     }
                 }
@@ -271,7 +271,7 @@ public class DefaultModel implements Model {
             if (templatesBuilder.length() > 0) {
                 throw new IllegalArgumentException(
                         "Route template " + routeTemplateId + " the following 
mandatory parameters must be provided: "
-                                                   + 
templatesBuilder.toString());
+                                                   + templatesBuilder);
             }
         }
 
diff --git 
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/routeTemplate.json
 
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/routeTemplate.json
index 954b665..25c4d73 100644
--- 
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/routeTemplate.json
+++ 
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/routeTemplate.json
@@ -11,7 +11,7 @@
     "output": true
   },
   "properties": {
-    "templateParameter": { "kind": "element", "displayName": "Template 
Parameter", "required": false, "type": "array", "javaType": 
"java.util.List<org.apache.camel.model.RouteTemplateParameterDefinition>", 
"deprecated": false, "autowired": false, "secret": false, "description": "Adds 
a parameter the route template uses." },
+    "templateParameter": { "kind": "element", "displayName": "Template 
Parameter", "required": false, "type": "array", "javaType": 
"java.util.List<org.apache.camel.model.RouteTemplateParameterDefinition>", 
"deprecated": false, "autowired": false, "secret": false, "description": "Adds 
a required parameter the route template uses." },
     "templateBean": { "kind": "element", "displayName": "Template Bean", 
"required": false, "type": "array", "javaType": 
"java.util.List<org.apache.camel.model.RouteTemplateBeanDefinition>", 
"deprecated": false, "autowired": false, "secret": false, "description": "Adds 
a local bean the route template uses." },
     "route": { "kind": "element", "displayName": "Route", "required": true, 
"type": "object", "javaType": "org.apache.camel.model.RouteDefinition", 
"deprecated": false, "autowired": false, "secret": false, "description": "To 
define the route in the template" },
     "id": { "kind": "attribute", "displayName": "Id", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Sets the id of this node" 
},
diff --git 
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/templateParameter.json
 
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/templateParameter.json
index 61aa987..bf2a558 100644
--- 
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/templateParameter.json
+++ 
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/templateParameter.json
@@ -11,8 +11,9 @@
     "output": false
   },
   "properties": {
-    "name": { "kind": "attribute", "displayName": "Name", "required": true, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Parameter name" },
-    "defaultValue": { "kind": "attribute", "displayName": "Default Value", 
"required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Parameter default value" },
-    "description": { "kind": "attribute", "displayName": "Description", 
"required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Parameter description" }
+    "name": { "kind": "attribute", "displayName": "Name", "required": true, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "The name of the parameter" 
},
+    "required": { "kind": "attribute", "displayName": "Required", "required": 
false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether the parameter is required or not. A parameter is required unless this 
option is set to false or a default value has been configured." },
+    "defaultValue": { "kind": "attribute", "displayName": "Default Value", 
"required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Default value of the parameter. If a default value is provided then the 
parameter is implied not to be required." },
+    "description": { "kind": "attribute", "displayName": "Description", 
"required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Description of the parameter" }
   }
 }
diff --git 
a/core/camel-core-model/src/main/java/org/apache/camel/model/RouteTemplateDefinition.java
 
b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteTemplateDefinition.java
index 8d60711..81a5bc7 100644
--- 
a/core/camel-core-model/src/main/java/org/apache/camel/model/RouteTemplateDefinition.java
+++ 
b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteTemplateDefinition.java
@@ -135,7 +135,7 @@ public class RouteTemplateDefinition extends 
OptionalIdentifiedDefinition {
     }
 
     /**
-     * Adds a parameter the route template uses.
+     * Adds a required parameter the route template uses.
      *
      * @param name the name of the parameter
      */
@@ -145,7 +145,28 @@ public class RouteTemplateDefinition extends 
OptionalIdentifiedDefinition {
     }
 
     /**
-     * Adds a parameter the route template uses.
+     * Adds an optional parameter the route template uses.
+     *
+     * @param name the name of the parameter
+     */
+    public RouteTemplateDefinition templateOptionalParameter(String name) {
+        addTemplateOptionalParameter(name, null);
+        return this;
+    }
+
+    /**
+     * Adds an optional parameter the route template uses.
+     *
+     * @param name        the name of the parameter
+     * @param description the description of the parameter
+     */
+    public RouteTemplateDefinition templateOptionalParameter(String name, 
String description) {
+        addTemplateOptionalParameter(name, description);
+        return this;
+    }
+
+    /**
+     * Adds a parameter (will use default value if not provided) the route 
template uses.
      *
      * @param name         the name of the parameter
      * @param defaultValue default value of the parameter
@@ -156,10 +177,11 @@ public class RouteTemplateDefinition extends 
OptionalIdentifiedDefinition {
     }
 
     /**
-     * Adds a parameter the route template uses.
+     * Adds a parameter (will use default value if not provided) the route 
template uses.
      *
      * @param name         the name of the parameter
      * @param defaultValue default value of the parameter
+     * @param description  the description of the parameter
      */
     public RouteTemplateDefinition templateParameter(String name, String 
defaultValue, String description) {
         addTemplateParameter(name, defaultValue, description);
@@ -169,6 +191,9 @@ public class RouteTemplateDefinition extends 
OptionalIdentifiedDefinition {
     /**
      * Adds the parameters the route template uses.
      *
+     * The keys in the map is the parameter names, and the values are optional 
default value. If a parameter has no
+     * default value then the parameter is required.
+     *
      * @param parameters the parameters (only name and default values)
      */
     public RouteTemplateDefinition templateParameters(Map<String, String> 
parameters) {
@@ -327,6 +352,18 @@ public class RouteTemplateDefinition extends 
OptionalIdentifiedDefinition {
     }
 
     /**
+     * Adds an optional parameter the route template uses.
+     */
+    private void addTemplateOptionalParameter(String name, String description) 
{
+        if (this.templateParameters == null) {
+            this.templateParameters = new ArrayList<>();
+        }
+        RouteTemplateParameterDefinition def = new 
RouteTemplateParameterDefinition(name, null, description);
+        def.setRequired(false);
+        this.templateParameters.add(def);
+    }
+
+    /**
      * Creates a copy of this template as a {@link RouteDefinition} which can 
be used to add as a new route.
      */
     public RouteDefinition asRouteDefinition() {
diff --git 
a/core/camel-core-model/src/main/java/org/apache/camel/model/RouteTemplateParameterDefinition.java
 
b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteTemplateParameterDefinition.java
index 26ef63b..9beba20 100644
--- 
a/core/camel-core-model/src/main/java/org/apache/camel/model/RouteTemplateParameterDefinition.java
+++ 
b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteTemplateParameterDefinition.java
@@ -33,6 +33,8 @@ public class RouteTemplateParameterDefinition {
     @XmlAttribute(required = true)
     String name;
     @XmlAttribute
+    Boolean required;
+    @XmlAttribute
     String defaultValue;
     @XmlAttribute
     String description;
@@ -42,8 +44,13 @@ public class RouteTemplateParameterDefinition {
 
     public RouteTemplateParameterDefinition(String name, String defaultValue, 
String description) {
         this.name = name;
-        this.defaultValue = defaultValue;
         this.description = description;
+        this.defaultValue = defaultValue;
+    }
+
+    public boolean isRequired() {
+        // assumed to be required if not set explicit to false
+        return required == null || required;
     }
 
     public String getName() {
@@ -51,18 +58,30 @@ public class RouteTemplateParameterDefinition {
     }
 
     /**
-     * Parameter name
+     * The name of the parameter
      */
     public void setName(String name) {
         this.name = name;
     }
 
+    public Boolean getRequired() {
+        return required;
+    }
+
+    /**
+     * Whether the parameter is required or not. A parameter is required 
unless this option is set to false or a default
+     * value has been configured.
+     */
+    public void setRequired(Boolean required) {
+        this.required = required;
+    }
+
     public String getDefaultValue() {
         return defaultValue;
     }
 
     /**
-     * Parameter default value
+     * Default value of the parameter. If a default value is provided then the 
parameter is implied not to be required.
      */
     public void setDefaultValue(String defaultValue) {
         this.defaultValue = defaultValue;
@@ -73,7 +92,7 @@ public class RouteTemplateParameterDefinition {
     }
 
     /**
-     * Parameter description
+     * Description of the parameter
      */
     public void setDescription(String description) {
         this.description = description;
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/builder/RouteTemplateOptionalValueTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/builder/RouteTemplateOptionalValueTest.java
new file mode 100644
index 0000000..c4c4a59
--- /dev/null
+++ 
b/core/camel-core/src/test/java/org/apache/camel/builder/RouteTemplateOptionalValueTest.java
@@ -0,0 +1,64 @@
+/*
+ * 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.builder;
+
+import org.apache.camel.ContextTestSupport;
+import org.junit.jupiter.api.Test;
+
+public class RouteTemplateOptionalValueTest extends ContextTestSupport {
+
+    @Test
+    public void testOptionalProvided() throws Exception {
+        TemplatedRouteBuilder.builder(context, "myTemplate")
+                .parameter("foo", "start")
+                .parameter("myRetain", "1")
+                .routeId("myRoute")
+                .add();
+
+        getMockEndpoint("mock:result?retainFirst=1").expectedMessageCount(1);
+
+        template.sendBody("direct:start", "Hello World");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testOptional() throws Exception {
+        TemplatedRouteBuilder.builder(context, "myTemplate")
+                .parameter("foo", "start2")
+                .routeId("myRoute")
+                .add();
+
+        getMockEndpoint("mock:result").expectedMessageCount(1);
+
+        template.sendBody("direct:start2", "Bye World");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                
routeTemplate("myTemplate").templateParameter("foo").templateOptionalParameter("myRetain")
+                        .from("direct:{{foo}}")
+                        .to("mock:result?retainFirst={{?myRetain}}");
+            }
+        };
+    }
+}
diff --git 
a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java 
b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
index df6ce58..1413e68 100644
--- 
a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
+++ 
b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
@@ -1057,6 +1057,7 @@ public class ModelParser extends BaseParser {
                 case "defaultValue": def.setDefaultValue(val); break;
                 case "description": def.setDescription(val); break;
                 case "name": def.setName(val); break;
+                case "required": def.setRequired(Boolean.valueOf(val)); break;
                 default: return false;
             }
             return true;
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java
index b681d4a..8992959 100644
--- 
a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java
@@ -11793,7 +11793,8 @@ public final class ModelDeserializers extends 
YamlDeserializerSupport {
             properties = {
                     @YamlProperty(name = "default-value", type = "string"),
                     @YamlProperty(name = "description", type = "string"),
-                    @YamlProperty(name = "name", type = "string", required = 
true)
+                    @YamlProperty(name = "name", type = "string", required = 
true),
+                    @YamlProperty(name = "required", type = "boolean")
             }
     )
     public static class RouteTemplateParameterDefinitionDeserializer extends 
YamlDeserializerBase<RouteTemplateParameterDefinition> {
@@ -11825,6 +11826,11 @@ public final class ModelDeserializers extends 
YamlDeserializerSupport {
                     target.setName(val);
                     break;
                 }
+                case "required": {
+                    String val = asText(node);
+                    target.setRequired(java.lang.Boolean.valueOf(val));
+                    break;
+                }
                 default: {
                     return false;
                 }
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/camel-yaml-dsl.json 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/camel-yaml-dsl.json
index 99d1e9b..53c4660 100644
--- 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/camel-yaml-dsl.json
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/camel-yaml-dsl.json
@@ -2113,6 +2113,9 @@
           },
           "name" : {
             "type" : "string"
+          },
+          "required" : {
+            "type" : "boolean"
           }
         },
         "required" : [ "name" ]

Reply via email to