From e3df33e0371480fab74c1009dae1137565f2f5a7 Mon Sep 17 00:00:00 2001 From: JiriOndrusek Date: Wed, 23 Feb 2022 12:01:27 +0100 Subject: [PATCH] Improve camel-quarkus-bean-validator test coverage #3567 --- .../reference/extensions/bean-validator.adoc | 25 +++++++++ .../runtime/src/main/doc/usage.adoc | 21 +++++++ .../validator/it/BeanValidatorResource.java | 34 ++++++++++-- .../bean/validator/it/BeanValidatorRoute.java | 4 ++ .../it/ValidatinFactoryCustomizer.java | 45 +++++++++++++++ .../bean/validator/it/model/Car.java | 34 ++---------- .../it/model/CarWithAnnotations.java | 55 +++++++++++++++++++ .../it/model/CarWithoutAnnotations.java | 50 +++++++++++++++++ .../validator/it/model/OptionalChecks.java | 23 ++++++++ .../main/resources/META-INF/validation.xml | 28 ++++++++++ .../src/main/resources/constraints-car.xml | 42 ++++++++++++++ .../bean/validator/it/BeanValidatorTest.java | 13 ++++- 12 files changed, 338 insertions(+), 36 deletions(-) create mode 100644 extensions/bean-validator/runtime/src/main/doc/usage.adoc create mode 100644 integration-tests/bean-validator/src/main/java/org/apache/camel/quarkus/component/bean/validator/it/ValidatinFactoryCustomizer.java create mode 100644 integration-tests/bean-validator/src/main/java/org/apache/camel/quarkus/component/bean/validator/it/model/CarWithAnnotations.java create mode 100644 integration-tests/bean-validator/src/main/java/org/apache/camel/quarkus/component/bean/validator/it/model/CarWithoutAnnotations.java create mode 100644 integration-tests/bean-validator/src/main/java/org/apache/camel/quarkus/component/bean/validator/it/model/OptionalChecks.java create mode 100644 integration-tests/bean-validator/src/main/resources/META-INF/validation.xml create mode 100644 integration-tests/bean-validator/src/main/resources/constraints-car.xml diff --git a/docs/modules/ROOT/pages/reference/extensions/bean-validator.adoc b/docs/modules/ROOT/pages/reference/extensions/bean-validator.adoc index c983099aba23..d43647fc57cb 100644 --- a/docs/modules/ROOT/pages/reference/extensions/bean-validator.adoc +++ b/docs/modules/ROOT/pages/reference/extensions/bean-validator.adoc @@ -38,3 +38,28 @@ Or add the coordinates to your existing project: ---- Check the xref:user-guide/index.adoc[User guide] for more information about writing Camel Quarkus applications. + +== Usage + +=== Configuring the ValidatorFactory + +Implementation of this extension leverages https://quarkus.io/guides/validation[Quarkus extension]. + +Therefore it is not possible to configure ValidatorFactory by Camel's properties ('constraintValidatorFactory`, `messageInterpolator`, `traversableResolver`, `validationProviderResolver` and `validatorFactory`). + +You can configure ValidatorFactory by creation of beans which will be injected into the default validationFactory (created by Quarkus). +See https://quarkus.io/guides/validation#hibernate-validator-extension-and-cdi[documentation] for more information. + +=== Custom validation groups in native mode + +For native mode, it is necessary to register definitions of custom validation groups for reflection. +To do this, annotate interface definition with `@RegisterForReflection`. + +Example: +[source,java] +---- +@RegisterForReflection +public interface OptionalChecks { +} +---- + diff --git a/extensions/bean-validator/runtime/src/main/doc/usage.adoc b/extensions/bean-validator/runtime/src/main/doc/usage.adoc new file mode 100644 index 000000000000..af8aed7fc733 --- /dev/null +++ b/extensions/bean-validator/runtime/src/main/doc/usage.adoc @@ -0,0 +1,21 @@ +=== Configuring the ValidatorFactory + +Implementation of this extension leverages https://quarkus.io/guides/validation[Quarkus extension]. + +Therefore it is not possible to configure ValidatorFactory by Camel's properties ('constraintValidatorFactory`, `messageInterpolator`, `traversableResolver`, `validationProviderResolver` and `validatorFactory`). + +You can configure ValidatorFactory by creation of beans which will be injected into the default validationFactory (created by Quarkus). +See https://quarkus.io/guides/validation#hibernate-validator-extension-and-cdi[documentation] for more information. + +=== Custom validation groups in native mode + +For native mode, it is necessary to register definitions of custom validation groups for reflection. +To do this, annotate interface definition with `@RegisterForReflection`. + +Example: +[source,java] +---- +@RegisterForReflection +public interface OptionalChecks { +} +---- diff --git a/integration-tests/bean-validator/src/main/java/org/apache/camel/quarkus/component/bean/validator/it/BeanValidatorResource.java b/integration-tests/bean-validator/src/main/java/org/apache/camel/quarkus/component/bean/validator/it/BeanValidatorResource.java index 5bf17e0fb8c1..68590ee79595 100644 --- a/integration-tests/bean-validator/src/main/java/org/apache/camel/quarkus/component/bean/validator/it/BeanValidatorResource.java +++ b/integration-tests/bean-validator/src/main/java/org/apache/camel/quarkus/component/bean/validator/it/BeanValidatorResource.java @@ -28,6 +28,7 @@ import org.apache.camel.Exchange; import org.apache.camel.ProducerTemplate; import org.apache.camel.quarkus.component.bean.validator.it.model.Car; +import org.apache.camel.quarkus.component.bean.validator.it.model.CarWithAnnotations; import org.jboss.logging.Logger; @Path("/bean-validator") @@ -39,13 +40,36 @@ public class BeanValidatorResource { @Inject ProducerTemplate producerTemplate; - @Path("/get/{manufactor}/{plate}") + @Inject + ValidatinFactoryCustomizer.MyMessageInterpolator messageInterpolator; + + @Path("/get/xml/{manufactor}/{plate}") @GET @Produces(MediaType.TEXT_PLAIN) - public Response get(@PathParam("manufactor") String manufactor, @PathParam("plate") String plate) throws Exception { - LOG.info("bean-validator: " + manufactor + "/" + plate); - Car car = new Car(manufactor, plate); - Exchange out = producerTemplate.request("direct:start", e -> e.getMessage().setBody(car)); + public Response getXml(@PathParam("manufactor") String manufactor, @PathParam("plate") String plate) throws Exception { + return get(new CarWithAnnotations(manufactor, plate), "start"); + } + + @Path("/get/anot/{manufactor}/{plate}") + @GET + @Produces(MediaType.TEXT_PLAIN) + public Response getAnot(@PathParam("manufactor") String manufactor, @PathParam("plate") String plate) throws Exception { + return get(new CarWithAnnotations(manufactor, plate), "start"); + } + + @Path("/get/optional/{manufactor}/{plate}") + @GET + @Produces(MediaType.TEXT_PLAIN) + public Response getOptional(@PathParam("manufactor") String manufactor, @PathParam("plate") String plate) throws Exception { + return get(new CarWithAnnotations(manufactor, plate), "optional"); + } + + private Response get(Car car, String endpoint) throws Exception { + LOG.info("bean-validator: " + car.getManufacturer() + "/" + car.getLicensePlate()); + Exchange out = producerTemplate.request("direct:" + endpoint, e -> e.getMessage().setBody(car)); + if(messageInterpolator.getCount() == 0) { + return Response.status(500, "Interpolator was not used.").build(); + } if (out.isFailed()) { return Response.status(400, "Invalid car").build(); } else { diff --git a/integration-tests/bean-validator/src/main/java/org/apache/camel/quarkus/component/bean/validator/it/BeanValidatorRoute.java b/integration-tests/bean-validator/src/main/java/org/apache/camel/quarkus/component/bean/validator/it/BeanValidatorRoute.java index 76a7c7d062d9..cc4e30e6f299 100644 --- a/integration-tests/bean-validator/src/main/java/org/apache/camel/quarkus/component/bean/validator/it/BeanValidatorRoute.java +++ b/integration-tests/bean-validator/src/main/java/org/apache/camel/quarkus/component/bean/validator/it/BeanValidatorRoute.java @@ -26,5 +26,9 @@ public void configure() throws Exception { from("direct:start") .to("bean-validator:car"); + + from("direct:optional") + .to("bean-validator:xmlCar?group=org.apache.camel.quarkus.component.bean.validator.it.model.OptionalChecks"); } + } diff --git a/integration-tests/bean-validator/src/main/java/org/apache/camel/quarkus/component/bean/validator/it/ValidatinFactoryCustomizer.java b/integration-tests/bean-validator/src/main/java/org/apache/camel/quarkus/component/bean/validator/it/ValidatinFactoryCustomizer.java new file mode 100644 index 000000000000..d36d92806f0f --- /dev/null +++ b/integration-tests/bean-validator/src/main/java/org/apache/camel/quarkus/component/bean/validator/it/ValidatinFactoryCustomizer.java @@ -0,0 +1,45 @@ +package org.apache.camel.quarkus.component.bean.validator.it; + +import org.hibernate.validator.internal.constraintvalidators.bv.NotNullValidator; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Produces; +import javax.inject.Singleton; +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorFactory; +import javax.validation.MessageInterpolator; +import javax.validation.Path; +import javax.validation.TraversableResolver; +import java.lang.annotation.ElementType; +import java.util.Locale; + +@ApplicationScoped +public class ValidatinFactoryCustomizer { + + @Produces + @Singleton + public MyMessageInterpolator createMyMessageInterpolator() { + return new MyMessageInterpolator(); + } + + class MyMessageInterpolator implements MessageInterpolator { + + private int count = 0; + + @Override + public String interpolate(String messageTemplate, Context context) { + count++; + return null; + } + + @Override + public String interpolate(String messageTemplate, Context context, Locale locale) { + count++; + return null; + } + + public int getCount() { + return count; + } + } +} diff --git a/integration-tests/bean-validator/src/main/java/org/apache/camel/quarkus/component/bean/validator/it/model/Car.java b/integration-tests/bean-validator/src/main/java/org/apache/camel/quarkus/component/bean/validator/it/model/Car.java index 19db6f8099bb..2450a2ed76ed 100644 --- a/integration-tests/bean-validator/src/main/java/org/apache/camel/quarkus/component/bean/validator/it/model/Car.java +++ b/integration-tests/bean-validator/src/main/java/org/apache/camel/quarkus/component/bean/validator/it/model/Car.java @@ -16,37 +16,13 @@ */ package org.apache.camel.quarkus.component.bean.validator.it.model; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; +public interface Car { -public class Car { + String getManufacturer(); - @NotNull - private String manufacturer; + void setManufacturer(String manufacturer); - @NotNull - @Size(min = 5, max = 14) - private String licensePlate; - - public Car(String manufacturer, String licencePlate) { - this.manufacturer = manufacturer; - this.licensePlate = licencePlate; - } - - public String getManufacturer() { - return manufacturer; - } - - public void setManufacturer(String manufacturer) { - this.manufacturer = manufacturer; - } - - public String getLicensePlate() { - return licensePlate; - } - - public void setLicensePlate(String licensePlate) { - this.licensePlate = licensePlate; - } + String getLicensePlate(); + void setLicensePlate(String licensePlate); } diff --git a/integration-tests/bean-validator/src/main/java/org/apache/camel/quarkus/component/bean/validator/it/model/CarWithAnnotations.java b/integration-tests/bean-validator/src/main/java/org/apache/camel/quarkus/component/bean/validator/it/model/CarWithAnnotations.java new file mode 100644 index 000000000000..db4a41ad1185 --- /dev/null +++ b/integration-tests/bean-validator/src/main/java/org/apache/camel/quarkus/component/bean/validator/it/model/CarWithAnnotations.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.quarkus.component.bean.validator.it.model; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +public class CarWithAnnotations implements Car { + + @NotNull + private String manufacturer; + + @NotNull + @Size(min = 5, max = 14) + private String licensePlate; + + public CarWithAnnotations(String manufacturer, String licencePlate) { + this.manufacturer = manufacturer; + this.licensePlate = licencePlate; + } + + @Override + public String getManufacturer() { + return manufacturer; + } + + @Override + public void setManufacturer(String manufacturer) { + this.manufacturer = manufacturer; + } + + @Override + public String getLicensePlate() { + return licensePlate; + } + + @Override + public void setLicensePlate(String licensePlate) { + this.licensePlate = licensePlate; + } +} diff --git a/integration-tests/bean-validator/src/main/java/org/apache/camel/quarkus/component/bean/validator/it/model/CarWithoutAnnotations.java b/integration-tests/bean-validator/src/main/java/org/apache/camel/quarkus/component/bean/validator/it/model/CarWithoutAnnotations.java new file mode 100644 index 000000000000..ee8b6c208afa --- /dev/null +++ b/integration-tests/bean-validator/src/main/java/org/apache/camel/quarkus/component/bean/validator/it/model/CarWithoutAnnotations.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.quarkus.component.bean.validator.it.model; + +//@RegisterForReflection +public class CarWithoutAnnotations implements Car { + + private String manufacturer; + + private String licensePlate; + + public CarWithoutAnnotations(String manufacturer, String licencePlate) { + this.manufacturer = manufacturer; + this.licensePlate = licencePlate; + } + + @Override + public String getManufacturer() { + return manufacturer; + } + + @Override + public void setManufacturer(String manufacturer) { + this.manufacturer = manufacturer; + } + + @Override + public String getLicensePlate() { + return licensePlate; + } + + @Override + public void setLicensePlate(String licensePlate) { + this.licensePlate = licensePlate; + } +} diff --git a/integration-tests/bean-validator/src/main/java/org/apache/camel/quarkus/component/bean/validator/it/model/OptionalChecks.java b/integration-tests/bean-validator/src/main/java/org/apache/camel/quarkus/component/bean/validator/it/model/OptionalChecks.java new file mode 100644 index 000000000000..fc40952e2773 --- /dev/null +++ b/integration-tests/bean-validator/src/main/java/org/apache/camel/quarkus/component/bean/validator/it/model/OptionalChecks.java @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.quarkus.component.bean.validator.it.model; + +import io.quarkus.runtime.annotations.RegisterForReflection; + +@RegisterForReflection +public interface OptionalChecks { +} diff --git a/integration-tests/bean-validator/src/main/resources/META-INF/validation.xml b/integration-tests/bean-validator/src/main/resources/META-INF/validation.xml new file mode 100644 index 000000000000..fb7baceb6e4b --- /dev/null +++ b/integration-tests/bean-validator/src/main/resources/META-INF/validation.xml @@ -0,0 +1,28 @@ + + + + + org.hibernate.validator.HibernateValidator + org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator + /constraints-car.xml + + \ No newline at end of file diff --git a/integration-tests/bean-validator/src/main/resources/constraints-car.xml b/integration-tests/bean-validator/src/main/resources/constraints-car.xml new file mode 100644 index 000000000000..486f0eb58588 --- /dev/null +++ b/integration-tests/bean-validator/src/main/resources/constraints-car.xml @@ -0,0 +1,42 @@ + + + + org.apache.camel.component.bean.validator + + + + + + + + + + + + org.apache.camel.quarkus.component.bean.validator.it.model.OptionalChecks + + 5 + 14 + + + + \ No newline at end of file diff --git a/integration-tests/bean-validator/src/test/java/org/apache/camel/quarkus/component/bean/validator/it/BeanValidatorTest.java b/integration-tests/bean-validator/src/test/java/org/apache/camel/quarkus/component/bean/validator/it/BeanValidatorTest.java index 8e91c6745be8..2954010afaf3 100644 --- a/integration-tests/bean-validator/src/test/java/org/apache/camel/quarkus/component/bean/validator/it/BeanValidatorTest.java +++ b/integration-tests/bean-validator/src/test/java/org/apache/camel/quarkus/component/bean/validator/it/BeanValidatorTest.java @@ -25,9 +25,18 @@ class BeanValidatorTest { @Test public void test() { - RestAssured.get("/bean-validator/get/honda/123").then().statusCode(400); + RestAssured.get("/bean-validator/get/anot/honda/123").then().statusCode(400); + + RestAssured.get("/bean-validator/get/anot/honda/DD-AB-123").then().statusCode(200); + + RestAssured.get("/bean-validator/get/xml/honda/123").then().statusCode(400); + + RestAssured.get("/bean-validator/get/xml/honda/DD-AB-123").then().statusCode(200); + + RestAssured.get("/bean-validator/get/optional/honda/123").then().statusCode(200); + + RestAssured.get("/bean-validator/get/optional/honda/DD-AB-12").then().statusCode(200); - RestAssured.get("/bean-validator/get/honda/DD-AB-123").then().statusCode(200); } }