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 2b249516284 CAMEL-22117: Include query params and headers in validation context. (#18233) 2b249516284 is described below commit 2b249516284e888a33d2ba80be09098867040e3d Author: Björn Beskow <bbes...@gmail.com> AuthorDate: Sat May 31 15:08:23 2025 +0200 CAMEL-22117: Include query params and headers in validation context. (#18233) * CAMEL-22117: Include query params and headers in validation context. * Header prefix check should be case insensitive. --------- Co-authored-by: Bjorn Beskow <b...@callistaenterprise.se> --- .../client/OpenApiRestClientRequestValidator.java | 22 ++++++++ .../OpenApiRestClientRequestValidatorTest.java | 64 ++++++++++++++++++++-- .../src/test/resources/petstore-v3.json | 6 +- 3 files changed, 84 insertions(+), 8 deletions(-) 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 1ab3d95fa4d..76382cbe283 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 @@ -54,6 +54,25 @@ public class OpenApiRestClientRequestValidator implements RestClientRequestValid if (body != null) { builder.withBody(body); } + // Use all non-Camel headers + for (String header : exchange.getMessage().getHeaders().keySet()) { + if (!startsWithIgnoreCase(header, "Camel")) { + builder.withHeader(header, exchange.getMessage().getHeader(header, String.class)); + } + } + // Use query parameters, if present + String query = exchange.getMessage().getHeader(Exchange.HTTP_QUERY, String.class); + if (query != null) { + String[] params = query.split("&"); + for (String param : params) { + String[] keyValue = param.split("="); + if (keyValue.length == 2) { + builder.withQueryParam(keyValue[0], keyValue[1]); + } else if (keyValue.length == 1) { + builder.withQueryParam(keyValue[0], ""); + } + } + } OpenApiInteractionValidator validator = OpenApiInteractionValidator.createFor(openAPI).build(); ValidationReport report = validator.validateRequest(builder.build()); @@ -69,4 +88,7 @@ public class OpenApiRestClientRequestValidator implements RestClientRequestValid return null; } + boolean startsWithIgnoreCase(String s, String prefix) { + return s.regionMatches(true, 0, prefix, 0, prefix.length()); + } } 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 4a70e0b2649..d1d88a9238c 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 @@ -16,6 +16,8 @@ */ package org.apache.camel.component.rest.openapi.validator.client; +import java.io.IOException; + import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.parser.OpenAPIV3Parser; import io.swagger.v3.parser.core.models.SwaggerParseResult; @@ -24,17 +26,25 @@ import org.apache.camel.spi.RestClientRequestValidator; import org.apache.camel.test.junit5.ExchangeTestSupport; import org.apache.camel.util.IOHelper; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; public class OpenApiRestClientRequestValidatorTest extends ExchangeTestSupport { - @Test - public void testValidator() throws Exception { + static OpenAPI openAPI; + static OpenApiRestClientRequestValidator validator; + + @BeforeAll + static void setup() throws IOException { String data = IOHelper.loadText(OpenApiRestClientRequestValidatorTest.class.getResourceAsStream("/petstore-v3.json")); OpenAPIV3Parser parser = new OpenAPIV3Parser(); SwaggerParseResult out = parser.readContents(data); - OpenAPI openAPI = out.getOpenAPI(); + openAPI = out.getOpenAPI(); + validator = new OpenApiRestClientRequestValidator(); + } + @Test + public void testValidateBody() { exchange.setProperty(Exchange.REST_OPENAPI, openAPI); exchange.setProperty(Exchange.CONTENT_TYPE, "application/json"); exchange.getMessage().setHeader(Exchange.HTTP_METHOD, "PUT"); @@ -42,8 +52,6 @@ public class OpenApiRestClientRequestValidatorTest extends ExchangeTestSupport { exchange.getMessage().setHeader("Accept", "application/json"); exchange.getMessage().setBody(""); - OpenApiRestClientRequestValidator validator = new OpenApiRestClientRequestValidator(); - RestClientRequestValidator.ValidationError error = validator.validate(exchange, new RestClientRequestValidator.ValidationContext( "application/json", "application/json", true, null, null, null, null)); @@ -57,4 +65,50 @@ public class OpenApiRestClientRequestValidatorTest extends ExchangeTestSupport { "application/json", "application/json", true, null, null, null, null)); Assertions.assertNull(error); } + + @Test + public void testValidateQueryParam() { + exchange.setProperty(Exchange.REST_OPENAPI, openAPI); + exchange.setProperty(Exchange.CONTENT_TYPE, "application/json"); + exchange.getMessage().setHeader(Exchange.HTTP_METHOD, "GET"); + exchange.getMessage().setHeader(Exchange.HTTP_PATH, "pet/findByStatus"); + exchange.getMessage().setHeader("Accept", "application/json"); + exchange.getMessage().setBody(""); + + RestClientRequestValidator.ValidationError error + = validator.validate(exchange, new RestClientRequestValidator.ValidationContext( + "application/json", "application/json", true, null, null, null, null)); + + Assertions.assertNotNull(error); + Assertions.assertTrue(error.body().contains("Query parameter 'status' is required")); + + exchange.getMessage().setHeader(Exchange.HTTP_QUERY, "status=available"); + + error = validator.validate(exchange, new RestClientRequestValidator.ValidationContext( + "application/json", "application/json", true, null, null, null, null)); + Assertions.assertNull(error); + } + + @Test + public void testValidateHeader() { + exchange.setProperty(Exchange.REST_OPENAPI, openAPI); + exchange.setProperty(Exchange.CONTENT_TYPE, "application/json"); + exchange.getMessage().setHeader(Exchange.HTTP_METHOD, "GET"); + exchange.getMessage().setHeader(Exchange.HTTP_PATH, "pet/findByTags"); + exchange.getMessage().setHeader("Accept", "application/json"); + exchange.getMessage().setBody(""); + + RestClientRequestValidator.ValidationError error + = validator.validate(exchange, new RestClientRequestValidator.ValidationContext( + "application/json", "application/json", true, null, null, null, null)); + + Assertions.assertNotNull(error); + Assertions.assertTrue(error.body().contains("Header parameter 'tags' is required")); + + exchange.getMessage().setHeader("tags", "dog"); + + error = validator.validate(exchange, new RestClientRequestValidator.ValidationContext( + "application/json", "application/json", true, null, null, null, null)); + Assertions.assertNull(error); + } } diff --git a/components/camel-openapi-validator/src/test/resources/petstore-v3.json b/components/camel-openapi-validator/src/test/resources/petstore-v3.json index 01732bb6fd1..53d445fd579 100644 --- a/components/camel-openapi-validator/src/test/resources/petstore-v3.json +++ b/components/camel-openapi-validator/src/test/resources/petstore-v3.json @@ -180,7 +180,7 @@ "name": "status", "in": "query", "description": "Status values that need to be considered for filter", - "required": false, + "required": true, "explode": true, "schema": { "type": "string", @@ -240,9 +240,9 @@ "parameters": [ { "name": "tags", - "in": "query", + "in": "header", "description": "Tags to filter by", - "required": false, + "required": true, "explode": true, "schema": { "type": "array",