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/12/30 11:21:19 UTC

[camel] branch main updated: CAMEL-18848: camel-core-model - Rest DSL allowedValues should use definition model for value

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


The following commit(s) were added to refs/heads/main by this push:
     new 28f4ae0d94a CAMEL-18848: camel-core-model - Rest DSL allowedValues should use definition model for value
28f4ae0d94a is described below

commit 28f4ae0d94a502ea6b8d941e005c948df9ac218c
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Fri Dec 30 12:20:58 2022 +0100

    CAMEL-18848: camel-core-model - Rest DSL allowedValues should use definition model for value
---
 .../org/apache/camel/catalog/models.properties     |   2 +
 .../org/apache/camel/catalog/models/param.json     |   3 +-
 .../camel/catalog/models/responseHeader.json       |   2 +-
 .../org/apache/camel/catalog/models/value.json     |  17 +
 .../apache/camel/catalog/schemas/camel-spring.xsd  |  38 +-
 .../apache/camel/openapi/RestOpenApiReader.java    |  12 +-
 .../org/apache/camel/spring/RoutePropertyTest.java |  42 ++
 .../org/apache/camel/spring/RoutePropertyTest.xml  |  35 +
 .../apache/camel/swagger/RestSwaggerReader.java    |  22 +-
 .../services/org/apache/camel/model.properties     |   1 +
 .../resources/org/apache/camel/model/jaxb.index    |   1 +
 .../org/apache/camel/model/rest/param.json         |   3 +-
 .../apache/camel/model/rest/responseHeader.json    |   2 +-
 .../resources/org/apache/camel/model/value.json    |  17 +
 .../org/apache/camel/model/RouteDefinition.java    |   2 +-
 .../org/apache/camel/model/ValueDefinition.java    |  57 ++
 .../apache/camel/model/rest/ParamDefinition.java   |  50 +-
 .../camel/model/rest/ResponseHeaderDefinition.java |  55 +-
 .../camel/component/rest/FromRestGetTest.java      |  10 +-
 .../java/org/apache/camel/main/MainSupport.java    |   4 +-
 .../java/org/apache/camel/xml/in/ModelParser.java  |   9 +-
 .../java/org/apache/camel/xml/in/BaseParser.java   |  64 +-
 .../org/apache/camel/xml/in/ModelParserTest.java   |  38 +-
 .../src/test/resources/restAllowedValues.xml       |  42 ++
 .../src/test/resources/routeProperty.xml           |  32 +
 .../ROOT/pages/camel-3x-upgrade-guide-3_20.adoc    |   6 +
 .../dsl/yaml/deserializers/ModelDeserializers.java |  62 +-
 .../deserializers/ModelDeserializersResolver.java  |   2 +
 .../generated/resources/schema/camel-yaml-dsl.json |  42 +-
 .../generated/resources/schema/camelYamlDsl.json   |  42 +-
 .../org/apache/camel/dsl/yaml/RestTest.groovy      |  21 +
 .../routes/rest-allowable-values-dsl.yaml          |  19 +
 .../packaging/ModelXmlParserGeneratorMojo.java     |  25 +-
 .../camel/maven/packaging/SchemaGeneratorMojo.java |  24 +-
 .../generator/openapi/RestDslYamlGenerator.java    |  15 +
 .../openapi/RestDslYamlGeneratorV302Test.java      |  62 ++
 .../src/test/resources/OpenApiV302PetstoreYaml.txt | 231 ++++++
 .../camel/generator/openapi/petstore-v3.yaml       | 819 +++++++++++++++++++++
 38 files changed, 1789 insertions(+), 141 deletions(-)

diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models.properties b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models.properties
index 26b1ed52416..1f8171a834c 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models.properties
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models.properties
@@ -1,4 +1,5 @@
 aggregate
+allowedValue
 any23
 apiKey
 asn1
@@ -211,6 +212,7 @@ univocityTsv
 unmarshal
 validate
 validators
+value
 weighted
 when
 whenSkipSendToEndpoint
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/param.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/param.json
index dbf7274d326..72e0f850dc3 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/param.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/param.json
@@ -20,8 +20,7 @@
     "arrayType": { "kind": "attribute", "displayName": "Array Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "string", "description": "Sets the parameter array type. Required if data type is array. Describes the type of items in the array." },
     "dataType": { "kind": "attribute", "displayName": "Data Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "string", "description": "Sets the parameter data type." },
     "dataFormat": { "kind": "attribute", "displayName": "Data Format", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the parameter data format." },
-    "value": { "kind": "element", "displayName": "Value", "required": false, "type": "array", "javaType": "java.util.List<java.lang.String>", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the parameter list of allowable values (enum)." },
-    "examples": { "kind": "element", "displayName": "Examples", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.rest.RestPropertyDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the parameter examples." },
+    "allowableValue": { "kind": "element", "displayName": "Allowable Value", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ValueDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the parameter list of allowable values (enum)." },
     "description": { "kind": "attribute", "displayName": "Description", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the parameter description." }
   }
 }
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/responseHeader.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/responseHeader.json
index c801389293e..7f3ce3cfdb2 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/responseHeader.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/responseHeader.json
@@ -17,7 +17,7 @@
     "arrayType": { "kind": "attribute", "displayName": "Array Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "string", "description": "Sets the parameter array type. Required if data type is array. Describes the type of items in the array." },
     "dataType": { "kind": "attribute", "displayName": "Data Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "string", "description": "Sets the header data type." },
     "dataFormat": { "kind": "attribute", "displayName": "Data Format", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the parameter data format." },
-    "value": { "kind": "element", "displayName": "Value", "required": false, "type": "array", "javaType": "java.util.List<java.lang.String>", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the parameter list of allowable values." },
+    "value": { "kind": "element", "displayName": "Value", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ValueDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the parameter list of allowable values." },
     "example": { "kind": "attribute", "displayName": "Example", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the example" },
     "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/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/value.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/value.json
new file mode 100644
index 00000000000..6e6e8f42d7d
--- /dev/null
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/value.json
@@ -0,0 +1,17 @@
+{
+  "model": {
+    "kind": "model",
+    "name": "value",
+    "title": "Value",
+    "description": "A single value",
+    "deprecated": false,
+    "label": "configuration",
+    "javaType": "org.apache.camel.model.ValueDefinition",
+    "abstract": false,
+    "input": false,
+    "output": false
+  },
+  "properties": {
+    "value": { "kind": "value", "displayName": "Value", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Property value" }
+  }
+}
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd
index 70ecb406339..b3c62dfff77 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd
@@ -2376,6 +2376,16 @@ To configure validators.
     </xs:annotation>
   </xs:element>
     
+  <xs:element name="value" type="tns:valueDefinition">
+    <xs:annotation>
+      <xs:documentation xml:lang="en">
+        <![CDATA[
+A single value
+      ]]>
+      </xs:documentation>
+    </xs:annotation>
+  </xs:element>
+    
   <xs:element name="weighted" type="tns:weightedLoadBalancerDefinition">
     <xs:annotation>
       <xs:documentation xml:lang="en">
@@ -18956,6 +18966,12 @@ exception to throw instead.
       
   </xs:complexType>
     
+  <xs:simpleType name="valueDefinition">
+        
+    <xs:restriction base="xs:string"/>
+      
+  </xs:simpleType>
+    
   <xs:complexType name="wireTapDefinition">
         
     <xs:complexContent>
@@ -21387,7 +21403,7 @@ Sets the id of the route.
                     
           <xs:sequence>
                         
-            <xs:element maxOccurs="unbounded" minOccurs="0" name="value" type="xs:string">
+            <xs:element maxOccurs="unbounded" minOccurs="0" name="allowableValue" type="tns:valueDefinition">
               <xs:annotation>
                 <xs:documentation xml:lang="en">
                   <![CDATA[
@@ -21403,15 +21419,7 @@ Sets the parameter list of allowable values (enum).
               
       </xs:element>
             
-      <xs:element maxOccurs="unbounded" minOccurs="0" name="examples" type="tns:restPropertyDefinition">
-        <xs:annotation>
-          <xs:documentation xml:lang="en">
-            <![CDATA[
-Sets the parameter examples.
-          ]]>
-          </xs:documentation>
-        </xs:annotation>
-      </xs:element>
+      <xs:element maxOccurs="unbounded" minOccurs="0" name="examples" nillable="true" type="tns:restPropertyDefinition"/>
           
     </xs:sequence>
         
@@ -21602,15 +21610,7 @@ The response model.
                     
           <xs:sequence>
                         
-            <xs:element maxOccurs="unbounded" minOccurs="0" name="value" type="xs:string">
-              <xs:annotation>
-                <xs:documentation xml:lang="en">
-                  <![CDATA[
-Sets the parameter list of allowable values.
-                ]]>
-                </xs:documentation>
-              </xs:annotation>
-            </xs:element>
+            <xs:element maxOccurs="unbounded" minOccurs="0" ref="tns:value"/>
                       
           </xs:sequence>
                   
diff --git a/components/camel-openapi-java/src/main/java/org/apache/camel/openapi/RestOpenApiReader.java b/components/camel-openapi-java/src/main/java/org/apache/camel/openapi/RestOpenApiReader.java
index 767bb043a6f..14956d3442a 100644
--- a/components/camel-openapi-java/src/main/java/org/apache/camel/openapi/RestOpenApiReader.java
+++ b/components/camel-openapi-java/src/main/java/org/apache/camel/openapi/RestOpenApiReader.java
@@ -626,7 +626,7 @@ public class RestOpenApiReader {
                     Oas30Parameter parameter30 = (Oas30Parameter) parameter;
                     Oas30Schema oas30Schema = null;
                     final boolean isArray = getValue(camelContext, param.getDataType()).equalsIgnoreCase("array");
-                    final List<String> allowableValues = getValue(camelContext, param.getAllowableValues());
+                    final List<String> allowableValues = getValue(camelContext, param.getAllowableValuesAsStringList());
                     final boolean hasAllowableValues = allowableValues != null && !allowableValues.isEmpty();
                     if (param.getDataType() != null) {
                         parameter30.schema = parameter30.createSchema();
@@ -869,7 +869,7 @@ public class RestOpenApiReader {
 
                     Oas20Parameter serializableParameter = (Oas20Parameter) parameter;
                     final boolean isArray = getValue(camelContext, param.getDataType()).equalsIgnoreCase("array");
-                    final List<String> allowableValues = getValue(camelContext, param.getAllowableValues());
+                    final List<String> allowableValues = getValue(camelContext, param.getAllowableValuesAsStringList());
                     final boolean hasAllowableValues = allowableValues != null && !allowableValues.isEmpty();
                     if (param.getDataType() != null) {
                         serializableParameter.type = param.getDataType();
@@ -1234,9 +1234,9 @@ public class RestOpenApiReader {
         ip.description = getValue(camelContext, header.getDescription());
 
         List<String> values;
-        if (!header.getAllowableValues().isEmpty()) {
+        if (header.getAllowableValues() != null) {
             values = new ArrayList<>();
-            for (String text : header.getAllowableValues()) {
+            for (String text : header.getAllowableValuesAsStringList()) {
                 values.add(getValue(camelContext, text));
             }
             schema.enum_ = values;
@@ -1349,9 +1349,9 @@ public class RestOpenApiReader {
         ip.description = getValue(camelContext, header.getDescription());
 
         List<String> values;
-        if (!header.getAllowableValues().isEmpty()) {
+        if (header.getAllowableValues() != null) {
             values = new ArrayList<>();
-            for (String text : header.getAllowableValues()) {
+            for (String text : header.getAllowableValuesAsStringList()) {
                 values.add(getValue(camelContext, text));
             }
             ip.enum_ = values;
diff --git a/components/camel-spring-xml/src/test/java/org/apache/camel/spring/RoutePropertyTest.java b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/RoutePropertyTest.java
new file mode 100644
index 00000000000..7755b7133ec
--- /dev/null
+++ b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/RoutePropertyTest.java
@@ -0,0 +1,42 @@
+/*
+ * 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.spring;
+
+import java.util.Map;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.springframework.context.support.AbstractXmlApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+class RoutePropertyTest extends SpringTestSupport {
+
+    @Override
+    protected AbstractXmlApplicationContext createApplicationContext() {
+        return new ClassPathXmlApplicationContext("org/apache/camel/spring/RoutePropertyTest.xml");
+    }
+
+    @Test
+    void testRouteProperties() throws Exception {
+        assertCollectionSize(context.getRouteDefinitions(), 1);
+        assertCollectionSize(context.getRoutes(), 1);
+
+        Map<String, Object> map = context.getRoutes().get(0).getProperties();
+        Assertions.assertEquals("1", map.get("a"));
+        Assertions.assertEquals("2", map.get("b"));
+    }
+}
diff --git a/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/RoutePropertyTest.xml b/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/RoutePropertyTest.xml
new file mode 100644
index 00000000000..e4abd1645a9
--- /dev/null
+++ b/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/RoutePropertyTest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="
+            http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
+            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+    <camelContext xmlns="http://camel.apache.org/schema/spring">
+        <route id="myRoute">
+            <routeProperty key="a" value="1"/>
+            <routeProperty key="b" value="2"/>
+            <from uri="direct:start"/>
+            <to uri="mock:result"/>
+        </route>
+    </camelContext>
+
+</beans>
diff --git a/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/RestSwaggerReader.java b/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/RestSwaggerReader.java
index 5de65ccde4b..3ec642686aa 100644
--- a/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/RestSwaggerReader.java
+++ b/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/RestSwaggerReader.java
@@ -348,7 +348,7 @@ public class RestSwaggerReader {
                         SerializableParameter serializableParameter = (SerializableParameter) parameter;
 
                         final boolean isArray = param.getDataType().equalsIgnoreCase("array");
-                        final List<String> allowableValues = param.getAllowableValues();
+                        final List<String> allowableValues = param.getAllowableValuesAsStringList();
                         final boolean hasAllowableValues = allowableValues != null && !allowableValues.isEmpty();
                         if (param.getDataType() != null) {
                             serializableParameter.setType(param.getDataType());
@@ -530,8 +530,8 @@ public class RestSwaggerReader {
                             sp.setFormat(format);
                         }
                         sp.setDescription(header.getDescription());
-                        if (!header.getAllowableValues().isEmpty()) {
-                            sp.setEnum(header.getAllowableValues());
+                        if (header.getAllowableValues() != null) {
+                            sp.setEnum(header.getAllowableValuesAsStringList());
                         }
                         // add example
                         if (header.getExample() != null) {
@@ -547,9 +547,9 @@ public class RestSwaggerReader {
                         ip.setDescription(header.getDescription());
 
                         List<Integer> values;
-                        if (!header.getAllowableValues().isEmpty()) {
+                        if (header.getAllowableValues() != null) {
                             values = new ArrayList<>();
-                            for (String text : header.getAllowableValues()) {
+                            for (String text : header.getAllowableValuesAsStringList()) {
                                 values.add(Integer.valueOf(text));
                             }
                             ip.setEnum(values);
@@ -568,9 +568,9 @@ public class RestSwaggerReader {
                         lp.setDescription(header.getDescription());
 
                         List<Long> values;
-                        if (!header.getAllowableValues().isEmpty()) {
+                        if (header.getAllowableValues() != null) {
                             values = new ArrayList<>();
-                            for (String text : header.getAllowableValues()) {
+                            for (String text : header.getAllowableValuesAsStringList()) {
                                 values.add(Long.valueOf(text));
                             }
                             lp.setEnum(values);
@@ -589,9 +589,9 @@ public class RestSwaggerReader {
                         fp.setDescription(header.getDescription());
 
                         List<Float> values;
-                        if (!header.getAllowableValues().isEmpty()) {
+                        if (header.getAllowableValues() != null) {
                             values = new ArrayList<>();
-                            for (String text : header.getAllowableValues()) {
+                            for (String text : header.getAllowableValuesAsStringList()) {
                                 values.add(Float.valueOf(text));
                             }
                             fp.setEnum(values);
@@ -610,9 +610,9 @@ public class RestSwaggerReader {
                         dp.setDescription(header.getDescription());
 
                         List<Double> values;
-                        if (!header.getAllowableValues().isEmpty()) {
+                        if (header.getAllowableValues() != null) {
                             values = new ArrayList<>();
-                            for (String text : header.getAllowableValues()) {
+                            for (String text : header.getAllowableValuesAsStringList()) {
                                 values.add(Double.valueOf(text));
                             }
                             dp.setEnum(values);
diff --git a/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/model.properties b/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/model.properties
index 4a8d56954e0..d6fe889aad1 100644
--- a/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/model.properties
+++ b/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/model.properties
@@ -212,6 +212,7 @@ univocityTsv
 unmarshal
 validate
 validators
+value
 weighted
 when
 whenSkipSendToEndpoint
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/jaxb.index b/core/camel-core-model/src/generated/resources/org/apache/camel/model/jaxb.index
index 6fb29c0d233..520b73327a1 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/jaxb.index
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/jaxb.index
@@ -105,5 +105,6 @@ TransformDefinition
 TryDefinition
 UnmarshalDefinition
 ValidateDefinition
+ValueDefinition
 WhenDefinition
 WireTapDefinition
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/param.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/param.json
index dbf7274d326..dfbf215e6c1 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/param.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/param.json
@@ -20,8 +20,7 @@
     "arrayType": { "kind": "attribute", "displayName": "Array Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "string", "description": "Sets the parameter array type. Required if data type is array. Describes the type of items in the array." },
     "dataType": { "kind": "attribute", "displayName": "Data Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "string", "description": "Sets the parameter data type." },
     "dataFormat": { "kind": "attribute", "displayName": "Data Format", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the parameter data format." },
-    "value": { "kind": "element", "displayName": "Value", "required": false, "type": "array", "javaType": "java.util.List<java.lang.String>", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the parameter list of allowable values (enum)." },
-    "examples": { "kind": "element", "displayName": "Examples", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.rest.RestPropertyDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the parameter examples." },
+    "allowableValues": { "kind": "element", "displayName": "Allowable Values", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ValueDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the parameter list of allowable values (enum)." },
     "description": { "kind": "attribute", "displayName": "Description", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the parameter description." }
   }
 }
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/responseHeader.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/responseHeader.json
index c801389293e..e4712c127a5 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/responseHeader.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/rest/responseHeader.json
@@ -17,7 +17,7 @@
     "arrayType": { "kind": "attribute", "displayName": "Array Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "string", "description": "Sets the parameter array type. Required if data type is array. Describes the type of items in the array." },
     "dataType": { "kind": "attribute", "displayName": "Data Type", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "string", "description": "Sets the header data type." },
     "dataFormat": { "kind": "attribute", "displayName": "Data Format", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the parameter data format." },
-    "value": { "kind": "element", "displayName": "Value", "required": false, "type": "array", "javaType": "java.util.List<java.lang.String>", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the parameter list of allowable values." },
+    "allowableValues": { "kind": "element", "displayName": "Allowable Values", "required": false, "type": "array", "javaType": "java.util.List<org.apache.camel.model.ValueDefinition>", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the parameter list of allowable values." },
     "example": { "kind": "attribute", "displayName": "Example", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the example" },
     "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/generated/resources/org/apache/camel/model/value.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/value.json
new file mode 100644
index 00000000000..6e6e8f42d7d
--- /dev/null
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/value.json
@@ -0,0 +1,17 @@
+{
+  "model": {
+    "kind": "model",
+    "name": "value",
+    "title": "Value",
+    "description": "A single value",
+    "deprecated": false,
+    "label": "configuration",
+    "javaType": "org.apache.camel.model.ValueDefinition",
+    "abstract": false,
+    "input": false,
+    "output": false
+  },
+  "properties": {
+    "value": { "kind": "value", "displayName": "Value", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Property value" }
+  }
+}
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/RouteDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteDefinition.java
index ea92bc4611b..bc72d9543ed 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/model/RouteDefinition.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteDefinition.java
@@ -56,7 +56,7 @@ import org.apache.camel.spi.RoutePolicy;
  */
 @Metadata(label = "configuration")
 @XmlRootElement(name = "route")
-@XmlType(propOrder = { "input", "inputType", "outputType", "outputs", "routeProperties" })
+@XmlType(propOrder = { "routeProperties", "input", "inputType", "outputType", "outputs" })
 @XmlAccessorType(XmlAccessType.PROPERTY)
 // must use XmlAccessType.PROPERTY as there is some custom logic needed to be executed in the setter methods
 public class RouteDefinition extends OutputDefinition<RouteDefinition>
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/ValueDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/ValueDefinition.java
new file mode 100644
index 00000000000..160b80c05ed
--- /dev/null
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/ValueDefinition.java
@@ -0,0 +1,57 @@
+/*
+ * 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.model;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlValue;
+
+import org.apache.camel.spi.Metadata;
+
+/**
+ * A single value
+ */
+@Metadata(label = "configuration")
+@XmlRootElement(name = "value")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class ValueDefinition {
+
+    @XmlValue
+    private String value;
+
+    public ValueDefinition() {
+    }
+
+    public ValueDefinition(String value) {
+        this.value = value;
+    }
+
+    /**
+     * Property value
+     */
+    public String getValue() {
+        return value;
+    }
+
+    /**
+     * Property value
+     */
+    public void setValue(String value) {
+        this.value = value;
+    }
+}
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/rest/ParamDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/rest/ParamDefinition.java
index 3d707b9b121..d20dc7eee67 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/model/rest/ParamDefinition.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/rest/ParamDefinition.java
@@ -17,7 +17,7 @@
 package org.apache.camel.model.rest;
 
 import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 
 import javax.xml.bind.annotation.XmlAccessType;
@@ -28,7 +28,9 @@ import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlTransient;
 
+import org.apache.camel.model.ValueDefinition;
 import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.annotations.DslProperty;
 import org.apache.camel.util.StringHelper;
 
 /**
@@ -66,9 +68,9 @@ public class ParamDefinition {
     @XmlAttribute
     private String dataFormat;
     @XmlElementWrapper(name = "allowableValues")
-    @XmlElement(name = "value")
-    private List<String> allowableValues;
-    @XmlElement(name = "examples")
+    @XmlElement(name = "value") // name = value due to camel-spring-xml
+    @DslProperty(name = "allowableValues") // yaml-dsl
+    private List<ValueDefinition> allowableValues;
     private List<RestPropertyDefinition> examples;
 
     public ParamDefinition() {
@@ -177,18 +179,14 @@ public class ParamDefinition {
         this.dataFormat = dataFormat;
     }
 
-    public List<String> getAllowableValues() {
-        if (allowableValues != null) {
-            return allowableValues;
-        }
-
-        return new ArrayList<>();
+    public List<ValueDefinition> getAllowableValues() {
+        return allowableValues;
     }
 
     /**
      * Sets the parameter list of allowable values (enum).
      */
-    public void setAllowableValues(List<String> allowableValues) {
+    public void setAllowableValues(List<ValueDefinition> allowableValues) {
         this.allowableValues = allowableValues;
     }
 
@@ -275,7 +273,11 @@ public class ParamDefinition {
      * Allowed values of the parameter when its an enum type
      */
     public ParamDefinition allowableValues(List<String> allowableValues) {
-        setAllowableValues(allowableValues);
+        List<ValueDefinition> list = new ArrayList<>();
+        for (String av : allowableValues) {
+            list.add(new ValueDefinition(av));
+        }
+        setAllowableValues(list);
         return this;
     }
 
@@ -283,7 +285,11 @@ public class ParamDefinition {
      * Allowed values of the parameter when its an enum type
      */
     public ParamDefinition allowableValues(String... allowableValues) {
-        setAllowableValues(Arrays.asList(allowableValues));
+        List<ValueDefinition> list = new ArrayList<>();
+        for (String av : allowableValues) {
+            list.add(new ValueDefinition(av));
+        }
+        setAllowableValues(list);
         return this;
     }
 
@@ -291,7 +297,11 @@ public class ParamDefinition {
      * Allowed values of the parameter when its an enum type
      */
     public ParamDefinition allowableValues(String allowableValues) {
-        setAllowableValues(Arrays.asList(allowableValues.split(",")));
+        List<ValueDefinition> list = new ArrayList<>();
+        for (String av : allowableValues.split(",")) {
+            list.add(new ValueDefinition(av));
+        }
+        setAllowableValues(list);
         return this;
     }
 
@@ -335,4 +345,16 @@ public class ParamDefinition {
         return verb.getRest();
     }
 
+    public List<String> getAllowableValuesAsStringList() {
+        if (allowableValues == null) {
+            return Collections.emptyList();
+        } else {
+            List<String> answer = new ArrayList<>();
+            for (ValueDefinition v : allowableValues) {
+                answer.add(v.getValue());
+            }
+            return answer;
+        }
+    }
+
 }
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/rest/ResponseHeaderDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/rest/ResponseHeaderDefinition.java
index d76a56ee696..c5b4e8ee77c 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/model/rest/ResponseHeaderDefinition.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/rest/ResponseHeaderDefinition.java
@@ -17,7 +17,7 @@
 package org.apache.camel.model.rest;
 
 import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 
 import javax.xml.bind.annotation.XmlAccessType;
@@ -28,7 +28,9 @@ import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlTransient;
 
+import org.apache.camel.model.ValueDefinition;
 import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.annotations.DslProperty;
 import org.apache.camel.util.StringHelper;
 
 /**
@@ -58,8 +60,9 @@ public class ResponseHeaderDefinition {
     @XmlAttribute
     private String dataFormat;
     @XmlElementWrapper(name = "allowableValues")
-    @XmlElement(name = "value")
-    private List<String> allowableValues;
+    @XmlElement(name = "value") // name = value due to camel-spring-xml
+    @DslProperty(name = "allowableValues") // yaml-dsl
+    private List<ValueDefinition> allowableValues;
     @XmlAttribute
     private String example;
 
@@ -141,12 +144,8 @@ public class ResponseHeaderDefinition {
         this.dataFormat = dataFormat;
     }
 
-    public List<String> getAllowableValues() {
-        if (allowableValues != null) {
-            return allowableValues;
-        }
-
-        return new ArrayList<>();
+    public List<ValueDefinition> getAllowableValues() {
+        return allowableValues;
     }
 
     public String getExample() {
@@ -163,7 +162,7 @@ public class ResponseHeaderDefinition {
     /**
      * Sets the parameter list of allowable values.
      */
-    public void setAllowableValues(List<String> allowableValues) {
+    public void setAllowableValues(List<ValueDefinition> allowableValues) {
         this.allowableValues = allowableValues;
     }
 
@@ -223,7 +222,11 @@ public class ResponseHeaderDefinition {
      * Allowed values of the header when its an enum type
      */
     public ResponseHeaderDefinition allowableValues(List<String> allowableValues) {
-        setAllowableValues(allowableValues);
+        List<ValueDefinition> list = new ArrayList<>();
+        for (String av : allowableValues) {
+            list.add(new ValueDefinition(av));
+        }
+        setAllowableValues(list);
         return this;
     }
 
@@ -231,7 +234,23 @@ public class ResponseHeaderDefinition {
      * Allowed values of the parameter when its an enum type
      */
     public ResponseHeaderDefinition allowableValues(String... allowableValues) {
-        setAllowableValues(Arrays.asList(allowableValues));
+        List<ValueDefinition> list = new ArrayList<>();
+        for (String av : allowableValues) {
+            list.add(new ValueDefinition(av));
+        }
+        setAllowableValues(list);
+        return this;
+    }
+
+    /**
+     * Allowed values of the parameter when its an enum type
+     */
+    public ResponseHeaderDefinition allowableValues(String allowableValues) {
+        List<ValueDefinition> list = new ArrayList<>();
+        for (String av : allowableValues.split(",")) {
+            list.add(new ValueDefinition(av));
+        }
+        setAllowableValues(list);
         return this;
     }
 
@@ -253,4 +272,16 @@ public class ResponseHeaderDefinition {
         return response;
     }
 
+    public List<String> getAllowableValuesAsStringList() {
+        if (allowableValues == null) {
+            return Collections.emptyList();
+        } else {
+            List<String> answer = new ArrayList<>();
+            for (ValueDefinition v : allowableValues) {
+                answer.add(v.getValue());
+            }
+            return answer;
+        }
+    }
+
 }
diff --git a/core/camel-core/src/test/java/org/apache/camel/component/rest/FromRestGetTest.java b/core/camel-core/src/test/java/org/apache/camel/component/rest/FromRestGetTest.java
index 91946aea0bc..c8db3b9e00f 100644
--- a/core/camel-core/src/test/java/org/apache/camel/component/rest/FromRestGetTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/component/rest/FromRestGetTest.java
@@ -73,8 +73,14 @@ public class FromRestGetTest extends ContextTestSupport {
 
         assertEquals("integer", rest.getVerbs().get(0).getParams().get(0).getDataType());
         assertEquals("string", rest.getVerbs().get(0).getParams().get(1).getDataType());
-        assertEquals(Arrays.asList("1", "2", "3", "4"), rest.getVerbs().get(0).getParams().get(0).getAllowableValues());
-        assertEquals(Arrays.asList("a", "b", "c", "d"), rest.getVerbs().get(0).getParams().get(1).getAllowableValues());
+        assertEquals("1", rest.getVerbs().get(0).getParams().get(0).getAllowableValues().get(0).getValue());
+        assertEquals("2", rest.getVerbs().get(0).getParams().get(0).getAllowableValues().get(1).getValue());
+        assertEquals("3", rest.getVerbs().get(0).getParams().get(0).getAllowableValues().get(2).getValue());
+        assertEquals("4", rest.getVerbs().get(0).getParams().get(0).getAllowableValues().get(3).getValue());
+        assertEquals("a", rest.getVerbs().get(0).getParams().get(1).getAllowableValues().get(0).getValue());
+        assertEquals("b", rest.getVerbs().get(0).getParams().get(1).getAllowableValues().get(1).getValue());
+        assertEquals("c", rest.getVerbs().get(0).getParams().get(1).getAllowableValues().get(2).getValue());
+        assertEquals("d", rest.getVerbs().get(0).getParams().get(1).getAllowableValues().get(3).getValue());
         assertEquals("1", rest.getVerbs().get(0).getParams().get(0).getDefaultValue());
         assertEquals("b", rest.getVerbs().get(0).getParams().get(1).getDefaultValue());
 
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/MainSupport.java b/core/camel-main/src/main/java/org/apache/camel/main/MainSupport.java
index 7125d075978..a4875764298 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/MainSupport.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/MainSupport.java
@@ -314,8 +314,8 @@ public abstract class MainSupport extends BaseMainSupport {
 
     @Override
     protected void configureLifecycle(CamelContext camelContext) throws Exception {
-        if ((mainConfigurationProperties.getDurationMaxSeconds() > 0
-                && mainConfigurationProperties.isRoutesReloadRestartDuration())
+        if (mainConfigurationProperties.getDurationMaxSeconds() > 0
+                && mainConfigurationProperties.isRoutesReloadRestartDuration()
                 || mainConfigurationProperties.getDurationMaxMessages() > 0
                 || mainConfigurationProperties.getDurationMaxIdleSeconds() > 0) {
             // register lifecycle, so we can trigger to shutdown the JVM when maximum number of messages has been processed
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 e6655ee501d..90234c24a23 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
@@ -1554,6 +1554,9 @@ public class ModelParser extends BaseParser {
             return processorDefinitionAttributeHandler().accept(def, key, val);
         }, expressionNodeElementHandler(), noValueHandler());
     }
+    protected List<ValueDefinition> doParseValueDefinition() throws IOException, XmlPullParserException {
+        return doParseValue(() -> new ValueDefinition(), (def, val) -> def.setValue(val));
+    }
     protected WireTapDefinition doParseWireTapDefinition() throws IOException, XmlPullParserException {
         return doParse(new WireTapDefinition(), (def, key, val) -> {
             switch (key) {
@@ -2967,7 +2970,7 @@ public class ModelParser extends BaseParser {
             return true;
         }, (def, key) -> {
             switch (key) {
-                case "value": doAdd(doParseText(), def.getAllowableValues(), def::setAllowableValues); break;
+                case "allowableValues": doAddValues(doParseValueDefinition(), def.getAllowableValues(), def::setAllowableValues); break;
                 case "examples": doAdd(doParseRestPropertyDefinition(), def.getExamples(), def::setExamples); break;
                 default: return false;
             }
@@ -3077,8 +3080,8 @@ public class ModelParser extends BaseParser {
             }
             return true;
         }, (def, key) -> {
-            if ("value".equals(key)) {
-                doAdd(doParseText(), def.getAllowableValues(), def::setAllowableValues);
+            if ("allowableValues".equals(key)) {
+                doAddValues(doParseValueDefinition(), def.getAllowableValues(), def::setAllowableValues);
                 return true;
             }
             return false;
diff --git a/core/camel-xml-io/src/main/java/org/apache/camel/xml/in/BaseParser.java b/core/camel-xml-io/src/main/java/org/apache/camel/xml/in/BaseParser.java
index f80df536ad4..d52dd0113bb 100644
--- a/core/camel-xml-io/src/main/java/org/apache/camel/xml/in/BaseParser.java
+++ b/core/camel-xml-io/src/main/java/org/apache/camel/xml/in/BaseParser.java
@@ -30,6 +30,7 @@ import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 import java.util.function.Consumer;
+import java.util.function.Supplier;
 
 import org.apache.camel.LineNumberAware;
 import org.apache.camel.model.language.ExpressionDefinition;
@@ -138,6 +139,56 @@ public class BaseParser {
         }
     }
 
+    protected <T> List<T> doParseValue(Supplier<T> definitionSupplier, ValueHandler<T> valueHandler)
+            throws IOException, XmlPullParserException {
+
+        List<T> answer = new ArrayList<>();
+
+        while (true) {
+            int event = parser.next();
+            if (event == XmlPullParser.TEXT) {
+                if (!parser.isWhitespace()) {
+                    T definition = definitionSupplier.get();
+                    if (definition instanceof LineNumberAware) {
+                        // we want to get the line number where the tag starts (in case its multi-line)
+                        int line = parser.getStartLineNumber();
+                        if (line == -1) {
+                            line = parser.getLineNumber();
+                        }
+                        ((LineNumberAware) definition).setLineNumber(line);
+                        if (resource != null) {
+                            ((LineNumberAware) definition).setLocation(resource.getLocation());
+                        }
+                    }
+                    valueHandler.accept(definition, parser.getText());
+                    answer.add(definition);
+                }
+            } else if (event == XmlPullParser.START_TAG) {
+                String ns = parser.getNamespace();
+                String name = parser.getName();
+                if (Objects.equals(ns, namespace)) {
+                    if (!"value".equals(name)) {
+                        handleUnexpectedElement(ns, name);
+                    }
+                } else {
+                    handleUnexpectedElement(ns, name);
+                }
+            } else if (event == XmlPullParser.END_TAG) {
+                String ns = parser.getNamespace();
+                String name = parser.getName();
+                if (Objects.equals(ns, namespace)) {
+                    if ("value".equals(name)) {
+                        continue;
+                    }
+                }
+                return answer;
+            } else {
+                throw new XmlPullParserException(
+                        "expected START_TAG or END_TAG not " + XmlPullParser.TYPES[event], parser, null);
+            }
+        }
+    }
+
     protected Class<?> asClass(String val) throws XmlPullParserException {
         try {
             return Class.forName(val);
@@ -175,15 +226,12 @@ public class BaseParser {
         existing.add(element);
     }
 
-    @SuppressWarnings("unchecked")
-    protected <T> void doAdd(T element, T[] existing, Consumer<T[]> setter) {
-        int len = existing != null ? existing.length : 0;
-        T[] newArray = (T[]) Array.newInstance(element.getClass(), len + 1);
-        if (len > 0) {
-            System.arraycopy(existing, 0, newArray, 0, len);
+    protected <T> void doAddValues(List<T> elements, List<T> existing, Consumer<List<T>> setter) {
+        if (existing == null) {
+            existing = new ArrayList<>();
+            setter.accept(existing);
         }
-        newArray[len] = element;
-        setter.accept(newArray);
+        existing.addAll(elements);
     }
 
     protected String doParseText() throws IOException, XmlPullParserException {
diff --git a/core/camel-xml-io/src/test/java/org/apache/camel/xml/in/ModelParserTest.java b/core/camel-xml-io/src/test/java/org/apache/camel/xml/in/ModelParserTest.java
index 2e80c2f82d0..4a55199a102 100644
--- a/core/camel-xml-io/src/test/java/org/apache/camel/xml/in/ModelParserTest.java
+++ b/core/camel-xml-io/src/test/java/org/apache/camel/xml/in/ModelParserTest.java
@@ -28,13 +28,17 @@ import java.util.Map;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
+import org.apache.camel.model.PropertyDefinition;
 import org.apache.camel.model.RouteDefinition;
 import org.apache.camel.model.RouteTemplatesDefinition;
 import org.apache.camel.model.RoutesDefinition;
 import org.apache.camel.model.SetBodyDefinition;
 import org.apache.camel.model.TemplatedRoutesDefinition;
 import org.apache.camel.model.language.XPathExpression;
+import org.apache.camel.model.rest.ParamDefinition;
+import org.apache.camel.model.rest.RestDefinition;
 import org.apache.camel.model.rest.RestsDefinition;
+import org.apache.camel.model.rest.VerbDefinition;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
@@ -44,7 +48,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
 public class ModelParserTest {
 
     public static final String NAMESPACE = "http://camel.apache.org/schema/spring";
-    private static final List<String> REST_XMLS = Arrays.asList("barRest.xml", "simpleRest.xml", "simpleRestToD.xml");
+    private static final List<String> REST_XMLS = Arrays.asList("barRest.xml", "simpleRest.xml", "simpleRestToD.xml", "restAllowedValues.xml");
     private static final List<String> TEMPLATE_XMLS = Arrays.asList("barTemplate.xml");
     private static final List<String> TEMPLATED_ROUTE_XMLS = Arrays.asList("barTemplatedRoute.xml");
 
@@ -162,6 +166,38 @@ public class ModelParserTest {
         Assertions.assertEquals(25, route.getOutputs().get(1).getLineNumber());
     }
 
+    @Test
+    public void testRouteProperty() throws Exception {
+        Path dir = getResourceFolder();
+        Path path = new File(dir.toFile(), "routeProperty.xml").toPath();
+        ModelParser parser = new ModelParser(Files.newInputStream(path), NAMESPACE);
+        RoutesDefinition routes = parser.parseRoutesDefinition().orElse(null);
+        assertNotNull(routes);
+        RouteDefinition route = routes.getRoutes().get(0);
+
+        PropertyDefinition p1 = route.getRouteProperties().get(0);
+        Assertions.assertEquals("a", p1.getKey());
+        Assertions.assertEquals("1", p1.getValue());
+        PropertyDefinition p2 = route.getRouteProperties().get(1);
+        Assertions.assertEquals("b", p2.getKey());
+        Assertions.assertEquals("2", p2.getValue());
+    }
+
+    @Test
+    public void testRestAllowedValues() throws Exception {
+        Path dir = getResourceFolder();
+        Path path = new File(dir.toFile(), "restAllowedValues.xml").toPath();
+        ModelParser parser = new ModelParser(Files.newInputStream(path), NAMESPACE);
+        RestsDefinition rests = parser.parseRestsDefinition().orElse(null);
+        assertNotNull(rests);
+        RestDefinition rest = rests.getRests().get(0);
+        Assertions.assertEquals(2, rest.getVerbs().size());
+        VerbDefinition verb = rest.getVerbs().get(0);
+        Assertions.assertEquals(1, verb.getParams().size());
+        ParamDefinition param = verb.getParams().get(0);
+        Assertions.assertEquals(4, param.getAllowableValues().size());
+    }
+
     private Path getResourceFolder() {
         String url = getClass().getClassLoader().getResource("barInterceptorRoute.xml").toString();
         if (url.startsWith("file:")) {
diff --git a/core/camel-xml-io/src/test/resources/restAllowedValues.xml b/core/camel-xml-io/src/test/resources/restAllowedValues.xml
new file mode 100644
index 00000000000..397bd1324f1
--- /dev/null
+++ b/core/camel-xml-io/src/test/resources/restAllowedValues.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<rests xmlns="http://camel.apache.org/schema/spring">
+    <rest path="/say/bye">
+        <get consumes="application/json">
+            <param name="header_count" type="header" description="header param description1" dataType="integer"
+                   defaultValue="1" required="true">
+                <allowableValues>
+                    <value>1</value>
+                    <value>2</value>
+                    <value>3</value>
+                    <value>4</value>
+                </allowableValues>
+            </param>
+            <responseMessage code="300" message="test msg" responseModel="java.lang.Integer">
+                <header name="rate" description="Rate limit" dataType="integer"/>
+            </responseMessage>
+            <responseMessage code="error" message="does not work"/>
+            <to uri="direct:bye"/>
+        </get>
+        <post>
+            <to uri="mock:update"/>
+        </post>
+    </rest>
+</rests>
\ No newline at end of file
diff --git a/core/camel-xml-io/src/test/resources/routeProperty.xml b/core/camel-xml-io/src/test/resources/routeProperty.xml
new file mode 100644
index 00000000000..959b4d00227
--- /dev/null
+++ b/core/camel-xml-io/src/test/resources/routeProperty.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<routes xmlns="http://camel.apache.org/schema/spring">
+
+    <!--
+         xsi:schemaLocation="http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"
+    -->
+    <route id="myRoute">
+        <routeProperty key="a" value="1"/>
+        <routeProperty key="b" value="2"/>
+        <from uri="direct:start"/>
+        <to uri="mock:result"/>
+    </route>
+
+</routes>
diff --git a/docs/user-manual/modules/ROOT/pages/camel-3x-upgrade-guide-3_20.adoc b/docs/user-manual/modules/ROOT/pages/camel-3x-upgrade-guide-3_20.adoc
index f0b3b649ac7..e705de6245b 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-3x-upgrade-guide-3_20.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-3x-upgrade-guide-3_20.adoc
@@ -4,6 +4,12 @@ This document is for helping you upgrade your Apache Camel application
 from Camel 3.x to 3.y. For example if you are upgrading Camel 3.0 to 3.2, then you should follow the guides
 from both 3.0 to 3.1 and 3.1 to 3.2.
 
+== Upgrading Camel 3.20 to 3.20.1
+
+=== XML DSL
+
+A route now have `<routeProperty>` in the top instead of the bottom.
+
 == Upgrading Camel 3.19 to 3.20
 
 === camel-api
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 5f8fd7ca3f5..2f3d50a7c7e 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
@@ -97,6 +97,7 @@ import org.apache.camel.model.TransformDefinition;
 import org.apache.camel.model.TryDefinition;
 import org.apache.camel.model.UnmarshalDefinition;
 import org.apache.camel.model.ValidateDefinition;
+import org.apache.camel.model.ValueDefinition;
 import org.apache.camel.model.WhenDefinition;
 import org.apache.camel.model.WhenSkipSendToEndpointDefinition;
 import org.apache.camel.model.WireTapDefinition;
@@ -9957,17 +9958,16 @@ public final class ModelDeserializers extends YamlDeserializerSupport {
             types = org.apache.camel.model.rest.ParamDefinition.class,
             order = org.apache.camel.dsl.yaml.common.YamlDeserializerResolver.ORDER_LOWEST - 1,
             properties = {
+                    @YamlProperty(name = "allowable-values", type = "array:org.apache.camel.model.ValueDefinition"),
                     @YamlProperty(name = "array-type", type = "string"),
                     @YamlProperty(name = "collection-format", type = "enum:csv,multi,pipes,ssv,tsv"),
                     @YamlProperty(name = "data-format", type = "string"),
                     @YamlProperty(name = "data-type", type = "string"),
                     @YamlProperty(name = "default-value", type = "string"),
                     @YamlProperty(name = "description", type = "string"),
-                    @YamlProperty(name = "examples", type = "array:org.apache.camel.model.rest.RestPropertyDefinition"),
                     @YamlProperty(name = "name", type = "string", required = true),
                     @YamlProperty(name = "required", type = "boolean"),
-                    @YamlProperty(name = "type", type = "enum:body,formData,header,path,query", required = true),
-                    @YamlProperty(name = "value", type = "array:string")
+                    @YamlProperty(name = "type", type = "enum:body,formData,header,path,query", required = true)
             }
     )
     public static class ParamDefinitionDeserializer extends YamlDeserializerBase<ParamDefinition> {
@@ -9984,8 +9984,8 @@ public final class ModelDeserializers extends YamlDeserializerSupport {
         protected boolean setProperty(ParamDefinition target, String propertyKey,
                 String propertyName, Node node) {
             switch(propertyKey) {
-                case "value": {
-                    java.util.List<String> val = asStringList(node);
+                case "allowable-values": {
+                    java.util.List<org.apache.camel.model.ValueDefinition> val = asFlatList(node, org.apache.camel.model.ValueDefinition.class);
                     target.setAllowableValues(val);
                     break;
                 }
@@ -10018,11 +10018,6 @@ public final class ModelDeserializers extends YamlDeserializerSupport {
                     target.setDescription(val);
                     break;
                 }
-                case "examples": {
-                    java.util.List<org.apache.camel.model.rest.RestPropertyDefinition> val = asFlatList(node, org.apache.camel.model.rest.RestPropertyDefinition.class);
-                    target.setExamples(val);
-                    break;
-                }
                 case "name": {
                     String val = asText(node);
                     target.setName(val);
@@ -12225,14 +12220,14 @@ public final class ModelDeserializers extends YamlDeserializerSupport {
             types = org.apache.camel.model.rest.ResponseHeaderDefinition.class,
             order = org.apache.camel.dsl.yaml.common.YamlDeserializerResolver.ORDER_LOWEST - 1,
             properties = {
+                    @YamlProperty(name = "allowable-values", type = "array:org.apache.camel.model.ValueDefinition"),
                     @YamlProperty(name = "array-type", type = "string"),
                     @YamlProperty(name = "collection-format", type = "enum:csv,multi,pipes,ssv,tsv"),
                     @YamlProperty(name = "data-format", type = "string"),
                     @YamlProperty(name = "data-type", type = "string"),
                     @YamlProperty(name = "description", type = "string"),
                     @YamlProperty(name = "example", type = "string"),
-                    @YamlProperty(name = "name", type = "string", required = true),
-                    @YamlProperty(name = "value", type = "array:string")
+                    @YamlProperty(name = "name", type = "string", required = true)
             }
     )
     public static class ResponseHeaderDefinitionDeserializer extends YamlDeserializerBase<ResponseHeaderDefinition> {
@@ -12249,8 +12244,8 @@ public final class ModelDeserializers extends YamlDeserializerSupport {
         protected boolean setProperty(ResponseHeaderDefinition target, String propertyKey,
                 String propertyName, Node node) {
             switch(propertyKey) {
-                case "value": {
-                    java.util.List<String> val = asStringList(node);
+                case "allowable-values": {
+                    java.util.List<org.apache.camel.model.ValueDefinition> val = asFlatList(node, org.apache.camel.model.ValueDefinition.class);
                     target.setAllowableValues(val);
                     break;
                 }
@@ -17995,6 +17990,45 @@ public final class ModelDeserializers extends YamlDeserializerSupport {
         }
     }
 
+    @YamlType(
+            nodes = "value",
+            inline = true,
+            types = org.apache.camel.model.ValueDefinition.class,
+            order = org.apache.camel.dsl.yaml.common.YamlDeserializerResolver.ORDER_LOWEST - 1,
+            properties = @YamlProperty(name = "value", type = "string")
+    )
+    public static class ValueDefinitionDeserializer extends YamlDeserializerBase<ValueDefinition> {
+        public ValueDefinitionDeserializer() {
+            super(ValueDefinition.class);
+        }
+
+        @Override
+        protected ValueDefinition newInstance() {
+            return new ValueDefinition();
+        }
+
+        @Override
+        protected ValueDefinition newInstance(String value) {
+            return new ValueDefinition(value);
+        }
+
+        @Override
+        protected boolean setProperty(ValueDefinition target, String propertyKey,
+                String propertyName, Node node) {
+            switch(propertyKey) {
+                case "value": {
+                    String val = asText(node);
+                    target.setValue(val);
+                    break;
+                }
+                default: {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+
     @YamlType(
             nodes = "weighted",
             types = org.apache.camel.model.loadbalancer.WeightedLoadBalancerDefinition.class,
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java
index 791739cdd4f..fd0d01573e4 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java
@@ -524,6 +524,8 @@ public final class ModelDeserializersResolver implements YamlDeserializerResolve
             case "org.apache.camel.model.ValidateDefinition": return new ModelDeserializers.ValidateDefinitionDeserializer();
             case "validators": return new ModelDeserializers.ValidatorsDefinitionDeserializer();
             case "org.apache.camel.model.validator.ValidatorsDefinition": return new ModelDeserializers.ValidatorsDefinitionDeserializer();
+            case "value": return new ModelDeserializers.ValueDefinitionDeserializer();
+            case "org.apache.camel.model.ValueDefinition": return new ModelDeserializers.ValueDefinitionDeserializer();
             case "weighted": return new ModelDeserializers.WeightedLoadBalancerDefinitionDeserializer();
             case "org.apache.camel.model.loadbalancer.WeightedLoadBalancerDefinition": return new ModelDeserializers.WeightedLoadBalancerDefinitionDeserializer();
             case "when": return new ModelDeserializers.WhenDefinitionDeserializer();
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 64e2544278a..e06f02e4c2f 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
@@ -3605,6 +3605,18 @@
           }
         }
       },
+      "org.apache.camel.model.ValueDefinition" : {
+        "oneOf" : [ {
+          "type" : "string"
+        }, {
+          "type" : "object",
+          "properties" : {
+            "value" : {
+              "type" : "string"
+            }
+          }
+        } ]
+      },
       "org.apache.camel.model.WhenDefinition" : {
         "type" : "object",
         "anyOf" : [ {
@@ -7342,6 +7354,12 @@
       "org.apache.camel.model.rest.ParamDefinition" : {
         "type" : "object",
         "properties" : {
+          "allowable-values" : {
+            "type" : "array",
+            "items" : {
+              "$ref" : "#/items/definitions/org.apache.camel.model.ValueDefinition"
+            }
+          },
           "array-type" : {
             "type" : "string"
           },
@@ -7361,12 +7379,6 @@
           "description" : {
             "type" : "string"
           },
-          "examples" : {
-            "type" : "array",
-            "items" : {
-              "$ref" : "#/items/definitions/org.apache.camel.model.rest.RestPropertyDefinition"
-            }
-          },
           "name" : {
             "type" : "string"
           },
@@ -7376,12 +7388,6 @@
           "type" : {
             "type" : "string",
             "enum" : [ "body", "formData", "header", "path", "query" ]
-          },
-          "value" : {
-            "type" : "array",
-            "items" : {
-              "type" : "string"
-            }
           }
         },
         "required" : [ "name", "type" ]
@@ -7605,6 +7611,12 @@
       "org.apache.camel.model.rest.ResponseHeaderDefinition" : {
         "type" : "object",
         "properties" : {
+          "allowable-values" : {
+            "type" : "array",
+            "items" : {
+              "$ref" : "#/items/definitions/org.apache.camel.model.ValueDefinition"
+            }
+          },
           "array-type" : {
             "type" : "string"
           },
@@ -7626,12 +7638,6 @@
           },
           "name" : {
             "type" : "string"
-          },
-          "value" : {
-            "type" : "array",
-            "items" : {
-              "type" : "string"
-            }
           }
         },
         "required" : [ "name" ]
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 3e8e83a0f63..7d8fe91ef75 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
@@ -3509,6 +3509,18 @@
           }
         }
       },
+      "org.apache.camel.model.ValueDefinition" : {
+        "oneOf" : [ {
+          "type" : "string"
+        }, {
+          "type" : "object",
+          "properties" : {
+            "value" : {
+              "type" : "string"
+            }
+          }
+        } ]
+      },
       "org.apache.camel.model.WhenDefinition" : {
         "type" : "object",
         "anyOf" : [ {
@@ -7243,6 +7255,12 @@
       "org.apache.camel.model.rest.ParamDefinition" : {
         "type" : "object",
         "properties" : {
+          "allowableValues" : {
+            "type" : "array",
+            "items" : {
+              "$ref" : "#/items/definitions/org.apache.camel.model.ValueDefinition"
+            }
+          },
           "arrayType" : {
             "type" : "string"
           },
@@ -7262,12 +7280,6 @@
           "description" : {
             "type" : "string"
           },
-          "examples" : {
-            "type" : "array",
-            "items" : {
-              "$ref" : "#/items/definitions/org.apache.camel.model.rest.RestPropertyDefinition"
-            }
-          },
           "name" : {
             "type" : "string"
           },
@@ -7277,12 +7289,6 @@
           "type" : {
             "type" : "string",
             "enum" : [ "body", "formData", "header", "path", "query" ]
-          },
-          "value" : {
-            "type" : "array",
-            "items" : {
-              "type" : "string"
-            }
           }
         },
         "required" : [ "name", "type" ]
@@ -7506,6 +7512,12 @@
       "org.apache.camel.model.rest.ResponseHeaderDefinition" : {
         "type" : "object",
         "properties" : {
+          "allowableValues" : {
+            "type" : "array",
+            "items" : {
+              "$ref" : "#/items/definitions/org.apache.camel.model.ValueDefinition"
+            }
+          },
           "arrayType" : {
             "type" : "string"
           },
@@ -7527,12 +7539,6 @@
           },
           "name" : {
             "type" : "string"
-          },
-          "value" : {
-            "type" : "array",
-            "items" : {
-              "type" : "string"
-            }
           }
         },
         "required" : [ "name" ]
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/RestTest.groovy b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/RestTest.groovy
index 7a4aa89dd67..c2a8160a569 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/RestTest.groovy
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/RestTest.groovy
@@ -22,6 +22,7 @@ import org.apache.camel.dsl.yaml.support.model.MyBean
 import org.apache.camel.dsl.yaml.support.model.MyFooBar
 import org.apache.camel.model.ToDefinition
 import org.apache.camel.model.rest.GetDefinition
+import org.apache.camel.model.rest.ParamDefinition
 import org.apache.camel.model.rest.PostDefinition
 import org.apache.camel.model.rest.RestDefinition
 import org.apache.camel.model.rest.VerbDefinition
@@ -187,4 +188,24 @@ class RestTest extends YamlTestSupport {
             context.restDefinitions != null
             !context.restDefinitions.isEmpty()
     }
+
+    def "load rest (allowableValues)"() {
+        setup:
+            def rloc = 'classpath:/routes/rest-allowable-values-dsl.yaml'
+            def rdsl = context.resourceLoader.resolveResource(rloc)
+        when:
+            loadRoutes rdsl
+        then:
+            context.restDefinitions != null
+            !context.restDefinitions.isEmpty()
+
+            with(context.restDefinitions[0].verbs[0].params[0], ParamDefinition) {
+                allowableValues.size() == 3
+                allowableValues[0].value == 'available'
+                allowableValues[1].value == 'pending'
+                allowableValues[2].value == 'sold'
+            }
+    }
+
+
 }
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/resources/routes/rest-allowable-values-dsl.yaml b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/resources/routes/rest-allowable-values-dsl.yaml
new file mode 100644
index 00000000000..92edc0388bc
--- /dev/null
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/resources/routes/rest-allowable-values-dsl.yaml
@@ -0,0 +1,19 @@
+- rest:
+    path: /v3
+    get:
+      - param:
+          - name: status
+            type: query
+            dataType: string
+            defaultValue: available
+            description: Status values that need to be considered for filter
+            required: false
+            allowableValues:
+              - available
+              - pending
+              - sold
+        id: findPetsByStatus
+        path: /pet/findByStatus
+        description: Multiple status values can be provided with comma separated strings
+        produces: application/xml,application/json
+        to: direct:findPetsByStatus
diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/ModelXmlParserGeneratorMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/ModelXmlParserGeneratorMojo.java
index b982f59e2d3..fefb8152bfb 100644
--- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/ModelXmlParserGeneratorMojo.java
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/ModelXmlParserGeneratorMojo.java
@@ -51,6 +51,7 @@ import javax.xml.bind.annotation.XmlAnyAttribute;
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementRef;
+import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlElements;
 import javax.xml.bind.annotation.XmlEnum;
 import javax.xml.bind.annotation.XmlRootElement;
@@ -378,6 +379,12 @@ public class ModelXmlParserGeneratorMojo extends AbstractGeneratorMojo {
                 String en = "##default";
                 if (((AccessibleObject)member).getAnnotation(XmlElement.class) != null) {
                     en = ((AccessibleObject)member).getAnnotation(XmlElement.class).name();
+                    // special for value which can be wrapped
+                    if ("value".equals(en)) {
+                        if (((AccessibleObject)member).getAnnotation(XmlElementWrapper.class) != null) {
+                            en = ((AccessibleObject)member).getAnnotation(XmlElementWrapper.class).name();
+                        }
+                    }
                 }
                 if ("##default".equals(en)) {
                     en = member instanceof Method ? propname(fn) : fn;
@@ -416,7 +423,13 @@ public class ModelXmlParserGeneratorMojo extends AbstractGeneratorMojo {
                     }
                     pc = n + ".valueOf(doParseText())";
                 }
-                cases.put(en, list ? "doAdd(" + pc + ", def." + gn + "(), def::" + sn + ");" : "def." + sn + "(" + pc + ");");
+
+                // special for allowableValues
+                if ("allowableValues".equals(en)) {
+                    cases.put(en, list ? "doAddValues(" + pc + ", def." + gn + "(), def::" + sn + ");" : "def." + sn + "(" + pc + ");");
+                } else {
+                    cases.put(en, list ? "doAdd(" + pc + ", def." + gn + "(), def::" + sn + ");" : "def." + sn + "(" + pc + ");");
+                }
             });
             String expressionHandler = null;
             for (Class<?> parent = clazz.getSuperclass(); parent != Object.class; parent = parent.getSuperclass()) {
@@ -536,8 +549,14 @@ public class ModelXmlParserGeneratorMojo extends AbstractGeneratorMojo {
                                  + (elementMembers.isEmpty() ? elements : lowercase(name) + "ElementHandler()") + "," + value + ");\n");
                 }
             } else {
-                parser.addMethod().setSignature("protected " + qname + " doParse" + name + "() throws IOException, XmlPullParserException")
-                    .setBody("return doParse(new " + qname + "()," + attributes + "," + elements + "," + value + ");\n");
+                // special for value definition
+                if ("ValueDefinition".equals(name)) {
+                    parser.addMethod().setSignature("protected List<" + qname + "> doParse" + name + "() throws IOException, XmlPullParserException")
+                            .setBody("return doParseValue(() -> new " + qname + "()" + "," + value + ");\n");
+                } else {
+                    parser.addMethod().setSignature("protected " + qname + " doParse" + name + "() throws IOException, XmlPullParserException")
+                            .setBody("return doParse(new " + qname + "()," + attributes + "," + elements + "," + value + ");\n");
+                }
             }
         }
 
diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SchemaGeneratorMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SchemaGeneratorMojo.java
index 39237b5acd6..6adab4c05de 100644
--- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SchemaGeneratorMojo.java
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/SchemaGeneratorMojo.java
@@ -18,6 +18,7 @@ package org.apache.camel.maven.packaging;
 
 import java.io.File;
 import java.io.IOException;
+import java.lang.reflect.AccessibleObject;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 import java.lang.reflect.Type;
@@ -39,6 +40,7 @@ import java.util.stream.Collectors;
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementRef;
+import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlElements;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
@@ -503,10 +505,8 @@ public class SchemaGeneratorMojo extends AbstractGeneratorMojo {
             Set<EipOptionModel> eipOptions, String prefix) {
         String fieldName = fieldElement.getName();
         if (element != null) {
-
             Metadata metadata = fieldElement.getAnnotation(Metadata.class);
-
-            String name = fetchName(element.name(), fieldName, prefix);
+            String name = fetchElementName(element, fieldElement, prefix);
             Class<?> fieldTypeElement = fieldElement.getType();
             String fieldTypeName = getTypeName(GenericsUtil.resolveType(originalClassType, fieldElement));
             boolean isDuration = false;
@@ -1039,6 +1039,24 @@ public class SchemaGeneratorMojo extends AbstractGeneratorMojo {
         return name;
     }
 
+    private String fetchElementName(XmlElement element, Field fieldElement, String prefix) {
+        String fieldName = fieldElement.getName();
+        String name = element.name();
+        if (Strings.isNullOrEmpty(name) || "##default".equals(name)) {
+            name = fieldName;
+        }
+        // special for value definition which can be wrapped
+        if ("value".equals(name)) {
+            XmlElementWrapper wrapper = fieldElement.getAnnotation(XmlElementWrapper.class);
+            String n = wrapper.name();
+            if (!"##default".equals(n)) {
+                name = n;
+            }
+        }
+        name = prefix + name;
+        return name;
+    }
+
     /**
      * Whether the class supports outputs.
      * <p/>
diff --git a/tooling/openapi-rest-dsl-generator/src/main/java/org/apache/camel/generator/openapi/RestDslYamlGenerator.java b/tooling/openapi-rest-dsl-generator/src/main/java/org/apache/camel/generator/openapi/RestDslYamlGenerator.java
index ba3d2c0479f..b191e478781 100644
--- a/tooling/openapi-rest-dsl-generator/src/main/java/org/apache/camel/generator/openapi/RestDslYamlGenerator.java
+++ b/tooling/openapi-rest-dsl-generator/src/main/java/org/apache/camel/generator/openapi/RestDslYamlGenerator.java
@@ -261,6 +261,21 @@ public class RestDslYamlGenerator extends RestDslGenerator<RestDslYamlGenerator>
                         BooleanNode bn = xmlMapper.createObjectNode().booleanNode(b);
                         on.set("required", bn);
                     }
+                    String k = "allowableValues";
+                    r = pc.get(k);
+                    if (r == null) {
+                        k = "allowable-values";
+                        r = pc.get(k);
+                    }
+                    if (r != null) {
+                        // remove value node
+                        JsonNode v = r.get("value");
+                        if (v.isArray()) {
+                            ObjectNode on = (ObjectNode) pc;
+                            on.set(k, v);
+                            on.remove("value");
+                        }
+                    }
                 }
             }
         }
diff --git a/tooling/openapi-rest-dsl-generator/src/test/java/org/apache/camel/generator/openapi/RestDslYamlGeneratorV302Test.java b/tooling/openapi-rest-dsl-generator/src/test/java/org/apache/camel/generator/openapi/RestDslYamlGeneratorV302Test.java
new file mode 100644
index 00000000000..574956ba51a
--- /dev/null
+++ b/tooling/openapi-rest-dsl-generator/src/test/java/org/apache/camel/generator/openapi/RestDslYamlGeneratorV302Test.java
@@ -0,0 +1,62 @@
+/*
+ * 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.generator.openapi;
+
+import java.io.InputStream;
+import java.net.URI;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
+import io.apicurio.datamodels.Library;
+import io.apicurio.datamodels.openapi.models.OasDocument;
+import org.apache.camel.CamelContext;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class RestDslYamlGeneratorV302Test {
+
+    static OasDocument document;
+
+    @Test
+    public void shouldGenerateYamlWithAllowedValues() throws Exception {
+        try (CamelContext context = new DefaultCamelContext()) {
+            final String yaml = RestDslGenerator.toYaml(document).generate(context);
+
+            final URI file = RestDslGeneratorTest.class.getResource("/OpenApiV302PetstoreYaml.txt").toURI();
+            final String expectedContent = new String(Files.readAllBytes(Paths.get(file)), StandardCharsets.UTF_8);
+
+            assertThat(yaml).isEqualTo(expectedContent);
+        }
+    }
+
+    @BeforeAll
+    public static void readOpenApiDoc() throws Exception {
+        final ObjectMapper mapper = new YAMLMapper();
+        try (InputStream is = RestDslYamlGeneratorV302Test.class.getResourceAsStream("petstore-v3.yaml")) {
+            final JsonNode node = mapper.readTree(is);
+            document = (OasDocument) Library.readDocument(node);
+        }
+    }
+
+}
diff --git a/tooling/openapi-rest-dsl-generator/src/test/resources/OpenApiV302PetstoreYaml.txt b/tooling/openapi-rest-dsl-generator/src/test/resources/OpenApiV302PetstoreYaml.txt
new file mode 100644
index 00000000000..cf64df35254
--- /dev/null
+++ b/tooling/openapi-rest-dsl-generator/src/test/resources/OpenApiV302PetstoreYaml.txt
@@ -0,0 +1,231 @@
+- rest:
+    path: "/v3"
+    put:
+    - id: "updatePet"
+      path: "/pet"
+      description: "Update an existing pet by Id"
+      consumes: "application/json,application/xml,application/x-www-form-urlencoded"
+      produces: "application/xml,application/json"
+      param:
+      - description: "Update an existent pet in the store"
+        name: "body"
+        required: true
+        type: "body"
+      to: "direct:updatePet"
+    - id: "updateUser"
+      path: "/user/{username}"
+      description: "This can only be done by the logged in user."
+      consumes: "application/json,application/xml,application/x-www-form-urlencoded"
+      param:
+      - dataType: "string"
+        description: "name that need to be deleted"
+        name: "username"
+        required: true
+        type: "path"
+      - description: "Update an existent user in the store"
+        name: "body"
+        required: true
+        type: "body"
+      to: "direct:updateUser"
+    post:
+    - id: "addPet"
+      path: "/pet"
+      description: "Add a new pet to the store"
+      consumes: "application/json,application/xml,application/x-www-form-urlencoded"
+      produces: "application/xml,application/json"
+      param:
+      - description: "Create a new pet in the store"
+        name: "body"
+        required: true
+        type: "body"
+      to: "direct:addPet"
+    - id: "updatePetWithForm"
+      path: "/pet/{petId}"
+      param:
+      - dataType: "integer"
+        description: "ID of pet that needs to be updated"
+        name: "petId"
+        required: true
+        type: "path"
+      - dataType: "string"
+        description: "Name of pet that needs to be updated"
+        name: "name"
+        required: false
+        type: "query"
+      - dataType: "string"
+        description: "Status of pet that needs to be updated"
+        name: "status"
+        required: false
+        type: "query"
+      to: "direct:updatePetWithForm"
+    - id: "uploadFile"
+      path: "/pet/{petId}/uploadImage"
+      consumes: "application/octet-stream"
+      produces: "application/json"
+      param:
+      - dataType: "integer"
+        description: "ID of pet to update"
+        name: "petId"
+        required: true
+        type: "path"
+      - dataType: "string"
+        description: "Additional Metadata"
+        name: "additionalMetadata"
+        required: false
+        type: "query"
+      - name: "body"
+        required: true
+        type: "body"
+      to: "direct:uploadFile"
+    - id: "placeOrder"
+      path: "/store/order"
+      description: "Place a new order in the store"
+      consumes: "application/json,application/xml,application/x-www-form-urlencoded"
+      produces: "application/json"
+      param:
+      - name: "body"
+        required: true
+        type: "body"
+      to: "direct:placeOrder"
+    - id: "createUser"
+      path: "/user"
+      description: "This can only be done by the logged in user."
+      consumes: "application/json,application/xml,application/x-www-form-urlencoded"
+      produces: "application/json,application/xml"
+      param:
+      - description: "Created user object"
+        name: "body"
+        required: true
+        type: "body"
+      to: "direct:createUser"
+    - id: "createUsersWithListInput"
+      path: "/user/createWithList"
+      description: "Creates list of users with given input array"
+      consumes: "application/json"
+      produces: "application/xml,application/json"
+      param:
+      - name: "body"
+        required: true
+        type: "body"
+      to: "direct:createUsersWithListInput"
+    get:
+    - id: "findPetsByStatus"
+      path: "/pet/findByStatus"
+      description: "Multiple status values can be provided with comma separated strings"
+      produces: "application/xml,application/json"
+      param:
+      - dataType: "string"
+        defaultValue: "available"
+        description: "Status values that need to be considered for filter"
+        name: "status"
+        required: false
+        type: "query"
+        allowableValues:
+        - "available"
+        - "pending"
+        - "sold"
+      to: "direct:findPetsByStatus"
+    - id: "findPetsByTags"
+      path: "/pet/findByTags"
+      description: "Multiple tags can be provided with comma separated strings. Use\
+        \ tag1, tag2, tag3 for testing."
+      produces: "application/xml,application/json"
+      param:
+      - arrayType: "string"
+        dataType: "array"
+        description: "Tags to filter by"
+        name: "tags"
+        required: false
+        type: "query"
+      to: "direct:findPetsByTags"
+    - id: "getPetById"
+      path: "/pet/{petId}"
+      description: "Returns a single pet"
+      produces: "application/xml,application/json"
+      param:
+      - dataType: "integer"
+        description: "ID of pet to return"
+        name: "petId"
+        required: true
+        type: "path"
+      to: "direct:getPetById"
+    - id: "getInventory"
+      path: "/store/inventory"
+      description: "Returns a map of status codes to quantities"
+      produces: "application/json"
+      to: "direct:getInventory"
+    - id: "getOrderById"
+      path: "/store/order/{orderId}"
+      description: "For valid response try integer IDs with value <= 5 or > 10. Other\
+        \ values will generate exceptions."
+      produces: "application/xml,application/json"
+      param:
+      - dataType: "integer"
+        description: "ID of order that needs to be fetched"
+        name: "orderId"
+        required: true
+        type: "path"
+      to: "direct:getOrderById"
+    - id: "loginUser"
+      path: "/user/login"
+      produces: "application/xml,application/json"
+      param:
+      - dataType: "string"
+        description: "The user name for login"
+        name: "username"
+        required: false
+        type: "query"
+      - dataType: "string"
+        description: "The password for login in clear text"
+        name: "password"
+        required: false
+        type: "query"
+      to: "direct:loginUser"
+    - id: "logoutUser"
+      path: "/user/logout"
+      to: "direct:logoutUser"
+    - id: "getUserByName"
+      path: "/user/{username}"
+      produces: "application/xml,application/json"
+      param:
+      - dataType: "string"
+        description: "The name that needs to be fetched. Use user1 for testing. "
+        name: "username"
+        required: true
+        type: "path"
+      to: "direct:getUserByName"
+    delete:
+    - id: "deletePet"
+      path: "/pet/{petId}"
+      param:
+      - dataType: "string"
+        name: "api_key"
+        required: false
+        type: "header"
+      - dataType: "integer"
+        description: "Pet id to delete"
+        name: "petId"
+        required: true
+        type: "path"
+      to: "direct:deletePet"
+    - id: "deleteOrder"
+      path: "/store/order/{orderId}"
+      description: "For valid response try integer IDs with value < 1000. Anything\
+        \ above 1000 or nonintegers will generate API errors"
+      param:
+      - dataType: "integer"
+        description: "ID of the order that needs to be deleted"
+        name: "orderId"
+        required: true
+        type: "path"
+      to: "direct:deleteOrder"
+    - id: "deleteUser"
+      path: "/user/{username}"
+      description: "This can only be done by the logged in user."
+      param:
+      - dataType: "string"
+        description: "The name that needs to be deleted"
+        name: "username"
+        required: true
+        type: "path"
+      to: "direct:deleteUser"
diff --git a/tooling/openapi-rest-dsl-generator/src/test/resources/org/apache/camel/generator/openapi/petstore-v3.yaml b/tooling/openapi-rest-dsl-generator/src/test/resources/org/apache/camel/generator/openapi/petstore-v3.yaml
new file mode 100644
index 00000000000..a87eeba6d27
--- /dev/null
+++ b/tooling/openapi-rest-dsl-generator/src/test/resources/org/apache/camel/generator/openapi/petstore-v3.yaml
@@ -0,0 +1,819 @@
+openapi: 3.0.2
+servers:
+  - url: /v3
+info:
+  description: |-
+    This is a sample Pet Store Server based on the OpenAPI 3.0 specification.  You can find out more about
+    Swagger at [http://swagger.io](http://swagger.io). In the third iteration of the pet store, we've switched to the design first approach!
+    You can now help us improve the API whether it's by making changes to the definition itself or to the code.
+    That way, with time, we can improve the API in general, and expose some of the new features in OAS3.
+
+    Some useful links:
+    - [The Pet Store repository](https://github.com/swagger-api/swagger-petstore)
+    - [The source API definition for the Pet Store](https://github.com/swagger-api/swagger-petstore/blob/master/src/main/resources/openapi.yaml)
+  version: 1.0.17
+  title: Swagger Petstore - OpenAPI 3.0
+  termsOfService: 'http://swagger.io/terms/'
+  contact:
+    email: apiteam@swagger.io
+  license:
+    name: Apache 2.0
+    url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
+tags:
+  - name: pet
+    description: Everything about your Pets
+    externalDocs:
+      description: Find out more
+      url: 'http://swagger.io'
+  - name: store
+    description: Access to Petstore orders
+    externalDocs:
+      description: Find out more about our store
+      url: 'http://swagger.io'
+  - name: user
+    description: Operations about user
+paths:
+  /pet:
+    post:
+      tags:
+        - pet
+      summary: Add a new pet to the store
+      description: Add a new pet to the store
+      operationId: addPet
+      responses:
+        '200':
+          description: Successful operation
+          content:
+            application/xml:
+              schema:
+                $ref: '#/components/schemas/Pet'
+            application/json:
+              schema:
+                $ref: '#/components/schemas/Pet'
+        '405':
+          description: Invalid input
+      security:
+        - petstore_auth:
+            - 'write:pets'
+            - 'read:pets'
+      requestBody:
+        description: Create a new pet in the store
+        required: true
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/Pet'
+          application/xml:
+            schema:
+              $ref: '#/components/schemas/Pet'
+          application/x-www-form-urlencoded:
+            schema:
+              $ref: '#/components/schemas/Pet'
+    put:
+      tags:
+        - pet
+      summary: Update an existing pet
+      description: Update an existing pet by Id
+      operationId: updatePet
+      responses:
+        '200':
+          description: Successful operation
+          content:
+            application/xml:
+              schema:
+                $ref: '#/components/schemas/Pet'
+            application/json:
+              schema:
+                $ref: '#/components/schemas/Pet'
+        '400':
+          description: Invalid ID supplied
+        '404':
+          description: Pet not found
+        '405':
+          description: Validation exception
+      security:
+        - petstore_auth:
+            - 'write:pets'
+            - 'read:pets'
+      requestBody:
+        description: Update an existent pet in the store
+        required: true
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/Pet'
+          application/xml:
+            schema:
+              $ref: '#/components/schemas/Pet'
+          application/x-www-form-urlencoded:
+            schema:
+              $ref: '#/components/schemas/Pet'
+  /pet/findByStatus:
+    get:
+      tags:
+        - pet
+      summary: Finds Pets by status
+      description: Multiple status values can be provided with comma separated strings
+      operationId: findPetsByStatus
+      parameters:
+        - name: status
+          in: query
+          description: Status values that need to be considered for filter
+          required: false
+          explode: true
+          schema:
+            type: string
+            enum:
+              - available
+              - pending
+              - sold
+            default: available
+      responses:
+        '200':
+          description: successful operation
+          content:
+            application/xml:
+              schema:
+                type: array
+                items:
+                  $ref: '#/components/schemas/Pet'
+            application/json:
+              schema:
+                type: array
+                items:
+                  $ref: '#/components/schemas/Pet'
+        '400':
+          description: Invalid status value
+      security:
+        - petstore_auth:
+            - 'write:pets'
+            - 'read:pets'
+  /pet/findByTags:
+    get:
+      tags:
+        - pet
+      summary: Finds Pets by tags
+      description: >-
+        Multiple tags can be provided with comma separated strings. Use tag1,
+        tag2, tag3 for testing.
+      operationId: findPetsByTags
+      parameters:
+        - name: tags
+          in: query
+          description: Tags to filter by
+          required: false
+          explode: true
+          schema:
+            type: array
+            items:
+              type: string
+      responses:
+        '200':
+          description: successful operation
+          content:
+            application/xml:
+              schema:
+                type: array
+                items:
+                  $ref: '#/components/schemas/Pet'
+            application/json:
+              schema:
+                type: array
+                items:
+                  $ref: '#/components/schemas/Pet'
+        '400':
+          description: Invalid tag value
+      security:
+        - petstore_auth:
+            - 'write:pets'
+            - 'read:pets'
+  '/pet/{petId}':
+    get:
+      tags:
+        - pet
+      summary: Find pet by ID
+      description: Returns a single pet
+      operationId: getPetById
+      parameters:
+        - name: petId
+          in: path
+          description: ID of pet to return
+          required: true
+          schema:
+            type: integer
+            format: int64
+      responses:
+        '200':
+          description: successful operation
+          content:
+            application/xml:
+              schema:
+                $ref: '#/components/schemas/Pet'
+            application/json:
+              schema:
+                $ref: '#/components/schemas/Pet'
+        '400':
+          description: Invalid ID supplied
+        '404':
+          description: Pet not found
+      security:
+        - api_key: []
+        - petstore_auth:
+            - 'write:pets'
+            - 'read:pets'
+    post:
+      tags:
+        - pet
+      summary: Updates a pet in the store with form data
+      description: ''
+      operationId: updatePetWithForm
+      parameters:
+        - name: petId
+          in: path
+          description: ID of pet that needs to be updated
+          required: true
+          schema:
+            type: integer
+            format: int64
+        - name: name
+          in: query
+          description: Name of pet that needs to be updated
+          schema:
+            type: string
+        - name: status
+          in: query
+          description: Status of pet that needs to be updated
+          schema:
+            type: string
+      responses:
+        '405':
+          description: Invalid input
+      security:
+        - petstore_auth:
+            - 'write:pets'
+            - 'read:pets'
+    delete:
+      tags:
+        - pet
+      summary: Deletes a pet
+      description: ''
+      operationId: deletePet
+      parameters:
+        - name: api_key
+          in: header
+          description: ''
+          required: false
+          schema:
+            type: string
+        - name: petId
+          in: path
+          description: Pet id to delete
+          required: true
+          schema:
+            type: integer
+            format: int64
+      responses:
+        '400':
+          description: Invalid pet value
+      security:
+        - petstore_auth:
+            - 'write:pets'
+            - 'read:pets'
+  '/pet/{petId}/uploadImage':
+    post:
+      tags:
+        - pet
+      summary: uploads an image
+      description: ''
+      operationId: uploadFile
+      parameters:
+        - name: petId
+          in: path
+          description: ID of pet to update
+          required: true
+          schema:
+            type: integer
+            format: int64
+        - name: additionalMetadata
+          in: query
+          description: Additional Metadata
+          required: false
+          schema:
+            type: string
+      responses:
+        '200':
+          description: successful operation
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/ApiResponse'
+      security:
+        - petstore_auth:
+            - 'write:pets'
+            - 'read:pets'
+      requestBody:
+        content:
+          application/octet-stream:
+            schema:
+              type: string
+              format: binary
+  /store/inventory:
+    get:
+      tags:
+        - store
+      summary: Returns pet inventories by status
+      description: Returns a map of status codes to quantities
+      operationId: getInventory
+      x-swagger-router-controller: OrderController
+      responses:
+        '200':
+          description: successful operation
+          content:
+            application/json:
+              schema:
+                type: object
+                additionalProperties:
+                  type: integer
+                  format: int32
+      security:
+        - api_key: []
+  /store/order:
+    post:
+      tags:
+        - store
+      summary: Place an order for a pet
+      description: Place a new order in the store
+      operationId: placeOrder
+      x-swagger-router-controller: OrderController
+      responses:
+        '200':
+          description: successful operation
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/Order'
+        '405':
+          description: Invalid input
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/Order'
+          application/xml:
+            schema:
+              $ref: '#/components/schemas/Order'
+          application/x-www-form-urlencoded:
+            schema:
+              $ref: '#/components/schemas/Order'
+  '/store/order/{orderId}':
+    get:
+      tags:
+        - store
+      summary: Find purchase order by ID
+      x-swagger-router-controller: OrderController
+      description: >-
+        For valid response try integer IDs with value <= 5 or > 10. Other values
+        will generate exceptions.
+      operationId: getOrderById
+      parameters:
+        - name: orderId
+          in: path
+          description: ID of order that needs to be fetched
+          required: true
+          schema:
+            type: integer
+            format: int64
+      responses:
+        '200':
+          description: successful operation
+          content:
+            application/xml:
+              schema:
+                $ref: '#/components/schemas/Order'
+            application/json:
+              schema:
+                $ref: '#/components/schemas/Order'
+        '400':
+          description: Invalid ID supplied
+        '404':
+          description: Order not found
+    delete:
+      tags:
+        - store
+      summary: Delete purchase order by ID
+      x-swagger-router-controller: OrderController
+      description: >-
+        For valid response try integer IDs with value < 1000. Anything above
+        1000 or nonintegers will generate API errors
+      operationId: deleteOrder
+      parameters:
+        - name: orderId
+          in: path
+          description: ID of the order that needs to be deleted
+          required: true
+          schema:
+            type: integer
+            format: int64
+      responses:
+        '400':
+          description: Invalid ID supplied
+        '404':
+          description: Order not found
+  /user:
+    post:
+      tags:
+        - user
+      summary: Create user
+      description: This can only be done by the logged in user.
+      operationId: createUser
+      responses:
+        default:
+          description: successful operation
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/User'
+            application/xml:
+              schema:
+                $ref: '#/components/schemas/User'
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/User'
+          application/xml:
+            schema:
+              $ref: '#/components/schemas/User'
+          application/x-www-form-urlencoded:
+            schema:
+              $ref: '#/components/schemas/User'
+        description: Created user object
+  /user/createWithList:
+    post:
+      tags:
+        - user
+      summary: Creates list of users with given input array
+      description: 'Creates list of users with given input array'
+      x-swagger-router-controller: UserController
+      operationId: createUsersWithListInput
+      responses:
+        '200':
+          description: Successful operation
+          content:
+            application/xml:
+              schema:
+                $ref: '#/components/schemas/User'
+            application/json:
+              schema:
+                $ref: '#/components/schemas/User'
+        default:
+          description: successful operation
+      requestBody:
+        content:
+          application/json:
+            schema:
+              type: array
+              items:
+                $ref: '#/components/schemas/User'
+  /user/login:
+    get:
+      tags:
+        - user
+      summary: Logs user into the system
+      description: ''
+      operationId: loginUser
+      parameters:
+        - name: username
+          in: query
+          description: The user name for login
+          required: false
+          schema:
+            type: string
+        - name: password
+          in: query
+          description: The password for login in clear text
+          required: false
+          schema:
+            type: string
+      responses:
+        '200':
+          description: successful operation
+          headers:
+            X-Rate-Limit:
+              description: calls per hour allowed by the user
+              schema:
+                type: integer
+                format: int32
+            X-Expires-After:
+              description: date in UTC when token expires
+              schema:
+                type: string
+                format: date-time
+          content:
+            application/xml:
+              schema:
+                type: string
+            application/json:
+              schema:
+                type: string
+        '400':
+          description: Invalid username/password supplied
+  /user/logout:
+    get:
+      tags:
+        - user
+      summary: Logs out current logged in user session
+      description: ''
+      operationId: logoutUser
+      parameters: []
+      responses:
+        default:
+          description: successful operation
+  '/user/{username}':
+    get:
+      tags:
+        - user
+      summary: Get user by user name
+      description: ''
+      operationId: getUserByName
+      parameters:
+        - name: username
+          in: path
+          description: 'The name that needs to be fetched. Use user1 for testing. '
+          required: true
+          schema:
+            type: string
+      responses:
+        '200':
+          description: successful operation
+          content:
+            application/xml:
+              schema:
+                $ref: '#/components/schemas/User'
+            application/json:
+              schema:
+                $ref: '#/components/schemas/User'
+        '400':
+          description: Invalid username supplied
+        '404':
+          description: User not found
+    put:
+      tags:
+        - user
+      summary: Update user
+      x-swagger-router-controller: UserController
+      description: This can only be done by the logged in user.
+      operationId: updateUser
+      parameters:
+        - name: username
+          in: path
+          description: name that need to be deleted
+          required: true
+          schema:
+            type: string
+      responses:
+        default:
+          description: successful operation
+      requestBody:
+        description: Update an existent user in the store
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/User'
+          application/xml:
+            schema:
+              $ref: '#/components/schemas/User'
+          application/x-www-form-urlencoded:
+            schema:
+              $ref: '#/components/schemas/User'
+    delete:
+      tags:
+        - user
+      summary: Delete user
+      description: This can only be done by the logged in user.
+      operationId: deleteUser
+      parameters:
+        - name: username
+          in: path
+          description: The name that needs to be deleted
+          required: true
+          schema:
+            type: string
+      responses:
+        '400':
+          description: Invalid username supplied
+        '404':
+          description: User not found
+externalDocs:
+  description: Find out more about Swagger
+  url: 'http://swagger.io'
+components:
+  schemas:
+    Order:
+      x-swagger-router-model: io.swagger.petstore.model.Order
+      properties:
+        id:
+          type: integer
+          format: int64
+          example: 10
+        petId:
+          type: integer
+          format: int64
+          example: 198772
+        quantity:
+          type: integer
+          format: int32
+          example: 7
+        shipDate:
+          type: string
+          format: date-time
+        status:
+          type: string
+          description: Order Status
+          enum:
+            - placed
+            - approved
+            - delivered
+          example: approved
+        complete:
+          type: boolean
+      xml:
+        name: order
+      type: object
+    Customer:
+      properties:
+        id:
+          type: integer
+          format: int64
+          example: 100000
+        username:
+          type: string
+          example: fehguy
+        address:
+          type: array
+          items:
+            $ref: '#/components/schemas/Address'
+          xml:
+            wrapped: true
+            name: addresses
+      xml:
+        name: customer
+      type: object
+    Address:
+      properties:
+        street:
+          type: string
+          example: 437 Lytton
+        city:
+          type: string
+          example: Palo Alto
+        state:
+          type: string
+          example: CA
+        zip:
+          type: string
+          example: 94301
+      xml:
+        name: address
+      type: object
+    Category:
+      x-swagger-router-model: io.swagger.petstore.model.Category
+      properties:
+        id:
+          type: integer
+          format: int64
+          example: 1
+        name:
+          type: string
+          example: Dogs
+      xml:
+        name: category
+      type: object
+    User:
+      x-swagger-router-model: io.swagger.petstore.model.User
+      properties:
+        id:
+          type: integer
+          format: int64
+          example: 10
+        username:
+          type: string
+          example: theUser
+        firstName:
+          type: string
+          example: John
+        lastName:
+          type: string
+          example: James
+        email:
+          type: string
+          example: john@email.com
+        password:
+          type: string
+          example: 12345
+        phone:
+          type: string
+          example: 12345
+        userStatus:
+          type: integer
+          format: int32
+          example: 1
+          description: User Status
+      xml:
+        name: user
+      type: object
+    Tag:
+      x-swagger-router-model: io.swagger.petstore.model.Tag
+      properties:
+        id:
+          type: integer
+          format: int64
+        name:
+          type: string
+      xml:
+        name: tag
+      type: object
+    Pet:
+      x-swagger-router-model: io.swagger.petstore.model.Pet
+      required:
+        - name
+        - photoUrls
+      properties:
+        id:
+          type: integer
+          format: int64
+          example: 10
+        name:
+          type: string
+          example: doggie
+        category:
+          $ref: '#/components/schemas/Category'
+        photoUrls:
+          type: array
+          xml:
+            wrapped: true
+          items:
+            type: string
+            xml:
+              name: photoUrl
+        tags:
+          type: array
+          xml:
+            wrapped: true
+          items:
+            $ref: '#/components/schemas/Tag'
+            xml:
+              name: tag
+        status:
+          type: string
+          description: pet status in the store
+          enum:
+            - available
+            - pending
+            - sold
+      xml:
+        name: pet
+      type: object
+    ApiResponse:
+      properties:
+        code:
+          type: integer
+          format: int32
+        type:
+          type: string
+        message:
+          type: string
+      xml:
+        name: '##default'
+      type: object
+  requestBodies:
+    Pet:
+      content:
+        application/json:
+          schema:
+            $ref: '#/components/schemas/Pet'
+        application/xml:
+          schema:
+            $ref: '#/components/schemas/Pet'
+      description: Pet object that needs to be added to the store
+    UserArray:
+      content:
+        application/json:
+          schema:
+            type: array
+            items:
+              $ref: '#/components/schemas/User'
+      description: List of user object
+  securitySchemes:
+    petstore_auth:
+      type: oauth2
+      flows:
+        implicit:
+          authorizationUrl: 'https://petstore.swagger.io/oauth/authorize'
+          scopes:
+            'write:pets': modify pets in your account
+            'read:pets': read your pets
+    api_key:
+      type: apiKey
+      name: api_key
+      in: header
\ No newline at end of file