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

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

commit 3c235f755619ecc75b35235096d30cbf8af7eefc
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Thu Apr 4 08:09:24 2024 +0200

    CAMEL-20557: Rest DSL to use openapi spec directly
---
 ...mHttpRestOpenApiConsumerRestDslBindingTest.java |  8 +++----
 .../rest/openapi/RestOpenApiComponent.java         | 12 ++++++----
 .../org/apache/camel/spi/RestConfiguration.java    | 13 +++++++++++
 .../camel/impl/RestConfigurationConfigurer.java    |  6 +++++
 .../apache/camel/model/rest/restConfiguration.json | 27 +++++++++++-----------
 .../model/rest/RestConfigurationDefinition.java    | 27 ++++++++++++++++++++++
 .../apache/camel/model/rest/RestDefinition.java    | 13 ++++++-----
 .../camel/reifier/rest/RestBindingReifier.java     |  1 +
 .../RestConfigurationPropertiesConfigurer.java     |  6 +++++
 .../camel-main-configuration-metadata.json         |  1 +
 core/camel-main/src/main/docs/main.adoc            |  3 ++-
 .../camel/main/RestConfigurationProperties.java    |  9 ++++++++
 .../processor/RestBindingConfiguration.java        |  9 ++++++++
 .../java/org/apache/camel/xml/in/ModelParser.java  |  1 +
 .../java/org/apache/camel/xml/out/ModelWriter.java |  1 +
 .../org/apache/camel/yaml/out/ModelWriter.java     |  1 +
 16 files changed, 109 insertions(+), 29 deletions(-)

diff --git 
a/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/PlatformHttpRestOpenApiConsumerRestDslBindingTest.java
 
b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/PlatformHttpRestOpenApiConsumerRestDslBindingTest.java
index 208f77982eb..454a7e6cec9 100644
--- 
a/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/PlatformHttpRestOpenApiConsumerRestDslBindingTest.java
+++ 
b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/PlatformHttpRestOpenApiConsumerRestDslBindingTest.java
@@ -73,11 +73,9 @@ public class 
PlatformHttpRestOpenApiConsumerRestDslBindingTest {
             context.addRoutes(new RouteBuilder() {
                 @Override
                 public void configure() {
-                    // TODO: make it easy to set binding package name in rest 
configuration
-                    context.getCamelContextExtension()
-                            
.setBasePackageScan("org.apache.camel.component.platform.http.vertx.model");
-
-                    restConfiguration().bindingMode(RestBindingMode.json);
+                    // turn on json binding and scan for POJO classes in the 
model package
+                    restConfiguration().bindingMode(RestBindingMode.json)
+                            
.bindingPackageScan("org.apache.camel.component.platform.http.vertx.model");
 
                     
rest().openApi().specification("openapi-v3.json").missingOperation("ignore");
 
diff --git 
a/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/RestOpenApiComponent.java
 
b/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/RestOpenApiComponent.java
index c5d5f85e123..2a4cd9ce10f 100644
--- 
a/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/RestOpenApiComponent.java
+++ 
b/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/RestOpenApiComponent.java
@@ -171,10 +171,14 @@ public final class RestOpenApiComponent extends 
DefaultComponent implements SSLC
     protected void doInit() throws Exception {
         super.doInit();
 
-        // use package scan for binding model classes
-        String current = 
getCamelContext().getCamelContextExtension().getBasePackageScan();
-        if (current != null && bindingPackageScan == null) {
-            bindingPackageScan = current;
+        if (bindingPackageScan == null) {
+            // prioritize use rest configuration
+            String base = 
getCamelContext().getRestConfiguration().getBindingPackageScan();
+            if (base == null) {
+                // over general base package from camel context
+                base = 
getCamelContext().getCamelContextExtension().getBasePackageScan();
+            }
+            bindingPackageScan = base;
         }
     }
 
diff --git 
a/core/camel-api/src/main/java/org/apache/camel/spi/RestConfiguration.java 
b/core/camel-api/src/main/java/org/apache/camel/spi/RestConfiguration.java
index ac2c5fe4950..bda68605e6e 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/RestConfiguration.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/RestConfiguration.java
@@ -63,6 +63,7 @@ public class RestConfiguration {
     private boolean apiVendorExtension;
     private RestHostNameResolver hostNameResolver = 
RestHostNameResolver.allLocalIp;
     private RestBindingMode bindingMode = RestBindingMode.off;
+    private String bindingPackageScan;
     private boolean skipBindingOnErrorCode = true;
     private boolean clientRequestValidation;
     private boolean inlineRoutes = true;
@@ -362,6 +363,18 @@ public class RestConfiguration {
         this.bindingMode = RestBindingMode.valueOf(bindingMode);
     }
 
+    public String getBindingPackageScan() {
+        return bindingPackageScan;
+    }
+
+    /**
+     * Package name to use as base (offset) for classpath scanning of POJO 
classes are located when using binding mode is enabled for JSon or XML.
+     * Multiple package names can be separated by comma.
+     */
+    public void setBindingPackageScan(String bindingPackageScan) {
+        this.bindingPackageScan = bindingPackageScan;
+    }
+
     /**
      * Whether to skip binding output if there is a custom HTTP error code, 
and instead use the response body as-is.
      * <p/>
diff --git 
a/core/camel-core-engine/src/generated/java/org/apache/camel/impl/RestConfigurationConfigurer.java
 
b/core/camel-core-engine/src/generated/java/org/apache/camel/impl/RestConfigurationConfigurer.java
index 7b6bccedec5..2e76fd7cb9e 100644
--- 
a/core/camel-core-engine/src/generated/java/org/apache/camel/impl/RestConfigurationConfigurer.java
+++ 
b/core/camel-core-engine/src/generated/java/org/apache/camel/impl/RestConfigurationConfigurer.java
@@ -35,6 +35,8 @@ public class RestConfigurationConfigurer extends 
org.apache.camel.support.compon
         case "apiVendorExtension": 
target.setApiVendorExtension(property(camelContext, boolean.class, value)); 
return true;
         case "bindingmode":
         case "bindingMode": target.setBindingMode(property(camelContext, 
java.lang.String.class, value)); return true;
+        case "bindingpackagescan":
+        case "bindingPackageScan": 
target.setBindingPackageScan(property(camelContext, java.lang.String.class, 
value)); return true;
         case "clientrequestvalidation":
         case "clientRequestValidation": 
target.setClientRequestValidation(property(camelContext, boolean.class, 
value)); return true;
         case "component": target.setComponent(property(camelContext, 
java.lang.String.class, value)); return true;
@@ -94,6 +96,8 @@ public class RestConfigurationConfigurer extends 
org.apache.camel.support.compon
         case "apiVendorExtension": return boolean.class;
         case "bindingmode":
         case "bindingMode": return java.lang.String.class;
+        case "bindingpackagescan":
+        case "bindingPackageScan": return java.lang.String.class;
         case "clientrequestvalidation":
         case "clientRequestValidation": return boolean.class;
         case "component": return java.lang.String.class;
@@ -154,6 +158,8 @@ public class RestConfigurationConfigurer extends 
org.apache.camel.support.compon
         case "apiVendorExtension": return target.isApiVendorExtension();
         case "bindingmode":
         case "bindingMode": return target.getBindingMode();
+        case "bindingpackagescan":
+        case "bindingPackageScan": return target.getBindingPackageScan();
         case "clientrequestvalidation":
         case "clientRequestValidation": return 
target.isClientRequestValidation();
         case "component": return target.getComponent();
diff --git 
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/rest/restConfiguration.json
 
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/rest/restConfiguration.json
index d72d7945fc5..60f460e2f1d 100644
--- 
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/rest/restConfiguration.json
+++ 
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/rest/restConfiguration.json
@@ -27,18 +27,19 @@
     "apiVendorExtension": { "index": 12, "kind": "attribute", "displayName": 
"Api Vendor Extension", "label": "consumer,advanced", "required": false, 
"type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether vendor extension is enabled in the Rest APIs. If enabled then Camel 
will include additional information as vendor extension (eg keys starting with 
x-) such as route ids, class names etc [...]
     "hostNameResolver": { "index": 13, "kind": "attribute", "displayName": 
"Host Name Resolver", "label": "consumer,advanced", "required": false, "type": 
"enum", "javaType": "org.apache.camel.model.rest.RestHostNameResolver", "enum": 
[ "allLocalIp", "localHostName", "localIp" ], "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "allLocalIp", "description": "If no 
hostname has been explicit configured, then this resolver is used to compute 
the hostname the REST ser [...]
     "bindingMode": { "index": 14, "kind": "attribute", "displayName": "Binding 
Mode", "required": false, "type": "enum", "javaType": 
"org.apache.camel.model.rest.RestBindingMode", "enum": [ "off", "auto", "json", 
"xml", "json_xml" ], "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": "off", "description": "Sets the binding mode to use. The 
default value is off" },
-    "skipBindingOnErrorCode": { "index": 15, "kind": "attribute", 
"displayName": "Skip Binding On Error Code", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether to skip binding on output if there is a custom HTTP error code header. 
This allows to build custom error messages that do not bind to json \/ xml etc, 
as success messages otherwise wil [...]
-    "clientRequestValidation": { "index": 16, "kind": "attribute", 
"displayName": "Client Request Validation", "label": "consumer,advanced", 
"required": false, "type": "boolean", "javaType": "java.lang.Boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
false, "description": "Whether to enable validation of the client request to 
check: 1) Content-Type header matches what the Rest DSL consumes; returns HTTP 
Status 415 if validation error. 2) Accept header m [...]
-    "enableCORS": { "index": 17, "kind": "attribute", "displayName": "Enable 
CORS", "label": "consumer,advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": false, "description": "Whether to enable CORS 
headers in the HTTP response. The default value is false." },
-    "enableNoContentResponse": { "index": 18, "kind": "attribute", 
"displayName": "Enable No Content Response", "label": "consumer,advanced", 
"required": false, "type": "boolean", "javaType": "java.lang.Boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
false, "description": "Whether to return HTTP 204 with an empty body when a 
response contains an empty JSON object or XML root object. The default value is 
false." },
-    "inlineRoutes": { "index": 19, "kind": "attribute", "displayName": "Inline 
Routes", "label": "consumer", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": true, "description": "Inline routes in rest-dsl which are 
linked using direct endpoints. Each service in Rest DSL is an individual route, 
meaning that you would have at least two routes per service (rest-dsl, and the 
route linked from res [...]
-    "jsonDataFormat": { "index": 20, "kind": "attribute", "displayName": "Json 
Data Format", "label": "advanced", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "Name of specific json data format to use. By 
default jackson will be used. Important: This option is only for setting a 
custom name of the data format, not to refer to an existing data format 
instance." },
-    "xmlDataFormat": { "index": 21, "kind": "attribute", "displayName": "Xml 
Data Format", "label": "advanced", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "Name of specific XML data format to use. By 
default jaxb will be used. Important: This option is only for setting a custom 
name of the data format, not to refer to an existing data format instance." },
-    "componentProperty": { "index": 22, "kind": "element", "displayName": 
"Component Property", "label": "advanced", "required": false, "type": "array", 
"javaType": 
"java.util.List<org.apache.camel.model.rest.RestPropertyDefinition>", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Allows to configure as many additional properties for the rest component in 
use." },
-    "endpointProperty": { "index": 23, "kind": "element", "displayName": 
"Endpoint Property", "label": "advanced", "required": false, "type": "array", 
"javaType": 
"java.util.List<org.apache.camel.model.rest.RestPropertyDefinition>", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Allows to configure as many additional properties for the rest endpoint in 
use." },
-    "consumerProperty": { "index": 24, "kind": "element", "displayName": 
"Consumer Property", "label": "consumer,advanced", "required": false, "type": 
"array", "javaType": 
"java.util.List<org.apache.camel.model.rest.RestPropertyDefinition>", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Allows to configure as many additional properties for the rest consumer in 
use." },
-    "dataFormatProperty": { "index": 25, "kind": "element", "displayName": 
"Data Format Property", "label": "advanced", "required": false, "type": 
"array", "javaType": 
"java.util.List<org.apache.camel.model.rest.RestPropertyDefinition>", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Allows to configure as many additional properties for the data formats in use. 
For example set property prettyPrint to true to have json outputted in pretty 
mode. The properties ca [...]
-    "apiProperty": { "index": 26, "kind": "element", "displayName": "Api 
Property", "label": "consumer,advanced", "required": false, "type": "array", 
"javaType": 
"java.util.List<org.apache.camel.model.rest.RestPropertyDefinition>", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Allows to configure as many additional properties for the api documentation. 
For example set property api.title to my cool stuff" },
-    "corsHeaders": { "index": 27, "kind": "element", "displayName": "Cors 
Headers", "label": "consumer,advanced", "required": false, "type": "array", 
"javaType": 
"java.util.List<org.apache.camel.model.rest.RestPropertyDefinition>", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Allows to configure custom CORS headers." }
+    "bindingPackageScan": { "index": 15, "kind": "attribute", "displayName": 
"Binding Package Scan", "label": "consumer,advanced", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "Package name to use as 
base (offset) for classpath scanning of POJO classes are located when using 
binding mode is enabled for JSon or XML. Multiple package names can be 
separated by comma." },
+    "skipBindingOnErrorCode": { "index": 16, "kind": "attribute", 
"displayName": "Skip Binding On Error Code", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether to skip binding on output if there is a custom HTTP error code header. 
This allows to build custom error messages that do not bind to json \/ xml etc, 
as success messages otherwise wil [...]
+    "clientRequestValidation": { "index": 17, "kind": "attribute", 
"displayName": "Client Request Validation", "label": "consumer,advanced", 
"required": false, "type": "boolean", "javaType": "java.lang.Boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
false, "description": "Whether to enable validation of the client request to 
check: 1) Content-Type header matches what the Rest DSL consumes; returns HTTP 
Status 415 if validation error. 2) Accept header m [...]
+    "enableCORS": { "index": 18, "kind": "attribute", "displayName": "Enable 
CORS", "label": "consumer,advanced", "required": false, "type": "boolean", 
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": false, "description": "Whether to enable CORS 
headers in the HTTP response. The default value is false." },
+    "enableNoContentResponse": { "index": 19, "kind": "attribute", 
"displayName": "Enable No Content Response", "label": "consumer,advanced", 
"required": false, "type": "boolean", "javaType": "java.lang.Boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
false, "description": "Whether to return HTTP 204 with an empty body when a 
response contains an empty JSON object or XML root object. The default value is 
false." },
+    "inlineRoutes": { "index": 20, "kind": "attribute", "displayName": "Inline 
Routes", "label": "consumer", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": true, "description": "Inline routes in rest-dsl which are 
linked using direct endpoints. Each service in Rest DSL is an individual route, 
meaning that you would have at least two routes per service (rest-dsl, and the 
route linked from res [...]
+    "jsonDataFormat": { "index": 21, "kind": "attribute", "displayName": "Json 
Data Format", "label": "advanced", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "Name of specific json data format to use. By 
default jackson will be used. Important: This option is only for setting a 
custom name of the data format, not to refer to an existing data format 
instance." },
+    "xmlDataFormat": { "index": 22, "kind": "attribute", "displayName": "Xml 
Data Format", "label": "advanced", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "Name of specific XML data format to use. By 
default jaxb will be used. Important: This option is only for setting a custom 
name of the data format, not to refer to an existing data format instance." },
+    "componentProperty": { "index": 23, "kind": "element", "displayName": 
"Component Property", "label": "advanced", "required": false, "type": "array", 
"javaType": 
"java.util.List<org.apache.camel.model.rest.RestPropertyDefinition>", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Allows to configure as many additional properties for the rest component in 
use." },
+    "endpointProperty": { "index": 24, "kind": "element", "displayName": 
"Endpoint Property", "label": "advanced", "required": false, "type": "array", 
"javaType": 
"java.util.List<org.apache.camel.model.rest.RestPropertyDefinition>", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Allows to configure as many additional properties for the rest endpoint in 
use." },
+    "consumerProperty": { "index": 25, "kind": "element", "displayName": 
"Consumer Property", "label": "consumer,advanced", "required": false, "type": 
"array", "javaType": 
"java.util.List<org.apache.camel.model.rest.RestPropertyDefinition>", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Allows to configure as many additional properties for the rest consumer in 
use." },
+    "dataFormatProperty": { "index": 26, "kind": "element", "displayName": 
"Data Format Property", "label": "advanced", "required": false, "type": 
"array", "javaType": 
"java.util.List<org.apache.camel.model.rest.RestPropertyDefinition>", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Allows to configure as many additional properties for the data formats in use. 
For example set property prettyPrint to true to have json outputted in pretty 
mode. The properties ca [...]
+    "apiProperty": { "index": 27, "kind": "element", "displayName": "Api 
Property", "label": "consumer,advanced", "required": false, "type": "array", 
"javaType": 
"java.util.List<org.apache.camel.model.rest.RestPropertyDefinition>", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Allows to configure as many additional properties for the api documentation. 
For example set property api.title to my cool stuff" },
+    "corsHeaders": { "index": 28, "kind": "element", "displayName": "Cors 
Headers", "label": "consumer,advanced", "required": false, "type": "array", 
"javaType": 
"java.util.List<org.apache.camel.model.rest.RestPropertyDefinition>", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Allows to configure custom CORS headers." }
   }
 }
diff --git 
a/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestConfigurationDefinition.java
 
b/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestConfigurationDefinition.java
index d770f6cae1a..3186fb5a383 100644
--- 
a/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestConfigurationDefinition.java
+++ 
b/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestConfigurationDefinition.java
@@ -83,6 +83,9 @@ public class RestConfigurationDefinition {
     @Metadata(defaultValue = "off", enums = "off,auto,json,xml,json_xml")
     private RestBindingMode bindingMode;
     @XmlAttribute
+    @Metadata(label = "consumer,advanced")
+    private String bindingPackageScan;
+    @XmlAttribute
     @Metadata(label = "advanced", javaType = "java.lang.Boolean", defaultValue 
= "false")
     private String skipBindingOnErrorCode;
     @XmlAttribute
@@ -313,6 +316,18 @@ public class RestConfigurationDefinition {
         this.bindingMode = bindingMode;
     }
 
+    public String getBindingPackageScan() {
+        return bindingPackageScan;
+    }
+
+    /**
+     * Package name to use as base (offset) for classpath scanning of POJO 
classes are located when using binding mode is enabled for JSon or XML.
+     * Multiple package names can be separated by comma.
+     */
+    public void setBindingPackageScan(String bindingPackageScan) {
+        this.bindingPackageScan = bindingPackageScan;
+    }
+
     public String getSkipBindingOnErrorCode() {
         return skipBindingOnErrorCode;
     }
@@ -658,6 +673,15 @@ public class RestConfigurationDefinition {
         return this;
     }
 
+    /**
+     * Package name to use as base (offset) for classpath scanning of POJO 
classes are located when using binding mode is enabled for JSon or XML.
+     * Multiple package names can be separated by comma.
+     */
+    public RestConfigurationDefinition bindingPackageScan(String 
bindingPackageScan) {
+        setBindingPackageScan(bindingPackageScan);
+        return this;
+    }
+
     /**
      * To specify whether to skip binding output if there is a custom HTTP 
error code
      */
@@ -956,6 +980,9 @@ public class RestConfigurationDefinition {
         if (bindingMode != null) {
             target.setBindingMode(bindingMode.name());
         }
+        if (bindingPackageScan != null) {
+            target.setBindingPackageScan(bindingPackageScan);
+        }
         if (skipBindingOnErrorCode != null) {
             
target.setSkipBindingOnErrorCode(CamelContextHelper.parseBoolean(context, 
skipBindingOnErrorCode));
         }
diff --git 
a/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestDefinition.java
 
b/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestDefinition.java
index 427f8136202..fa549a46a8f 100644
--- 
a/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestDefinition.java
+++ 
b/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestDefinition.java
@@ -997,6 +997,7 @@ public class RestDefinition extends 
OptionalIdentifiedDefinition<RestDefinition>
             binding.setConsumes("application/json;application/xml");
             binding.setProduces("application/json;application/xml");
         }
+        binding.setBindingMode(mode);
         binding.setSkipBindingOnErrorCode(getSkipBindingOnErrorCode());
         binding.setClientRequestValidation(getClientRequestValidation());
         binding.setEnableCORS(getEnableCORS());
@@ -1006,24 +1007,24 @@ public class RestDefinition extends 
OptionalIdentifiedDefinition<RestDefinition>
         // append options
         Map<String, Object> options = new HashMap<>();
         if (binding.getConsumes() != null) {
-            options.put("consumes", binding.getConsumes());
+            options.put("consumes", parseText(camelContext, 
binding.getConsumes()));
         }
         if (binding.getProduces() != null) {
-            options.put("produces", binding.getProduces());
+            options.put("produces", parseText(camelContext, 
binding.getProduces()));
         }
         if (getClientRequestValidation() != null) {
-            options.put("clientRequestValidation", 
getClientRequestValidation());
+            options.put("clientRequestValidation", parseBoolean(camelContext, 
getClientRequestValidation()));
         } else if (clientValidation) {
             options.put("clientRequestValidation", "true");
         }
         if (openApi.getMissingOperation() != null) {
-            options.put("missingOperation", openApi.getMissingOperation());
+            options.put("missingOperation", parseText(camelContext, 
openApi.getMissingOperation()));
         }
         if (openApi.getMockIncludePattern() != null) {
-            options.put("mockIncludePattern", openApi.getMockIncludePattern());
+            options.put("mockIncludePattern", parseText(camelContext, 
openApi.getMockIncludePattern()));
         }
         if (openApi.getApiContextPath() != null) {
-            options.put("apiContextPath", openApi.getApiContextPath());
+            options.put("apiContextPath", parseText(camelContext, 
openApi.getApiContextPath()));
         }
 
         // include optional description
diff --git 
a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/rest/RestBindingReifier.java
 
b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/rest/RestBindingReifier.java
index 67f872abec8..6e3f7fa08f4 100644
--- 
a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/rest/RestBindingReifier.java
+++ 
b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/rest/RestBindingReifier.java
@@ -45,6 +45,7 @@ public class RestBindingReifier extends AbstractReifier {
             mode = parse(RestBindingMode.class, 
definition.getBindingMode()).name();
         }
         rbc.setBindingMode(mode);
+        rbc.setBindingPackageScan(config.getBindingPackageScan());
         boolean cors = config.isEnableCORS();
         if (definition.getEnableCORS() != null) {
             cors = parseBoolean(definition.getEnableCORS(), false);
diff --git 
a/core/camel-main/src/generated/java/org/apache/camel/main/RestConfigurationPropertiesConfigurer.java
 
b/core/camel-main/src/generated/java/org/apache/camel/main/RestConfigurationPropertiesConfigurer.java
index 03d56421c17..41c79ffb94e 100644
--- 
a/core/camel-main/src/generated/java/org/apache/camel/main/RestConfigurationPropertiesConfigurer.java
+++ 
b/core/camel-main/src/generated/java/org/apache/camel/main/RestConfigurationPropertiesConfigurer.java
@@ -35,6 +35,8 @@ public class RestConfigurationPropertiesConfigurer extends 
org.apache.camel.supp
         case "apiVendorExtension": 
target.setApiVendorExtension(property(camelContext, boolean.class, value)); 
return true;
         case "bindingmode":
         case "bindingMode": target.setBindingMode(property(camelContext, 
java.lang.String.class, value)); return true;
+        case "bindingpackagescan":
+        case "bindingPackageScan": 
target.setBindingPackageScan(property(camelContext, java.lang.String.class, 
value)); return true;
         case "clientrequestvalidation":
         case "clientRequestValidation": 
target.setClientRequestValidation(property(camelContext, boolean.class, 
value)); return true;
         case "component": target.setComponent(property(camelContext, 
java.lang.String.class, value)); return true;
@@ -94,6 +96,8 @@ public class RestConfigurationPropertiesConfigurer extends 
org.apache.camel.supp
         case "apiVendorExtension": return boolean.class;
         case "bindingmode":
         case "bindingMode": return java.lang.String.class;
+        case "bindingpackagescan":
+        case "bindingPackageScan": return java.lang.String.class;
         case "clientrequestvalidation":
         case "clientRequestValidation": return boolean.class;
         case "component": return java.lang.String.class;
@@ -154,6 +158,8 @@ public class RestConfigurationPropertiesConfigurer extends 
org.apache.camel.supp
         case "apiVendorExtension": return target.isApiVendorExtension();
         case "bindingmode":
         case "bindingMode": return target.getBindingMode();
+        case "bindingpackagescan":
+        case "bindingPackageScan": return target.getBindingPackageScan();
         case "clientrequestvalidation":
         case "clientRequestValidation": return 
target.isClientRequestValidation();
         case "component": return target.getComponent();
diff --git 
a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
 
b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
index 942ec07472f..6a5e64eabbf 100644
--- 
a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
+++ 
b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
@@ -216,6 +216,7 @@
     { "name": "camel.rest.apiProperties", "description": "Sets additional 
options on api level", "sourceType": "org.apache.camel.spi.RestConfiguration", 
"type": "object", "javaType": "java.util.Map" },
     { "name": "camel.rest.apiVendorExtension", "description": "Whether vendor 
extension is enabled in the Rest APIs. If enabled then Camel will include 
additional information as vendor extension (eg keys starting with x-) such as 
route ids, class names etc. Not all 3rd party API gateways and tools supports 
vendor-extensions when importing your API docs.", "sourceType": 
"org.apache.camel.spi.RestConfiguration", "type": "boolean", "javaType": 
"boolean", "defaultValue": "false" },
     { "name": "camel.rest.bindingMode", "description": "Sets the binding mode 
to be used by the REST consumer", "sourceType": 
"org.apache.camel.spi.RestConfiguration", "type": "object", "javaType": 
"org.apache.camel.spi.RestBindingMode", "defaultValue": "RestBindingMode.off", 
"enum": [ "auto", "off", "json", "xml", "json_xml" ] },
+    { "name": "camel.rest.bindingPackageScan", "description": "Package name to 
use as base (offset) for classpath scanning of POJO classes are located when 
using binding mode is enabled for JSon or XML. Multiple package names can be 
separated by comma.", "sourceType": "org.apache.camel.spi.RestConfiguration", 
"type": "string", "javaType": "java.lang.String" },
     { "name": "camel.rest.clientRequestValidation", "description": "Whether to 
enable validation of the client request to check: 1) Content-Type header 
matches what the Rest DSL consumes; returns HTTP Status 415 if validation 
error. 2) Accept header matches what the Rest DSL produces; returns HTTP Status 
406 if validation error. 3) Missing required data (query parameters, HTTP 
headers, body); returns HTTP Status 400 if validation error. 4) Parsing error 
of the message body (JSon, XML or  [...]
     { "name": "camel.rest.component", "description": "Sets the name of the 
Camel component to use as the REST consumer", "sourceType": 
"org.apache.camel.spi.RestConfiguration", "type": "string", "javaType": 
"java.lang.String" },
     { "name": "camel.rest.componentProperties", "description": "Sets 
additional options on component level", "sourceType": 
"org.apache.camel.spi.RestConfiguration", "type": "object", "javaType": 
"java.util.Map" },
diff --git a/core/camel-main/src/main/docs/main.adoc 
b/core/camel-main/src/main/docs/main.adoc
index 2f1bf56bfa1..9030646a5de 100644
--- a/core/camel-main/src/main/docs/main.adoc
+++ b/core/camel-main/src/main/docs/main.adoc
@@ -282,7 +282,7 @@ The camel.health supports 8 options, which are listed below.
 
 
 === Camel Rest-DSL configurations
-The camel.rest supports 28 options, which are listed below.
+The camel.rest supports 29 options, which are listed below.
 
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
@@ -294,6 +294,7 @@ The camel.rest supports 28 options, which are listed below.
 | *camel.rest.apiProperties* | Sets additional options on api level |  | Map
 | *camel.rest.apiVendorExtension* | Whether vendor extension is enabled in the 
Rest APIs. If enabled then Camel will include additional information as vendor 
extension (eg keys starting with x-) such as route ids, class names etc. Not 
all 3rd party API gateways and tools supports vendor-extensions when importing 
your API docs. | false | boolean
 | *camel.rest.bindingMode* | Sets the binding mode to be used by the REST 
consumer | RestBindingMode.off | RestBindingMode
+| *camel.rest.bindingPackageScan* | Package name to use as base (offset) for 
classpath scanning of POJO classes are located when using binding mode is 
enabled for JSon or XML. Multiple package names can be separated by comma. |  | 
String
 | *camel.rest.clientRequest{zwsp}Validation* | Whether to enable validation of 
the client request to check: 1) Content-Type header matches what the Rest DSL 
consumes; returns HTTP Status 415 if validation error. 2) Accept header matches 
what the Rest DSL produces; returns HTTP Status 406 if validation error. 3) 
Missing required data (query parameters, HTTP headers, body); returns HTTP 
Status 400 if validation error. 4) Parsing error of the message body (JSon, XML 
or Auto binding mode mus [...]
 | *camel.rest.component* | Sets the name of the Camel component to use as the 
REST consumer |  | String
 | *camel.rest.componentProperties* | Sets additional options on component 
level |  | Map
diff --git 
a/core/camel-main/src/main/java/org/apache/camel/main/RestConfigurationProperties.java
 
b/core/camel-main/src/main/java/org/apache/camel/main/RestConfigurationProperties.java
index a39fb09e790..126d1fcbf02 100644
--- 
a/core/camel-main/src/main/java/org/apache/camel/main/RestConfigurationProperties.java
+++ 
b/core/camel-main/src/main/java/org/apache/camel/main/RestConfigurationProperties.java
@@ -212,6 +212,15 @@ public class RestConfigurationProperties extends 
RestConfiguration implements Bo
         return this;
     }
 
+    /**
+     * Package name to use as base (offset) for classpath scanning of POJO 
classes are located when using binding mode is enabled for JSon or XML.
+     * Multiple package names can be separated by comma.
+     */
+    public RestConfigurationProperties withBindingPackageScan(String 
bindingPackageScan) {
+        setBindingPackageScan(bindingPackageScan);
+        return this;
+    }
+
     /**
      * Whether to skip binding on output if there is a custom HTTP error code 
header. This allows to build custom error
      * messages that do not bind to json / xml etc, as success messages 
otherwise will do.
diff --git 
a/core/camel-support/src/main/java/org/apache/camel/support/processor/RestBindingConfiguration.java
 
b/core/camel-support/src/main/java/org/apache/camel/support/processor/RestBindingConfiguration.java
index 383d33a3a04..95a4b1ea5e0 100644
--- 
a/core/camel-support/src/main/java/org/apache/camel/support/processor/RestBindingConfiguration.java
+++ 
b/core/camel-support/src/main/java/org/apache/camel/support/processor/RestBindingConfiguration.java
@@ -27,6 +27,7 @@ public class RestBindingConfiguration {
     private String consumes;
     private String produces;
     private String bindingMode;
+    private String bindingPackageScan;
     private boolean skipBindingOnErrorCode;
     private boolean clientRequestValidation;
     private boolean enableCORS;
@@ -65,6 +66,14 @@ public class RestBindingConfiguration {
         this.bindingMode = bindingMode;
     }
 
+    public String getBindingPackageScan() {
+        return bindingPackageScan;
+    }
+
+    public void setBindingPackageScan(String bindingPackageScan) {
+        this.bindingPackageScan = bindingPackageScan;
+    }
+
     public boolean isSkipBindingOnErrorCode() {
         return skipBindingOnErrorCode;
     }
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 aaefc3d2747..d8807a60ffa 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
@@ -1752,6 +1752,7 @@ public class ModelParser extends BaseParser {
                 case "apiHost": def.setApiHost(val); break;
                 case "apiVendorExtension": def.setApiVendorExtension(val); 
break;
                 case "bindingMode": 
def.setBindingMode(RestBindingMode.valueOf(val)); break;
+                case "bindingPackageScan": def.setBindingPackageScan(val); 
break;
                 case "clientRequestValidation": 
def.setClientRequestValidation(val); break;
                 case "component": def.setComponent(val); break;
                 case "contextPath": def.setContextPath(val); break;
diff --git 
a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java
 
b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java
index b2d94894bf5..eb9433c08bb 100644
--- 
a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java
+++ 
b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java
@@ -4541,6 +4541,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("host", def.getHost());
         doWriteAttribute("producerComponent", def.getProducerComponent());
         doWriteAttribute("enableCORS", def.getEnableCORS());
+        doWriteAttribute("bindingPackageScan", def.getBindingPackageScan());
         doWriteAttribute("useXForwardHeaders", def.getUseXForwardHeaders());
         doWriteAttribute("apiHost", def.getApiHost());
         doWriteAttribute("contextPath", def.getContextPath());
diff --git 
a/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java
 
b/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java
index eecb2246f2d..f4d114a2d51 100644
--- 
a/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java
+++ 
b/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java
@@ -4541,6 +4541,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("host", def.getHost());
         doWriteAttribute("producerComponent", def.getProducerComponent());
         doWriteAttribute("enableCORS", def.getEnableCORS());
+        doWriteAttribute("bindingPackageScan", def.getBindingPackageScan());
         doWriteAttribute("useXForwardHeaders", def.getUseXForwardHeaders());
         doWriteAttribute("apiHost", def.getApiHost());
         doWriteAttribute("contextPath", def.getContextPath());


Reply via email to