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",