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 853e94510bf CAMEL-22121: rest-dsl: Add client response validator
853e94510bf is described below

commit 853e94510bfedf06b4fbf6f9bfd0f1ded18d581f
Author: Claus Ibsen <[email protected]>
AuthorDate: Tue Jun 17 14:14:56 2025 +0200

    CAMEL-22121: rest-dsl: Add client response validator
---
 .../main/camel-main-configuration-metadata.json    |  1 +
 .../camel/catalog/models/restConfiguration.json    |  3 +-
 .../apache/camel/catalog/schemas/camel-spring.xsd  |  9 ++++++
 .../apache/camel/catalog/schemas/camel-xml-io.xsd  |  9 ++++++
 .../src/main/docs/openapi-validator.adoc           | 14 +++++++++
 .../client/OpenApiRestClientRequestValidator.java  | 32 ++++++++++++++++++--
 .../client/OpenApiRestClientResponseValidator.java | 32 ++++++++++++++++++--
 .../OpenApiRestClientRequestValidatorTest.java     |  9 ++++++
 .../src/test/resources/log4j2.properties           |  4 +++
 .../org/apache/camel/spi/RestConfiguration.java    | 17 +++++++++++
 .../camel/impl/RestConfigurationConfigurer.java    |  8 +++++
 .../apache/camel/model/rest/restConfiguration.json |  3 +-
 .../model/rest/RestConfigurationDefinition.java    | 34 ++++++++++++++++++++++
 .../RestConfigurationPropertiesConfigurer.java     |  9 ++++++
 .../camel-main-configuration-metadata.json         |  1 +
 core/camel-main/src/main/docs/main.adoc            |  3 +-
 .../camel/main/RestConfigurationProperties.java    | 12 ++++++++
 .../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 +
 .../dsl/yaml/deserializers/ModelDeserializers.java |  6 ++++
 .../generated/resources/schema/camelYamlDsl.json   |  8 +++++
 22 files changed, 208 insertions(+), 9 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
index 339f9e360d2..ecd123e7a0b 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
@@ -282,6 +282,7 @@
     { "name": "camel.rest.scheme", "description": "Sets the scheme to use by 
the REST consumer", "sourceType": "org.apache.camel.spi.RestConfiguration", 
"type": "string", "javaType": "java.lang.String" },
     { "name": "camel.rest.skipBindingOnErrorCode", "description": "Whether to 
skip binding output if there is a custom HTTP error code, and instead use the 
response body as-is. This option is default true.", "sourceType": 
"org.apache.camel.spi.RestConfiguration", "type": "boolean", "javaType": 
"boolean", "defaultValue": true },
     { "name": "camel.rest.useXForwardHeaders", "description": "Whether to use 
X-Forward headers to set host etc. for OpenApi. This may be needed in special 
cases involving reverse-proxy and networking going from HTTP to HTTPS etc. Then 
the proxy can send X-Forward headers (X-Forwarded-Proto) that influences the 
host names in the OpenAPI schema that camel-openapi-java generates from Rest 
DSL routes.", "sourceType": "org.apache.camel.spi.RestConfiguration", "type": 
"boolean", "javaType": " [...]
+    { "name": "camel.rest.validationLevels", "description": "Sets the client 
request validation levels when using camel-openapi-validator.", "sourceType": 
"org.apache.camel.spi.RestConfiguration", "type": "object", "javaType": 
"java.util.Map" },
     { "name": "camel.rest.xmlDataFormat", "description": "Sets a custom xml 
data format to 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.", 
"sourceType": "org.apache.camel.spi.RestConfiguration", "type": "string", 
"javaType": "java.lang.String" },
     { "name": "camel.routecontroller.backOffDelay", "description": "Backoff 
delay in millis when restarting a route that failed to startup.", "sourceType": 
"org.apache.camel.main.RouteControllerConfigurationProperties", "type": 
"integer", "javaType": "long", "defaultValue": 2000 },
     { "name": "camel.routecontroller.backOffMaxAttempts", "description": 
"Backoff maximum number of attempts to restart a route that failed to startup. 
When this threshold has been exceeded then the controller will give up 
attempting to restart the route, and the route will remain as stopped.", 
"sourceType": "org.apache.camel.main.RouteControllerConfigurationProperties", 
"type": "integer", "javaType": "long" },
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/restConfiguration.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/restConfiguration.json
index a1da1650ec6..ad355731a51 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/restConfiguration.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/restConfiguration.json
@@ -41,6 +41,7 @@
     "consumerProperty": { "index": 26, "kind": "element", "displayName": 
"Consumer Property", "group": "consumer (advanced)", "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": 27, "kind": "element", "displayName": 
"Data Format Property", "group": "advanced", "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 
mo [...]
     "apiProperty": { "index": 28, "kind": "element", "displayName": "Api 
Property", "group": "consumer (advanced)", "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": 29, "kind": "element", "displayName": "Cors 
Headers", "group": "consumer (advanced)", "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." }
+    "corsHeaders": { "index": 29, "kind": "element", "displayName": "Cors 
Headers", "group": "consumer (advanced)", "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." },
+    "validationLevels": { "index": 30, "kind": "element", "displayName": 
"Validation Levels", "group": "consumer (advanced)", "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 validation levels when using 
camel-openapi-validator with client request\/response validator." }
   }
 }
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 119c7ad7ed1..bffbe6ee933 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
@@ -15076,6 +15076,15 @@ cool stuff.
           <xs:documentation xml:lang="en">
 <![CDATA[
 Allows to configure custom CORS headers.
+]]>
+          </xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element maxOccurs="unbounded" minOccurs="0" name="validationLevels" 
type="tns:restPropertyDefinition">
+        <xs:annotation>
+          <xs:documentation xml:lang="en">
+<![CDATA[
+Allows to configure custom validation levels when using 
camel-openapi-validator with client request/response validator.
 ]]>
           </xs:documentation>
         </xs:annotation>
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-xml-io.xsd
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-xml-io.xsd
index 03be38284e2..1566ea1afde 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-xml-io.xsd
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-xml-io.xsd
@@ -13770,6 +13770,15 @@ cool stuff.
           <xs:documentation xml:lang="en">
 <![CDATA[
 Allows to configure custom CORS headers.
+]]>
+          </xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element maxOccurs="unbounded" minOccurs="0" name="validationLevels" 
type="tns:restPropertyDefinition">
+        <xs:annotation>
+          <xs:documentation xml:lang="en">
+<![CDATA[
+Allows to configure custom validation levels when using 
camel-openapi-validator with client request/response validator.
 ]]>
           </xs:documentation>
         </xs:annotation>
diff --git 
a/components/camel-openapi-validator/src/main/docs/openapi-validator.adoc 
b/components/camel-openapi-validator/src/main/docs/openapi-validator.adoc
index e16bab971a5..7506c61ae07 100644
--- a/components/camel-openapi-validator/src/main/docs/openapi-validator.adoc
+++ b/components/camel-openapi-validator/src/main/docs/openapi-validator.adoc
@@ -20,3 +20,17 @@ NOTE: This library does not work with running in 
`camel-jbang`.
 == Auto-detection from classpath
 
 To use this implementation all you need to do is to add the 
`camel-openapi-validator` dependency to the classpath.
+
+=== Configuring levels of errors
+
+The Atlassian Swagger Request Validator supports configuring 
https://bitbucket.org/atlassian/swagger-request-validator/src/c6200d0d849ae69be679f7fe01042cd9e84637c4/swagger-request-validator-core/README.md[fine-grained
 levels]
+for validating. This allows to turn on ignoring some specific errors.
+
+For example, you can ignore query parameters
+
+[source,properties]
+----
+camel.rest.validation-levels[validation.schema.required] = INFO
+camel.rest.validation-levels[validation.request.parameter.query.missing] = 
IGNORE
+camel.rest.validation-levels[validation.response.body.missing] = WARN
+----
diff --git 
a/components/camel-openapi-validator/src/main/java/org/apache/camel/component/rest/openapi/validator/client/OpenApiRestClientRequestValidator.java
 
b/components/camel-openapi-validator/src/main/java/org/apache/camel/component/rest/openapi/validator/client/OpenApiRestClientRequestValidator.java
index b6e857fc268..a2c5f1c4380 100644
--- 
a/components/camel-openapi-validator/src/main/java/org/apache/camel/component/rest/openapi/validator/client/OpenApiRestClientRequestValidator.java
+++ 
b/components/camel-openapi-validator/src/main/java/org/apache/camel/component/rest/openapi/validator/client/OpenApiRestClientRequestValidator.java
@@ -19,6 +19,7 @@ package 
org.apache.camel.component.rest.openapi.validator.client;
 import com.atlassian.oai.validator.OpenApiInteractionValidator;
 import com.atlassian.oai.validator.model.SimpleRequest;
 import com.atlassian.oai.validator.report.JsonValidationReportFormat;
+import com.atlassian.oai.validator.report.LevelResolver;
 import com.atlassian.oai.validator.report.SimpleValidationReportFormat;
 import com.atlassian.oai.validator.report.ValidationReport;
 import io.swagger.v3.oas.models.OpenAPI;
@@ -27,13 +28,18 @@ import 
org.apache.camel.component.rest.openapi.RestOpenApiComponent;
 import org.apache.camel.component.rest.openapi.RestOpenApiHelper;
 import org.apache.camel.http.base.HttpHeaderFilterStrategy;
 import org.apache.camel.spi.RestClientRequestValidator;
+import org.apache.camel.spi.RestConfiguration;
 import org.apache.camel.spi.annotations.JdkService;
 import org.apache.camel.support.ExchangeHelper;
 import org.apache.camel.support.MessageHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 @JdkService(RestClientRequestValidator.FACTORY)
 public class OpenApiRestClientRequestValidator implements 
RestClientRequestValidator {
 
+    private static final Logger LOG = 
LoggerFactory.getLogger(OpenApiRestClientRequestValidator.class);
+
     private final HttpHeaderFilterStrategy filter = new 
HttpHeaderFilterStrategy();
 
     public OpenApiRestClientRequestValidator() {
@@ -102,16 +108,36 @@ public class OpenApiRestClientRequestValidator implements 
RestClientRequestValid
             }
         }
 
-        OpenApiInteractionValidator validator = 
OpenApiInteractionValidator.createFor(openAPI).build();
+        LevelResolver.Builder lr = LevelResolver.create();
+        RestConfiguration rc = exchange.getContext().getRestConfiguration();
+        if (rc.getValidationLevels() != null) {
+            for (var e : rc.getValidationLevels().entrySet()) {
+                String key = e.getKey();
+                var level = ValidationReport.Level.valueOf(e.getValue());
+                if ("defaultLevel".equalsIgnoreCase(key)) {
+                    lr.withDefaultLevel(level);
+                } else {
+                    lr.withLevel(key, level);
+                }
+            }
+        }
+        OpenApiInteractionValidator validator = 
OpenApiInteractionValidator.createFor(openAPI)
+                .withLevelResolver(lr.build())
+                .build();
         ValidationReport report = validator.validateRequest(builder.build());
-        if (report.hasErrors()) {
+
+        // create report if error of DEBUG logging
+        if (report.hasErrors() || LOG.isDebugEnabled()) {
             String msg;
             if (accept != null && accept.contains("application/json")) {
                 msg = JsonValidationReportFormat.getInstance().apply(report);
             } else {
                 msg = SimpleValidationReportFormat.getInstance().apply(report);
             }
-            return new ValidationError(400, msg);
+            LOG.debug("Client Request Validation: {}", msg);
+            if (report.hasErrors()) {
+                return new ValidationError(400, msg);
+            }
         }
 
         return null;
diff --git 
a/components/camel-openapi-validator/src/main/java/org/apache/camel/component/rest/openapi/validator/client/OpenApiRestClientResponseValidator.java
 
b/components/camel-openapi-validator/src/main/java/org/apache/camel/component/rest/openapi/validator/client/OpenApiRestClientResponseValidator.java
index bf45f1fea63..5c8002fac2d 100644
--- 
a/components/camel-openapi-validator/src/main/java/org/apache/camel/component/rest/openapi/validator/client/OpenApiRestClientResponseValidator.java
+++ 
b/components/camel-openapi-validator/src/main/java/org/apache/camel/component/rest/openapi/validator/client/OpenApiRestClientResponseValidator.java
@@ -20,6 +20,7 @@ import 
com.atlassian.oai.validator.OpenApiInteractionValidator;
 import com.atlassian.oai.validator.model.Request;
 import com.atlassian.oai.validator.model.SimpleResponse;
 import com.atlassian.oai.validator.report.JsonValidationReportFormat;
+import com.atlassian.oai.validator.report.LevelResolver;
 import com.atlassian.oai.validator.report.SimpleValidationReportFormat;
 import com.atlassian.oai.validator.report.ValidationReport;
 import io.swagger.v3.oas.models.OpenAPI;
@@ -28,13 +29,18 @@ import 
org.apache.camel.component.rest.openapi.RestOpenApiComponent;
 import org.apache.camel.component.rest.openapi.RestOpenApiHelper;
 import org.apache.camel.http.base.HttpHeaderFilterStrategy;
 import org.apache.camel.spi.RestClientResponseValidator;
+import org.apache.camel.spi.RestConfiguration;
 import org.apache.camel.spi.annotations.JdkService;
 import org.apache.camel.support.ExchangeHelper;
 import org.apache.camel.support.MessageHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 @JdkService(RestClientResponseValidator.FACTORY)
 public class OpenApiRestClientResponseValidator implements 
RestClientResponseValidator {
 
+    private static final Logger LOG = 
LoggerFactory.getLogger(OpenApiRestClientResponseValidator.class);
+
     private final HttpHeaderFilterStrategy filter = new 
HttpHeaderFilterStrategy();
 
     public OpenApiRestClientResponseValidator() {
@@ -93,16 +99,36 @@ public class OpenApiRestClientResponseValidator implements 
RestClientResponseVal
             }
         }
 
-        OpenApiInteractionValidator validator = 
OpenApiInteractionValidator.createFor(openAPI).build();
+        LevelResolver.Builder lr = LevelResolver.create();
+        RestConfiguration rc = exchange.getContext().getRestConfiguration();
+        if (rc.getValidationLevels() != null) {
+            for (var e : rc.getValidationLevels().entrySet()) {
+                String key = e.getKey();
+                var level = ValidationReport.Level.valueOf(e.getValue());
+                if ("defaultLevel".equalsIgnoreCase(key)) {
+                    lr.withDefaultLevel(level);
+                } else {
+                    lr.withLevel(key, level);
+                }
+            }
+        }
+        OpenApiInteractionValidator validator = 
OpenApiInteractionValidator.createFor(openAPI)
+                .withLevelResolver(lr.build())
+                .build();
         ValidationReport report = validator.validateResponse(path, 
asMethod(method), builder.build());
-        if (report.hasErrors()) {
+
+        // create report if error of DEBUG logging
+        if (report.hasErrors() || LOG.isDebugEnabled()) {
             String msg;
             if (accept != null && accept.contains("application/json")) {
                 msg = JsonValidationReportFormat.getInstance().apply(report);
             } else {
                 msg = SimpleValidationReportFormat.getInstance().apply(report);
             }
-            return new ValidationError(400, msg);
+            LOG.debug("Client Request Validation: {}", msg);
+            if (report.hasErrors()) {
+                return new ValidationError(500, msg);
+            }
         }
 
         return null;
diff --git 
a/components/camel-openapi-validator/src/test/java/org/apache/camel/component/rest/openapi/validator/client/OpenApiRestClientRequestValidatorTest.java
 
b/components/camel-openapi-validator/src/test/java/org/apache/camel/component/rest/openapi/validator/client/OpenApiRestClientRequestValidatorTest.java
index eb1764b6eaa..af088df8d2c 100644
--- 
a/components/camel-openapi-validator/src/test/java/org/apache/camel/component/rest/openapi/validator/client/OpenApiRestClientRequestValidatorTest.java
+++ 
b/components/camel-openapi-validator/src/test/java/org/apache/camel/component/rest/openapi/validator/client/OpenApiRestClientRequestValidatorTest.java
@@ -17,6 +17,7 @@
 package org.apache.camel.component.rest.openapi.validator.client;
 
 import java.io.IOException;
+import java.util.Map;
 
 import io.swagger.v3.oas.models.OpenAPI;
 import io.swagger.v3.parser.OpenAPIV3Parser;
@@ -68,6 +69,14 @@ public class OpenApiRestClientRequestValidatorTest extends 
ExchangeTestSupport {
         error = validator.validate(exchange, new 
RestClientRequestValidator.ValidationContext(
                 "application/json", "application/json", true, null, null, 
null, null));
         Assertions.assertNull(error);
+
+        // turn off required validator
+        exchange.getMessage().setBody("{ \"name\": \"tiger\" }");
+        
context.getRestConfiguration().setValidationLevels(Map.of("validation.request.body.schema.required",
 "INFO"));
+        error = validator.validate(exchange, new 
RestClientRequestValidator.ValidationContext(
+                "application/json", "application/json", true, null, null, 
null, null));
+        Assertions.assertNull(error);
+        context.getRestConfiguration().setValidationLevels(null);
     }
 
     @Test
diff --git 
a/components/camel-openapi-validator/src/test/resources/log4j2.properties 
b/components/camel-openapi-validator/src/test/resources/log4j2.properties
index 2ea0f59401f..9ec0547c84a 100644
--- a/components/camel-openapi-validator/src/test/resources/log4j2.properties
+++ b/components/camel-openapi-validator/src/test/resources/log4j2.properties
@@ -26,3 +26,7 @@ appender.out.layout.type = PatternLayout
 appender.out.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
 rootLogger.level = INFO
 rootLogger.appenderRef.file.ref = file
+
+logger.validator.name=org.apache.camel.component.rest.openapi.validator.client
+logger.validator.level=DEBUG
+
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 6b4c6844919..413e9538f34 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
@@ -79,6 +79,7 @@ public class RestConfiguration {
     private Map<String, Object> dataFormatProperties;
     private Map<String, Object> apiProperties;
     private Map<String, String> corsHeaders;
+    private Map<String, String> validationLevels;
 
     /**
      * Gets the name of the Camel component to use as the REST consumer
@@ -637,4 +638,20 @@ public class RestConfiguration {
     public void setCorsHeaders(Map<String, String> corsHeaders) {
         this.corsHeaders = corsHeaders;
     }
+
+    /**
+     * Gets the client request validation levels when using 
camel-openapi-validator.
+     *
+     * @return the validation levels
+     */
+    public Map<String, String> getValidationLevels() {
+        return validationLevels;
+    }
+
+    /**
+     * Sets the client request validation levels when using 
camel-openapi-validator.
+     */
+    public void setValidationLevels(Map<String, String> validationLevels) {
+        this.validationLevels = validationLevels;
+    }
 }
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 0dd2169d743..2ba7f5e7378 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
@@ -77,6 +77,8 @@ public class RestConfigurationConfigurer extends 
org.apache.camel.support.compon
         case "skipBindingOnErrorCode": 
target.setSkipBindingOnErrorCode(property(camelContext, boolean.class, value)); 
return true;
         case "usexforwardheaders":
         case "useXForwardHeaders": 
target.setUseXForwardHeaders(property(camelContext, boolean.class, value)); 
return true;
+        case "validationlevels":
+        case "validationLevels": 
target.setValidationLevels(property(camelContext, java.util.Map.class, value)); 
return true;
         case "xmldataformat":
         case "xmlDataFormat": target.setXmlDataFormat(property(camelContext, 
java.lang.String.class, value)); return true;
         default: return false;
@@ -140,6 +142,8 @@ public class RestConfigurationConfigurer extends 
org.apache.camel.support.compon
         case "skipBindingOnErrorCode": return boolean.class;
         case "usexforwardheaders":
         case "useXForwardHeaders": return boolean.class;
+        case "validationlevels":
+        case "validationLevels": return java.util.Map.class;
         case "xmldataformat":
         case "xmlDataFormat": return java.lang.String.class;
         default: return null;
@@ -204,6 +208,8 @@ public class RestConfigurationConfigurer extends 
org.apache.camel.support.compon
         case "skipBindingOnErrorCode": return 
target.isSkipBindingOnErrorCode();
         case "usexforwardheaders":
         case "useXForwardHeaders": return target.isUseXForwardHeaders();
+        case "validationlevels":
+        case "validationLevels": return target.getValidationLevels();
         case "xmldataformat":
         case "xmlDataFormat": return target.getXmlDataFormat();
         default: return null;
@@ -225,6 +231,8 @@ public class RestConfigurationConfigurer extends 
org.apache.camel.support.compon
         case "dataFormatProperties": return java.lang.Object.class;
         case "endpointproperties":
         case "endpointProperties": return java.lang.Object.class;
+        case "validationlevels":
+        case "validationLevels": return java.lang.String.class;
         default: return null;
         }
     }
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 a1da1650ec6..ad355731a51 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
@@ -41,6 +41,7 @@
     "consumerProperty": { "index": 26, "kind": "element", "displayName": 
"Consumer Property", "group": "consumer (advanced)", "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": 27, "kind": "element", "displayName": 
"Data Format Property", "group": "advanced", "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 
mo [...]
     "apiProperty": { "index": 28, "kind": "element", "displayName": "Api 
Property", "group": "consumer (advanced)", "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": 29, "kind": "element", "displayName": "Cors 
Headers", "group": "consumer (advanced)", "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." }
+    "corsHeaders": { "index": 29, "kind": "element", "displayName": "Cors 
Headers", "group": "consumer (advanced)", "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." },
+    "validationLevels": { "index": 30, "kind": "element", "displayName": 
"Validation Levels", "group": "consumer (advanced)", "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 validation levels when using 
camel-openapi-validator with client request\/response validator." }
   }
 }
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 69b4bd44fd3..7af57ddd270 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
@@ -127,6 +127,9 @@ public class RestConfigurationDefinition {
     @XmlElement(name = "corsHeaders")
     @Metadata(label = "consumer,advanced")
     private List<RestPropertyDefinition> corsHeaders = new ArrayList<>();
+    @XmlElement(name = "validationLevels")
+    @Metadata(label = "consumer,advanced")
+    private List<RestPropertyDefinition> validationLevels = new ArrayList<>();
 
     public String getComponent() {
         return component;
@@ -519,6 +522,17 @@ public class RestConfigurationDefinition {
         this.corsHeaders = corsHeaders;
     }
 
+    public List<RestPropertyDefinition> getValidationLevels() {
+        return validationLevels;
+    }
+
+    /**
+     * Allows to configure custom validation levels when using 
camel-openapi-validator with client request/response validator.
+     */
+    public void setValidationLevels(List<RestPropertyDefinition> 
validationLevels) {
+        this.validationLevels = validationLevels;
+    }
+
     public String getUseXForwardHeaders() {
         return useXForwardHeaders;
     }
@@ -934,6 +948,17 @@ public class RestConfigurationDefinition {
         return this;
     }
 
+    /**
+     * For configuring validation error levels
+     */
+    public RestConfigurationDefinition validationLevelProperty(String key, 
String value) {
+        RestPropertyDefinition prop = new RestPropertyDefinition();
+        prop.setKey(key);
+        prop.setValue(value);
+        getValidationLevels().add(prop);
+        return this;
+    }
+
     /**
      * Shortcut for setting the Access-Control-Allow-Credentials header.
      */
@@ -1103,6 +1128,15 @@ public class RestConfigurationDefinition {
             }
             target.setCorsHeaders(props);
         }
+        if (!validationLevels.isEmpty()) {
+            Map<String, String> props = new HashMap<>();
+            for (RestPropertyDefinition prop : validationLevels) {
+                String key = prop.getKey();
+                String value = CamelContextHelper.parseText(context, 
prop.getValue());
+                props.put(key, value);
+            }
+            target.setValidationLevels(props);
+        }
         return target;
     }
 
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 10a21a902d2..be561905c80 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
@@ -51,6 +51,7 @@ public class RestConfigurationPropertiesConfigurer extends 
org.apache.camel.supp
         map.put("Scheme", java.lang.String.class);
         map.put("SkipBindingOnErrorCode", boolean.class);
         map.put("UseXForwardHeaders", boolean.class);
+        map.put("ValidationLevels", java.util.Map.class);
         map.put("XmlDataFormat", java.lang.String.class);
         ALL_OPTIONS = map;
     }
@@ -113,6 +114,8 @@ public class RestConfigurationPropertiesConfigurer extends 
org.apache.camel.supp
         case "skipBindingOnErrorCode": 
target.setSkipBindingOnErrorCode(property(camelContext, boolean.class, value)); 
return true;
         case "usexforwardheaders":
         case "useXForwardHeaders": 
target.setUseXForwardHeaders(property(camelContext, boolean.class, value)); 
return true;
+        case "validationlevels":
+        case "validationLevels": 
target.setValidationLevels(property(camelContext, java.util.Map.class, value)); 
return true;
         case "xmldataformat":
         case "xmlDataFormat": target.setXmlDataFormat(property(camelContext, 
java.lang.String.class, value)); return true;
         default: return false;
@@ -181,6 +184,8 @@ public class RestConfigurationPropertiesConfigurer extends 
org.apache.camel.supp
         case "skipBindingOnErrorCode": return boolean.class;
         case "usexforwardheaders":
         case "useXForwardHeaders": return boolean.class;
+        case "validationlevels":
+        case "validationLevels": return java.util.Map.class;
         case "xmldataformat":
         case "xmlDataFormat": return java.lang.String.class;
         default: return null;
@@ -245,6 +250,8 @@ public class RestConfigurationPropertiesConfigurer extends 
org.apache.camel.supp
         case "skipBindingOnErrorCode": return 
target.isSkipBindingOnErrorCode();
         case "usexforwardheaders":
         case "useXForwardHeaders": return target.isUseXForwardHeaders();
+        case "validationlevels":
+        case "validationLevels": return target.getValidationLevels();
         case "xmldataformat":
         case "xmlDataFormat": return target.getXmlDataFormat();
         default: return null;
@@ -266,6 +273,8 @@ public class RestConfigurationPropertiesConfigurer extends 
org.apache.camel.supp
         case "dataFormatProperties": return java.lang.Object.class;
         case "endpointproperties":
         case "endpointProperties": return java.lang.Object.class;
+        case "validationlevels":
+        case "validationLevels": return java.lang.String.class;
         default: return null;
         }
     }
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 339f9e360d2..ecd123e7a0b 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
@@ -282,6 +282,7 @@
     { "name": "camel.rest.scheme", "description": "Sets the scheme to use by 
the REST consumer", "sourceType": "org.apache.camel.spi.RestConfiguration", 
"type": "string", "javaType": "java.lang.String" },
     { "name": "camel.rest.skipBindingOnErrorCode", "description": "Whether to 
skip binding output if there is a custom HTTP error code, and instead use the 
response body as-is. This option is default true.", "sourceType": 
"org.apache.camel.spi.RestConfiguration", "type": "boolean", "javaType": 
"boolean", "defaultValue": true },
     { "name": "camel.rest.useXForwardHeaders", "description": "Whether to use 
X-Forward headers to set host etc. for OpenApi. This may be needed in special 
cases involving reverse-proxy and networking going from HTTP to HTTPS etc. Then 
the proxy can send X-Forward headers (X-Forwarded-Proto) that influences the 
host names in the OpenAPI schema that camel-openapi-java generates from Rest 
DSL routes.", "sourceType": "org.apache.camel.spi.RestConfiguration", "type": 
"boolean", "javaType": " [...]
+    { "name": "camel.rest.validationLevels", "description": "Sets the client 
request validation levels when using camel-openapi-validator.", "sourceType": 
"org.apache.camel.spi.RestConfiguration", "type": "object", "javaType": 
"java.util.Map" },
     { "name": "camel.rest.xmlDataFormat", "description": "Sets a custom xml 
data format to 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.", 
"sourceType": "org.apache.camel.spi.RestConfiguration", "type": "string", 
"javaType": "java.lang.String" },
     { "name": "camel.routecontroller.backOffDelay", "description": "Backoff 
delay in millis when restarting a route that failed to startup.", "sourceType": 
"org.apache.camel.main.RouteControllerConfigurationProperties", "type": 
"integer", "javaType": "long", "defaultValue": 2000 },
     { "name": "camel.routecontroller.backOffMaxAttempts", "description": 
"Backoff maximum number of attempts to restart a route that failed to startup. 
When this threshold has been exceeded then the controller will give up 
attempting to restart the route, and the route will remain as stopped.", 
"sourceType": "org.apache.camel.main.RouteControllerConfigurationProperties", 
"type": "integer", "javaType": "long" },
diff --git a/core/camel-main/src/main/docs/main.adoc 
b/core/camel-main/src/main/docs/main.adoc
index 4ebb925893b..dde170b84a0 100644
--- a/core/camel-main/src/main/docs/main.adoc
+++ b/core/camel-main/src/main/docs/main.adoc
@@ -363,7 +363,7 @@ The camel.health supports 8 options, which are listed below.
 
 
 === Camel Rest-DSL configurations
-The camel.rest supports 30 options, which are listed below.
+The camel.rest supports 31 options, which are listed below.
 
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
@@ -397,6 +397,7 @@ The camel.rest supports 30 options, which are listed below.
 | *camel.rest.scheme* | Sets the scheme to use by the REST consumer |  | String
 | *camel.rest.skipBindingOnError{zwsp}Code* | Whether to skip binding output 
if there is a custom HTTP error code, and instead use the response body as-is. 
This option is default true. | true | boolean
 | *camel.rest.useXForwardHeaders* | Whether to use X-Forward headers to set 
host etc. for OpenApi. This may be needed in special cases involving 
reverse-proxy and networking going from HTTP to HTTPS etc. Then the proxy can 
send X-Forward headers (X-Forwarded-Proto) that influences the host names in 
the OpenAPI schema that camel-openapi-java generates from Rest DSL routes. | 
false | boolean
+| *camel.rest.validationLevels* | Sets the client request validation levels 
when using camel-openapi-validator. |  | Map
 | *camel.rest.xmlDataFormat* | Sets a custom xml data format to 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. |  | String
 |===
 
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 11fd5db35c8..3bda60c37b5 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
@@ -47,6 +47,7 @@ public class RestConfigurationProperties extends 
RestConfiguration implements Bo
         setDataFormatProperties(null);
         setApiProperties(null);
         setCorsHeaders(null);
+        setValidationLevels(null);
     }
 
     // getter and setters
@@ -363,4 +364,15 @@ public class RestConfigurationProperties extends 
RestConfiguration implements Bo
         return this;
     }
 
+    /**
+     * Adds a validation error property
+     */
+    public RestConfigurationProperties withValidationLevel(String key, String 
value) {
+        if (getValidationLevels() == null) {
+            setValidationLevels(new HashMap<>());
+        }
+        getValidationLevels().put(key, value);
+        return this;
+    }
+
 }
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 d2b7a68b922..a97693f4c29 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
@@ -1457,6 +1457,7 @@ public class ModelParser extends BaseParser {
                 case "corsHeaders": doAdd(doParseRestPropertyDefinition(), 
def.getCorsHeaders(), def::setCorsHeaders); yield true;
                 case "dataFormatProperty": 
doAdd(doParseRestPropertyDefinition(), def.getDataFormatProperties(), 
def::setDataFormatProperties); yield true;
                 case "endpointProperty": 
doAdd(doParseRestPropertyDefinition(), def.getEndpointProperties(), 
def::setEndpointProperties); yield true;
+                case "validationLevels": 
doAdd(doParseRestPropertyDefinition(), def.getValidationLevels(), 
def::setValidationLevels); yield true;
                 default: yield false;
             }, noValueHandler());
     }
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 fcc91f1db0e..abc7713fb95 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
@@ -3507,6 +3507,7 @@ public class ModelWriter extends BaseWriter {
         doWriteList(null, "consumerProperty", def.getConsumerProperties(), 
this::doWriteRestPropertyDefinition);
         doWriteList(null, "corsHeaders", def.getCorsHeaders(), 
this::doWriteRestPropertyDefinition);
         doWriteList(null, "componentProperty", def.getComponentProperties(), 
this::doWriteRestPropertyDefinition);
+        doWriteList(null, "validationLevels", def.getValidationLevels(), 
this::doWriteRestPropertyDefinition);
         doWriteList(null, "apiProperty", def.getApiProperties(), 
this::doWriteRestPropertyDefinition);
         doWriteList(null, "endpointProperty", def.getEndpointProperties(), 
this::doWriteRestPropertyDefinition);
         doWriteList(null, "dataFormatProperty", def.getDataFormatProperties(), 
this::doWriteRestPropertyDefinition);
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 ba9234a2299..f5654fd238e 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
@@ -3507,6 +3507,7 @@ public class ModelWriter extends BaseWriter {
         doWriteList(null, "consumerProperty", def.getConsumerProperties(), 
this::doWriteRestPropertyDefinition);
         doWriteList(null, "corsHeaders", def.getCorsHeaders(), 
this::doWriteRestPropertyDefinition);
         doWriteList(null, "componentProperty", def.getComponentProperties(), 
this::doWriteRestPropertyDefinition);
+        doWriteList(null, "validationLevels", def.getValidationLevels(), 
this::doWriteRestPropertyDefinition);
         doWriteList(null, "apiProperty", def.getApiProperties(), 
this::doWriteRestPropertyDefinition);
         doWriteList(null, "endpointProperty", def.getEndpointProperties(), 
this::doWriteRestPropertyDefinition);
         doWriteList(null, "dataFormatProperty", def.getDataFormatProperties(), 
this::doWriteRestPropertyDefinition);
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 e581baa526a..39921d7868f 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
@@ -14328,6 +14328,7 @@ public final class ModelDeserializers extends 
YamlDeserializerSupport {
                     @YamlProperty(name = "scheme", type = "string", 
description = "The scheme to use for exposing the REST service. Usually http or 
https is supported. The default value is http", displayName = "Scheme"),
                     @YamlProperty(name = "skipBindingOnErrorCode", type = 
"boolean", 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 will do.", 
displayName = "Skip Binding On Error Code"),
                     @YamlProperty(name = "useXForwardHeaders", type = 
"boolean", description = "Whether to use X-Forward headers to set host etc. for 
OpenApi. This may be needed in special cases involving reverse-proxy and 
networking going from HTTP to HTTPS etc. Then the proxy can send X-Forward 
headers (X-Forwarded-Proto) that influences the host names in the OpenAPI 
schema that camel-openapi-java generates from Rest DSL routes.", displayName = 
"Use XForward Headers"),
+                    @YamlProperty(name = "validationLevels", type = 
"array:org.apache.camel.model.rest.RestPropertyDefinition", description = 
"Allows to configure custom validation levels when using 
camel-openapi-validator with client request/response validator.", displayName = 
"Validation Levels"),
                     @YamlProperty(name = "xmlDataFormat", type = "string", 
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.", displayName = "Xml 
Data Format")
             }
     )
@@ -14489,6 +14490,11 @@ public final class ModelDeserializers extends 
YamlDeserializerSupport {
                     target.setUseXForwardHeaders(val);
                     break;
                 }
+                case "validationLevels": {
+                    
java.util.List<org.apache.camel.model.rest.RestPropertyDefinition> val = 
asFlatList(node, org.apache.camel.model.rest.RestPropertyDefinition.class);
+                    target.setValidationLevels(val);
+                    break;
+                }
                 case "xmlDataFormat": {
                     String val = asText(node);
                     target.setXmlDataFormat(val);
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 2840dfaae15..e466dbb118d 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
@@ -15867,6 +15867,14 @@
             "title" : "Use XForward Headers",
             "description" : "Whether to use X-Forward headers to set host etc. 
for OpenApi. This may be needed in special cases involving reverse-proxy and 
networking going from HTTP to HTTPS etc. Then the proxy can send X-Forward 
headers (X-Forwarded-Proto) that influences the host names in the OpenAPI 
schema that camel-openapi-java generates from Rest DSL routes."
           },
+          "validationLevels" : {
+            "type" : "array",
+            "title" : "Validation Levels",
+            "description" : "Allows to configure custom validation levels when 
using camel-openapi-validator with client request/response validator.",
+            "items" : {
+              "$ref" : 
"#/items/definitions/org.apache.camel.model.rest.RestPropertyDefinition"
+            }
+          },
           "xmlDataFormat" : {
             "type" : "string",
             "title" : "Xml Data Format",


Reply via email to