generated from micronaut-projects/micronaut-project-template
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Custom validation have incomplete proprety path #205
Reproducer for #205
Showing
28 changed files
with
1,132 additions
and
0 deletions.
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
53 changes: 53 additions & 0 deletions
53
test-suite/src/test/java/io/micronaut/docs/validation/path/ValidationTest.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,53 @@ | ||
package io.micronaut.docs.validation.path; | ||
|
||
import io.micronaut.docs.validation.path.model.Dag; | ||
import io.micronaut.docs.validation.path.model.Flow; | ||
import io.micronaut.docs.validation.path.model.Log; | ||
import io.micronaut.test.extensions.junit5.annotation.MicronautTest; | ||
import jakarta.inject.Inject; | ||
import jakarta.validation.Validator; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import java.util.List; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
|
||
@MicronautTest(startApplication = false) | ||
public class ValidationTest { | ||
@Inject | ||
Validator validator; | ||
|
||
@Test | ||
void testValidationOk() { | ||
Flow f = Flow.builder() | ||
.id("id") | ||
.namespace("namespace") | ||
.tasks(List.of(Log.builder().id("task").type(Log.class.getName()).message("").build())) | ||
.build(); | ||
|
||
var violation = validator.validate(f).stream().findFirst().get(); | ||
assertEquals("tasks[0].message", violation.getPropertyPath().toString()); | ||
assertEquals("must not be blank", violation.getMessage()); | ||
} | ||
|
||
@Test | ||
void testValidationKo() { | ||
Flow f = Flow.builder() | ||
.id("id") | ||
.namespace("namespace") | ||
.tasks(List.of( | ||
Dag.builder() | ||
.id("dag") | ||
.type(Dag.class.getName()) | ||
.tasks(List.of( | ||
Dag.DagTask.builder().task(Log.builder().id("cycle").type(Log.class.getName()).message("").build()).dependsOn(List.of("cycle")).build() | ||
)) | ||
.build()) | ||
) | ||
.build(); | ||
|
||
var violation = validator.validate(f).stream().findFirst().get(); | ||
assertEquals("tasks[0].tasks", violation.getPropertyPath().toString()); | ||
assertEquals("Cyclic dependency detected: cycle", violation.getMessage()); | ||
} | ||
} |
41 changes: 41 additions & 0 deletions
41
test-suite/src/test/java/io/micronaut/docs/validation/path/model/AbstractTrigger.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,41 @@ | ||
package io.micronaut.docs.validation.path.model; | ||
|
||
import io.micronaut.core.annotation.Introspected; | ||
import jakarta.validation.Valid; | ||
import jakarta.validation.constraints.NotBlank; | ||
import jakarta.validation.constraints.NotNull; | ||
import jakarta.validation.constraints.Pattern; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import lombok.experimental.SuperBuilder; | ||
|
||
import java.util.List; | ||
|
||
@SuperBuilder | ||
@Getter | ||
@NoArgsConstructor | ||
@Introspected | ||
abstract public class AbstractTrigger { | ||
@NotNull | ||
@NotBlank | ||
@Pattern(regexp="[a-zA-Z0-9_-]+") | ||
protected String id; | ||
|
||
@NotNull | ||
@NotBlank | ||
@Pattern(regexp="\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*(\\.\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*)*") | ||
protected String type; | ||
|
||
private String description; | ||
|
||
@Valid | ||
private List<Condition> conditions; | ||
|
||
@NotNull | ||
@Builder.Default | ||
private boolean disabled = false; | ||
|
||
@Valid | ||
private WorkerGroup workerGroup; | ||
} |
20 changes: 20 additions & 0 deletions
20
test-suite/src/test/java/io/micronaut/docs/validation/path/model/Condition.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,20 @@ | ||
package io.micronaut.docs.validation.path.model; | ||
|
||
import io.micronaut.core.annotation.Introspected; | ||
import jakarta.validation.constraints.NotNull; | ||
import jakarta.validation.constraints.Pattern; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import lombok.experimental.SuperBuilder; | ||
|
||
@SuperBuilder | ||
@Getter | ||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
@Introspected | ||
public abstract class Condition { | ||
@NotNull | ||
@Pattern(regexp="\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*(\\.\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*)*") | ||
protected String type; | ||
} |
105 changes: 105 additions & 0 deletions
105
test-suite/src/test/java/io/micronaut/docs/validation/path/model/Dag.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,105 @@ | ||
package io.micronaut.docs.validation.path.model; | ||
|
||
import io.micronaut.core.annotation.Introspected; | ||
import io.micronaut.docs.validation.path.validations.DagTaskValidation; | ||
import jakarta.validation.Valid; | ||
import jakarta.validation.constraints.NotEmpty; | ||
import jakarta.validation.constraints.NotNull; | ||
import lombok.Builder; | ||
import lombok.EqualsAndHashCode; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import lombok.ToString; | ||
import lombok.experimental.SuperBuilder; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collection; | ||
import java.util.List; | ||
import java.util.Objects; | ||
import java.util.Optional; | ||
import java.util.stream.Collectors; | ||
|
||
@SuperBuilder | ||
@ToString | ||
@EqualsAndHashCode | ||
@Getter | ||
@NoArgsConstructor | ||
@DagTaskValidation | ||
public class Dag extends Task{ | ||
@NotNull | ||
@Builder.Default | ||
private final Integer concurrent = 0; | ||
|
||
@NotEmpty | ||
@Valid | ||
private List<DagTask> tasks; | ||
|
||
@Valid | ||
protected List<Task> errors; | ||
|
||
public List<String> dagCheckNotExistTask(List<DagTask> taskDepends) { | ||
List<String> dependenciesIds = taskDepends | ||
.stream() | ||
.map(DagTask::getDependsOn) | ||
.filter(Objects::nonNull) | ||
.flatMap(Collection::stream) | ||
.toList(); | ||
|
||
List<String> tasksIds = taskDepends | ||
.stream() | ||
.map(taskDepend -> taskDepend.getTask().getId()) | ||
.toList(); | ||
|
||
return dependenciesIds.stream() | ||
.filter(dependencyId -> !tasksIds.contains(dependencyId)) | ||
.collect(Collectors.toList()); | ||
} | ||
|
||
public ArrayList<String> dagCheckCyclicDependencies(List<DagTask> taskDepends) { | ||
ArrayList<String> cyclicDependency = new ArrayList<>(); | ||
taskDepends.forEach(taskDepend -> { | ||
if (taskDepend.getDependsOn() != null) { | ||
List<String> nestedDependencies = this.nestedDependencies(taskDepend, taskDepends, new ArrayList<>()); | ||
if (nestedDependencies.contains(taskDepend.getTask().getId())) { | ||
cyclicDependency.add(taskDepend.getTask().getId()); | ||
} | ||
} | ||
}); | ||
|
||
return cyclicDependency; | ||
} | ||
|
||
private ArrayList<String> nestedDependencies(DagTask taskDepend, List<DagTask> tasks, List<String> visited) { | ||
final ArrayList<String> localVisited = new ArrayList<>(visited); | ||
if (taskDepend.getDependsOn() != null) { | ||
taskDepend.getDependsOn() | ||
.stream() | ||
.filter(depend -> !localVisited.contains(depend)) | ||
.forEach(depend -> { | ||
localVisited.add(depend); | ||
Optional<DagTask> task = tasks | ||
.stream() | ||
.filter(t -> t.getTask().getId().equals(depend)) | ||
.findFirst(); | ||
|
||
if (task.isPresent()) { | ||
localVisited.addAll(this.nestedDependencies(task.get(), tasks, localVisited)); | ||
} | ||
}); | ||
} | ||
return localVisited; | ||
} | ||
|
||
@SuperBuilder | ||
@ToString | ||
@EqualsAndHashCode | ||
@Getter | ||
@NoArgsConstructor | ||
@Introspected | ||
public static class DagTask { | ||
@NotNull | ||
private Task task; | ||
|
||
private List<String> dependsOn; | ||
} | ||
} |
5 changes: 5 additions & 0 deletions
5
test-suite/src/test/java/io/micronaut/docs/validation/path/model/DeletedInterface.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,5 @@ | ||
package io.micronaut.docs.validation.path.model; | ||
|
||
public interface DeletedInterface { | ||
boolean isDeleted(); | ||
} |
Oops, something went wrong.