Skip to content

Commit

Permalink
Don't fail Hibernate Validator when no RESTEasy Reactive request is i…
Browse files Browse the repository at this point in the history
…n flight

Relates to: #19834
  • Loading branch information
geoand committed Sep 1, 2021
1 parent 469e81a commit ee298ec
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 ee298ec

Please sign in to comment.