-
Notifications
You must be signed in to change notification settings - Fork 2.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Don't fail Hibernate Validator when no RESTEasy Reactive request is in progress #19844
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
182 changes: 182 additions & 0 deletions
182
integration-tests/hibernate-validator-resteasy-reactive/pom.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
167 changes: 167 additions & 0 deletions
167
...ctive/src/main/java/io/quarkus/it/hibernate/validator/HibernateValidatorTestResource.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
|
||
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; | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
...ava/io/quarkus/it/hibernate/validator/HibernateValidatorTestResourceGenericInterface.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
|
||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not possible to return an empty header object? I'm not sure I understand how the case of not having a request can happen and when the user will be confronted to it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I understand from the OP's case is that
ResteasyReactiveRequestContext.getHttpHeaders()
fails somehow. I'm wondering if we should return empty headers there and thus cover this case entirely.Note that I have absolutely no knowledge of the RR codebase so I'm just thinking out loud, given the pattern above looks hackyish and fixing the issue at the source might be a more general solution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
org.jboss.resteasy.reactive.server.injection.ContextProducers.getHttpHeaders()
would indeed make sense to return an empty headers in this case. However it does not make sense for others inContextProducers
, so we need a consistent approach.