Skip to content

Commit

Permalink
Merge pull request #19844 from geoand/#19834-validation
Browse files Browse the repository at this point in the history
Don't fail Hibernate Validator when no RESTEasy Reactive request is in progress
  • Loading branch information
gsmet authored Sep 2, 2021
2 parents aeab361 + ee298ec commit 05bebe3
Show file tree
Hide file tree
Showing 10 changed files with 473 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ public ResteasyReactiveContextLocaleResolver(HttpHeaders headers) {

@Override
protected HttpHeaders getHeaders() {
return headers;
try {
headers.getLength(); // this forces the creation of the actual object which will fail if there is no request in flight
return headers;
} catch (IllegalStateException e) {
return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,10 @@ SecurityContext securityContext() {
}

private ResteasyReactiveRequestContext getContext() {
return CurrentRequestManager.get();
ResteasyReactiveRequestContext context = CurrentRequestManager.get();
if (context == null) {
throw new IllegalStateException("No RESTEasy Reactive request in progress");
}
return context;
}
}
182 changes: 182 additions & 0 deletions integration-tests/hibernate-validator-resteasy-reactive/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>quarkus-integration-tests-parent</artifactId>
<groupId>io.quarkus</groupId>
<version>999-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>quarkus-integration-test-hibernate-validator-resteasy-reactive</artifactId>
<name>Quarkus - Integration Tests - Hibernate Validator</name>
<description>Module that contains Hibernate Validator/Bean Validation related tests using RESTEasy Reactive</description>

<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive-jsonb</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-arc</artifactId>
</dependency>

<!-- To test the ORM integration -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-orm</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-h2</artifactId>
</dependency>

<!-- Test dependencies -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-test-h2</artifactId>
<scope>test</scope>
</dependency>
<!-- Minimal test dependencies to *-deployment artifacts for consistent build order -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-arc-deployment</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-orm-deployment</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-validator-deployment</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-h2-deployment</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive-jsonb-deployment</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<!-- force the locale as we want to explicitly test message interpolation -->
<user.language>en</user.language>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>

<profiles>
<profile>
<id>native-image</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<build>
<!-- add some custom config, the rest comes from parent -->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<!-- force the locale as we want to explicitly test message interpolation -->
<user.language>en</user.language>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
package io.quarkus.it.hibernate.validator;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import javax.enterprise.event.Observes;
import javax.inject.Inject;
import javax.validation.ConstraintViolation;
import javax.validation.Valid;
import javax.validation.Validator;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.Email;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.hibernate.validator.constraints.Length;

import io.quarkus.it.hibernate.validator.custom.MyOtherBean;
import io.quarkus.runtime.StartupEvent;

@Path("/hibernate-validator/test")
public class HibernateValidatorTestResource {

@Inject
Validator validator;

public void testValidationOutsideOfResteasyContext(@Observes StartupEvent startupEvent) {
validator.validate(new MyOtherBean(null));
}

@GET
@Path("/basic-features")
@Produces(MediaType.TEXT_PLAIN)
public String testBasicFeatures() {
ResultBuilder result = new ResultBuilder();

Map<String, List<String>> invalidCategorizedEmails = new HashMap<>();
invalidCategorizedEmails.put("a", Collections.singletonList("b"));

result.append(formatViolations(validator.validate(new MyBean(
"Bill Jones",
"b",
Collections.singletonList("c"),
-4d,
invalidCategorizedEmails))));

Map<String, List<String>> validCategorizedEmails = new HashMap<>();
validCategorizedEmails.put("Professional", Collections.singletonList("[email protected]"));

result.append(formatViolations(validator.validate(new MyBean(
"Bill Jones",
"[email protected]",
Collections.singletonList("[email protected]"),
5d,
validCategorizedEmails))));

return result.build();
}

private String formatViolations(Set<? extends ConstraintViolation<?>> violations) {
if (violations.isEmpty()) {
return "passed";
}

return "failed: " + violations.stream()
.map(v -> v.getPropertyPath().toString() + " (" + v.getMessage() + ")")
.sorted()
.collect(Collectors.joining(", "));
}

public static class MyBean {

private String name;

@Email
private String email;

private List<@Email String> additionalEmails;

@DecimalMin("0")
private Double score;

private Map<@Length(min = 3) String, List<@Email String>> categorizedEmails;

@Valid
private NestedBeanWithoutConstraints nestedBeanWithoutConstraints;

public MyBean(String name, String email, List<String> additionalEmails, Double score,
Map<String, List<String>> categorizedEmails) {
this.name = name;
this.email = email;
this.additionalEmails = additionalEmails;
this.score = score;
this.categorizedEmails = categorizedEmails;
this.nestedBeanWithoutConstraints = new NestedBeanWithoutConstraints();
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public List<String> getAdditionalEmails() {
return additionalEmails;
}

public void setAdditionalEmails(List<String> additionalEmails) {
this.additionalEmails = additionalEmails;
}

public Double getScore() {
return score;
}

public void setScore(Double score) {
this.score = score;
}

public Map<String, List<String>> getCategorizedEmails() {
return categorizedEmails;
}

public void setCategorizedEmails(Map<String, List<String>> categorizedEmails) {
this.categorizedEmails = categorizedEmails;
}
}

private static class ResultBuilder {

private StringBuilder builder = new StringBuilder();

public ResultBuilder append(String element) {
if (builder.length() > 0) {
builder.append("\n");
}
builder.append(element);
return this;
}

public String build() {
return builder.toString();
}
}

private static class NestedBeanWithoutConstraints {

@SuppressWarnings("unused")
private String property;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package io.quarkus.it.hibernate.validator;

import javax.validation.constraints.Digits;

public interface HibernateValidatorTestResourceGenericInterface<T extends Number> {

T testRestEndpointGenericMethodValidation(@Digits(integer = 5, fraction = 0) T id);

}
Loading

0 comments on commit 05bebe3

Please sign in to comment.