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

davsclaus pushed a commit to branch fix/CAMEL-24114
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 70370ac67210184674b1457c27d403d539c7b806
Author: Claus Ibsen <[email protected]>
AuthorDate: Thu Jul 16 17:03:52 2026 +0200

    CAMEL-24114: camel-rest-openapi - Request validator also checks exchange 
variables and endpoint literal parameters for required query parameters
    
    Signed-off-by: Claus Ibsen <[email protected]>
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
    Signed-off-by: Claus Ibsen <[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 761ca925126c..47abaac46f37 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
@@ -864,6 +864,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);

Reply via email to