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 5fd8b363f275 CAMEL-24114: camel-rest-openapi - Request validator also
checks exchange variables and endpoint literal parameters
5fd8b363f275 is described below
commit 5fd8b363f275a506d2b7b2a5fba1ba7f237655ab
Author: Claus Ibsen <[email protected]>
AuthorDate: Thu Jul 16 22:49:25 2026 +0200
CAMEL-24114: camel-rest-openapi - Request validator also checks exchange
variables and endpoint literal parameters
Co-Authored-By: Claude Opus 4.6 <[email protected]>
---
.../rest/openapi/RestOpenApiEndpoint.java | 1 +
.../openapi/validator/DefaultRequestValidator.java | 19 +++++++++--
.../openapi/RestOpenApiRequestValidationTest.java | 39 ++++++++++++++++++++++
3 files changed, 56 insertions(+), 3 deletions(-)
diff --git
a/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/RestOpenApiEndpoint.java
b/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/RestOpenApiEndpoint.java
index 67cf9b92e73c..0abb19e54be0 100644
---
a/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/RestOpenApiEndpoint.java
+++
b/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/RestOpenApiEndpoint.java
@@ -895,6 +895,7 @@ public final class RestOpenApiEndpoint extends
DefaultEndpoint {
OpenAPI openAPI, Operation operation, String method, String
uriTemplate) {
DefaultRequestValidator answer = new DefaultRequestValidator();
answer.setOperation(new RestOpenApiOperation(operation, method,
uriTemplate));
+ answer.setEndpointParameters(parameters);
return answer;
}
diff --git
a/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/validator/DefaultRequestValidator.java
b/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/validator/DefaultRequestValidator.java
index af20dc487bf4..112b951da96d 100644
---
a/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/validator/DefaultRequestValidator.java
+++
b/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/validator/DefaultRequestValidator.java
@@ -18,6 +18,7 @@ package org.apache.camel.component.rest.openapi.validator;
import java.util.Collections;
import java.util.LinkedHashSet;
+import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
@@ -34,12 +35,17 @@ import static
org.apache.camel.support.http.RestUtil.isValidOrAcceptedContentTyp
public class DefaultRequestValidator implements RequestValidator {
private RestOpenApiOperation operation;
+ private Map<String, Object> endpointParameters = Collections.emptyMap();
@Override
public void setOperation(RestOpenApiOperation operation) {
this.operation = operation;
}
+ public void setEndpointParameters(Map<String, Object> endpointParameters) {
+ this.endpointParameters = endpointParameters != null ?
endpointParameters : Collections.emptyMap();
+ }
+
@Override
public RestOpenApiOperation getOperation() {
return operation;
@@ -100,9 +106,16 @@ public class DefaultRequestValidator implements
RequestValidator {
.stream()
.filter(parameter -> Objects.nonNull(parameter.getRequired())
&& parameter.getRequired())
.forEach(parameter -> {
- Object header = message.getHeader(parameter.getName());
- if (ObjectHelper.isEmpty(header)) {
- validationErrors.add("Query parameter '" +
parameter.getName() + "' is required but none found.");
+ String name = parameter.getName();
+ Object value = message.getHeader(name);
+ if (ObjectHelper.isEmpty(value)) {
+ value = exchange.getVariable(name);
+ }
+ if (ObjectHelper.isEmpty(value)) {
+ value = endpointParameters.get(name);
+ }
+ if (ObjectHelper.isEmpty(value)) {
+ validationErrors.add("Query parameter '" + name + "'
is required but none found.");
}
});
diff --git
a/components/camel-rest-openapi/src/test/java/org/apache/camel/component/rest/openapi/RestOpenApiRequestValidationTest.java
b/components/camel-rest-openapi/src/test/java/org/apache/camel/component/rest/openapi/RestOpenApiRequestValidationTest.java
index 158ecea5c4c8..3a4a2b951c79 100644
---
a/components/camel-rest-openapi/src/test/java/org/apache/camel/component/rest/openapi/RestOpenApiRequestValidationTest.java
+++
b/components/camel-rest-openapi/src/test/java/org/apache/camel/component/rest/openapi/RestOpenApiRequestValidationTest.java
@@ -307,6 +307,37 @@ public class RestOpenApiRequestValidationTest extends
CamelTestSupport {
assertFalse(pets.isEmpty());
}
+ @ParameterizedTest
+ @MethodSource("petStoreVersions")
+ @SuppressWarnings("unchecked")
+ void requestValidationWithRequiredQueryParameterFromEndpointUri(String
petStoreVersion) {
+ Map<String, Object> headers = Map.of("petStoreVersion",
petStoreVersion);
+ List<Pet> pets
+ =
template.requestBodyAndHeaders("direct:validateQueryParamsFromEndpoint", null,
headers, List.class);
+ assertFalse(pets.isEmpty());
+ }
+
+ @ParameterizedTest
+ @MethodSource("petStoreVersions")
+ @SuppressWarnings("unchecked")
+ void requestValidationWithRequiredQueryParameterFromVariable(String
petStoreVersion) {
+ Exchange exchange =
template.request("direct:validateQueryParamsFromVariable", new Processor() {
+ @Override
+ public void process(Exchange exchange) throws Exception {
+ exchange.getMessage().setHeader("petStoreVersion",
petStoreVersion);
+ exchange.setVariable("status", "available");
+ }
+ });
+
+ Exception exception = exchange.getException();
+ if (exception != null) {
+ throw new AssertionError("Unexpected validation failure",
exception);
+ }
+ List<Pet> pets = exchange.getMessage().getBody(List.class);
+ assertNotNull(pets);
+ assertFalse(pets.isEmpty());
+ }
+
@ParameterizedTest
@ValueSource(strings = { "petStoreV3" })
void requestValidationWithBinaryBody(String petStoreVersion) throws
IOException {
@@ -460,6 +491,14 @@ public class RestOpenApiRequestValidationTest extends
CamelTestSupport {
.toD("${header.petStoreVersion}:findPetsByStatus?requestValidationEnabled=true")
.unmarshal(jacksonDataFormat);
+ from("direct:validateQueryParamsFromEndpoint")
+
.toD("${header.petStoreVersion}:findPetsByStatus?requestValidationEnabled=true&status=available")
+ .unmarshal(jacksonDataFormat);
+
+ from("direct:validateQueryParamsFromVariable")
+
.toD("${header.petStoreVersion}:findPetsByStatus?requestValidationEnabled=true")
+ .unmarshal(jacksonDataFormat);
+
from("direct:binaryContent")
.toD("${header.petStoreVersion}:uploadFile?requestValidationEnabled=true&produces=application/octet-stream")
.unmarshal(jacksonDataFormat);