This is an automated email from the ASF dual-hosted git repository. jamesnetherton pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
The following commit(s) were added to refs/heads/main by this push: new a9ad59abae Verify expected json-validator error messages a9ad59abae is described below commit a9ad59abae244f347e552cdaceb2682a617f436d Author: James Netherton <jamesnether...@gmail.com> AuthorDate: Thu Mar 6 09:13:31 2025 +0000 Verify expected json-validator error messages --- extensions/json-validator/deployment/pom.xml | 4 ++ .../deployment/JsonValidatorProcessor.java | 13 +++-- extensions/json-validator/runtime/pom.xml | 4 ++ integration-tests/json-validator/pom.xml | 4 ++ .../json/validator/it/JsonValidatorResource.java | 68 +++++++++++++++++----- .../json/validator/it/JsonValidatorRoute.java | 10 ++-- .../json-validator/src/main/resources/schema.json | 3 +- .../json/validator/it/JsonValidatorTest.java | 51 ++++++++++++---- 8 files changed, 122 insertions(+), 35 deletions(-) diff --git a/extensions/json-validator/deployment/pom.xml b/extensions/json-validator/deployment/pom.xml index 2c85fcc9c9..19f0c45304 100644 --- a/extensions/json-validator/deployment/pom.xml +++ b/extensions/json-validator/deployment/pom.xml @@ -30,6 +30,10 @@ <name>Camel Quarkus :: JSON Schema Validator :: Deployment</name> <dependencies> + <dependency> + <groupId>io.quarkus</groupId> + <artifactId>quarkus-jackson-deployment</artifactId> + </dependency> <dependency> <groupId>org.apache.camel.quarkus</groupId> <artifactId>camel-quarkus-core-deployment</artifactId> diff --git a/extensions/json-validator/deployment/src/main/java/org/apache/camel/quarkus/component/json/validator/deployment/JsonValidatorProcessor.java b/extensions/json-validator/deployment/src/main/java/org/apache/camel/quarkus/component/json/validator/deployment/JsonValidatorProcessor.java index 6e218d05d4..eb376766a5 100644 --- a/extensions/json-validator/deployment/src/main/java/org/apache/camel/quarkus/component/json/validator/deployment/JsonValidatorProcessor.java +++ b/extensions/json-validator/deployment/src/main/java/org/apache/camel/quarkus/component/json/validator/deployment/JsonValidatorProcessor.java @@ -22,6 +22,7 @@ import io.quarkus.deployment.builditem.CombinedIndexBuildItem; import io.quarkus.deployment.builditem.FeatureBuildItem; import io.quarkus.deployment.builditem.IndexDependencyBuildItem; import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; +import org.jboss.jandex.ClassInfo; import org.jboss.jandex.DotName; class JsonValidatorProcessor { @@ -44,10 +45,14 @@ class JsonValidatorProcessor { * So, let's register all the known JsonValidator implementations for reflective access in native mode. */ @BuildStep - void registerReflectiveClasses(CombinedIndexBuildItem combinedIndex, + void registerReflectiveClasses( + CombinedIndexBuildItem combinedIndex, BuildProducer<ReflectiveClassBuildItem> reflectiveProducer) { - combinedIndex.getIndex().getAllKnownImplementors(VALIDATOR_INTERFACE).stream() - .forEach(c -> reflectiveProducer - .produce(ReflectiveClassBuildItem.builder(c.name().toString()).build())); + combinedIndex.getIndex() + .getAllKnownImplementors(VALIDATOR_INTERFACE) + .stream() + .map(ClassInfo::name) + .map(DotName::toString) + .forEach(c -> reflectiveProducer.produce(ReflectiveClassBuildItem.builder(c).build())); } } diff --git a/extensions/json-validator/runtime/pom.xml b/extensions/json-validator/runtime/pom.xml index 94d6369fa0..b8d374e309 100644 --- a/extensions/json-validator/runtime/pom.xml +++ b/extensions/json-validator/runtime/pom.xml @@ -36,6 +36,10 @@ </properties> <dependencies> + <dependency> + <groupId>io.quarkus</groupId> + <artifactId>quarkus-jackson</artifactId> + </dependency> <dependency> <groupId>org.apache.camel.quarkus</groupId> <artifactId>camel-quarkus-core</artifactId> diff --git a/integration-tests/json-validator/pom.xml b/integration-tests/json-validator/pom.xml index a7144d347c..7938d27cef 100644 --- a/integration-tests/json-validator/pom.xml +++ b/integration-tests/json-validator/pom.xml @@ -43,6 +43,10 @@ <groupId>io.quarkus</groupId> <artifactId>quarkus-resteasy</artifactId> </dependency> + <dependency> + <groupId>io.quarkus</groupId> + <artifactId>quarkus-resteasy-jackson</artifactId> + </dependency> <!-- test dependencies --> <dependency> diff --git a/integration-tests/json-validator/src/main/java/org/apache/camel/quarkus/component/json/validator/it/JsonValidatorResource.java b/integration-tests/json-validator/src/main/java/org/apache/camel/quarkus/component/json/validator/it/JsonValidatorResource.java index 6338ef4d83..aa66bcf47b 100644 --- a/integration-tests/json-validator/src/main/java/org/apache/camel/quarkus/component/json/validator/it/JsonValidatorResource.java +++ b/integration-tests/json-validator/src/main/java/org/apache/camel/quarkus/component/json/validator/it/JsonValidatorResource.java @@ -18,7 +18,9 @@ package org.apache.camel.quarkus.component.json.validator.it; import java.io.ByteArrayInputStream; import java.nio.charset.StandardCharsets; +import java.util.List; +import com.networknt.schema.ValidationMessage; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.ws.rs.Consumes; @@ -26,7 +28,9 @@ import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.MediaType; +import org.apache.camel.CamelExecutionException; import org.apache.camel.ProducerTemplate; +import org.apache.camel.component.jsonvalidator.JsonValidationException; import org.jboss.logging.Logger; @Path("/json-validator") @@ -41,29 +45,65 @@ public class JsonValidatorResource { @Path("/validate") @GET @Consumes(MediaType.TEXT_PLAIN) - @Produces(MediaType.TEXT_PLAIN) - public String validate(String json) { - LOG.infof("Calling validate with: %s", json); - return producerTemplate.requestBody("direct:validate-json", json, String.class); + @Produces(MediaType.APPLICATION_JSON) + public List<String> validate(String json) { + try { + LOG.infof("Calling validate with: %s", json); + String result = producerTemplate.requestBody("direct:validate-json", json, String.class); + return List.of(result); + } catch (CamelExecutionException e) { + if (e.getCause() instanceof JsonValidationException jve) { + return jve.getErrors() + .stream() + .map(ValidationMessage::getError) + .toList(); + } else { + throw e; + } + } } @Path("/validate-as-stream") @GET @Consumes(MediaType.TEXT_PLAIN) - @Produces(MediaType.TEXT_PLAIN) - public String validateAsStream(String json) { - LOG.infof("Calling validateAsStream with: %s", json); - ByteArrayInputStream bais = new ByteArrayInputStream(json.getBytes(StandardCharsets.UTF_8)); - return producerTemplate.requestBody("direct:validate-json", bais, String.class) + "-as-stream"; + @Produces(MediaType.APPLICATION_JSON) + public List<String> validateAsStream(String json) { + try { + LOG.infof("Calling validateAsStream with: %s", json); + ByteArrayInputStream bais = new ByteArrayInputStream(json.getBytes(StandardCharsets.UTF_8)); + String result = producerTemplate.requestBody("direct:validate-json", bais, String.class) + "-as-stream"; + return List.of(result); + } catch (CamelExecutionException e) { + if (e.getCause() instanceof JsonValidationException jve) { + return jve.getErrors() + .stream() + .map(ValidationMessage::getError) + .toList(); + } else { + throw e; + } + } } @Path("/validate-from-header") @GET @Consumes(MediaType.TEXT_PLAIN) - @Produces(MediaType.TEXT_PLAIN) - public String validateFromHeader(String json) { - LOG.infof("Calling validateFromHeader with: %s", json); - return producerTemplate.requestBodyAndHeader("direct:validate-json-from-header", null, "headerToValidate", - json, String.class); + @Produces(MediaType.APPLICATION_JSON) + public List<String> validateFromHeader(String json) { + try { + LOG.infof("Calling validateFromHeader with: %s", json); + String result = producerTemplate.requestBodyAndHeader("direct:validate-json-from-header", null, "headerToValidate", + json, String.class); + return List.of(result); + } catch (CamelExecutionException e) { + if (e.getCause() instanceof JsonValidationException jve) { + return jve.getErrors() + .stream() + .map(ValidationMessage::getError) + .toList(); + } else { + throw e; + } + } } } diff --git a/integration-tests/json-validator/src/main/java/org/apache/camel/quarkus/component/json/validator/it/JsonValidatorRoute.java b/integration-tests/json-validator/src/main/java/org/apache/camel/quarkus/component/json/validator/it/JsonValidatorRoute.java index dd8844897f..1824c4fc69 100644 --- a/integration-tests/json-validator/src/main/java/org/apache/camel/quarkus/component/json/validator/it/JsonValidatorRoute.java +++ b/integration-tests/json-validator/src/main/java/org/apache/camel/quarkus/component/json/validator/it/JsonValidatorRoute.java @@ -17,7 +17,6 @@ package org.apache.camel.quarkus.component.json.validator.it; import jakarta.enterprise.context.ApplicationScoped; -import org.apache.camel.ValidationException; import org.apache.camel.builder.RouteBuilder; @ApplicationScoped @@ -25,11 +24,10 @@ public class JsonValidatorRoute extends RouteBuilder { @Override public void configure() { - from("direct:validate-json").doTry().to("json-validator:schema.json").setBody(constant("valid")) - .doCatch(ValidationException.class).setBody(constant("invalid")).end(); + from("direct:validate-json") + .to("json-validator:schema.json").setBody(constant("valid")); - from("direct:validate-json-from-header").doTry().to("json-validator:schema.json?headerName=headerToValidate") - .setBody(constant("valid-header")) - .doCatch(ValidationException.class).setBody(constant("invalid-header")).end(); + from("direct:validate-json-from-header") + .to("json-validator:schema.json?headerName=headerToValidate").setBody(constant("valid-header")); } } diff --git a/integration-tests/json-validator/src/main/resources/schema.json b/integration-tests/json-validator/src/main/resources/schema.json index f5d493f4a8..8f5da2252a 100644 --- a/integration-tests/json-validator/src/main/resources/schema.json +++ b/integration-tests/json-validator/src/main/resources/schema.json @@ -25,6 +25,7 @@ "name", "id", "price" - ], + ], + "additionalProperties": false, "type": "object" } \ No newline at end of file diff --git a/integration-tests/json-validator/src/test/java/org/apache/camel/quarkus/component/json/validator/it/JsonValidatorTest.java b/integration-tests/json-validator/src/test/java/org/apache/camel/quarkus/component/json/validator/it/JsonValidatorTest.java index 9512549799..58e371602a 100644 --- a/integration-tests/json-validator/src/test/java/org/apache/camel/quarkus/component/json/validator/it/JsonValidatorTest.java +++ b/integration-tests/json-validator/src/test/java/org/apache/camel/quarkus/component/json/validator/it/JsonValidatorTest.java @@ -20,46 +20,77 @@ import io.quarkus.test.junit.QuarkusTest; import org.junit.jupiter.api.Test; import static io.restassured.RestAssured.given; +import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; @QuarkusTest class JsonValidatorTest { - @Test public void validJsonShouldBeValidated() { final String validJson = "{ \"name\": \"John Doe\", \"id\": 1, \"price\": 12.5 }"; - given().body(validJson).get("/json-validator/validate").then().statusCode(200).body(is("valid")); + given() + .body(validJson) + .get("/json-validator/validate") + .then() + .statusCode(200) + .body("[0]", is("valid")); } @Test public void invalidJsonShouldNotBeValidated() { - final String invalidJson = "{ \"name\": \"John Doe\", \"id\": \"AA1\", \"price\": 12.5 }"; - given().body(invalidJson).get("/json-validator/validate").then().statusCode(200).body(is("invalid")); + final String invalidJson = "{ \"name\": \"John Doe\", \"id\": \"AA1\", \"unknown\": \"not in schema\" }"; + given() + .body(invalidJson) + .get("/json-validator/validate") + .then() + .statusCode(200) + .body( + "[0]", is("string found, integer expected"), + "[1]", is("required property 'price' not found"), + "[2]", containsString("property 'unknown' is not defined in the schema")); } @Test public void validJsonFromHeaderShouldBeValidated() { final String validJson = "{ \"name\": \"John Doe\", \"id\": 1, \"price\": 12.5 }"; - given().body(validJson).get("/json-validator/validate-from-header").then().statusCode(200).body(is("valid-header")); + given() + .body(validJson) + .get("/json-validator/validate-from-header") + .then() + .statusCode(200) + .body("[0]", is("valid-header")); } @Test public void invalidJsonFromHeaderShouldNotBeValidated() { final String invalidJson = "{ \"name\": \"John Doe\", \"id\": \"AA1\", \"price\": 12.5 }"; - given().body(invalidJson).get("/json-validator/validate-from-header").then().statusCode(200).body(is("invalid-header")); + given() + .body(invalidJson) + .get("/json-validator/validate-from-header") + .then() + .statusCode(200) + .body("[0]", is("string found, integer expected")); } @Test public void validJsonAsStreamShouldBeValidated() { final String validJson = "{ \"name\": \"John Doe\", \"id\": 1, \"price\": 12.5 }"; - given().body(validJson).get("/json-validator/validate-as-stream").then().statusCode(200).body(is("valid-as-stream")); + given() + .body(validJson) + .get("/json-validator/validate-as-stream") + .then() + .statusCode(200) + .body("[0]", is("valid-as-stream")); } @Test public void invalidJsonAsStreamShouldNotBeValidated() { final String invalidJson = "{ \"name\": \"John Doe\", \"id\": \"AA1\", \"price\": 12.5 }"; - given().body(invalidJson).get("/json-validator/validate-as-stream").then().statusCode(200) - .body(is("invalid-as-stream")); + given() + .body(invalidJson) + .get("/json-validator/validate-as-stream") + .then() + .statusCode(200) + .body("[0]", is("string found, integer expected")); } - }