Validation Rules
An expansion-resource can define Validation Rules to validate models.
Validation Rules are integrated into the Radiant. You can also generate reports on command line
Adding new Rules
To add a new rule, create a class that implements ValidatableRule
and add @ValidationRule
and @ValidationGroup
:
@ValidationRule(
element = "elements::Application",
severity = ValidationSeverity.ERROR,
reason = "Short explanation",
description = "More detailed description"
)
@ValidationGroup("My Rules")
public class MyNewRule implements ValidatableRule<ApplicationComposite> {
@Override
public void validate(ApplicationComposite application, Critiques critiques) {
// implement validation
}
}
The target element can be any element. Just make sure that generic type of the interface matches the Composite of that element.
Conditional Rules
If a rule only applies to a subset of element, you can make it conditional.
Conditional Rules need to implement the ConditionalRule
interface:
@ValidationRule(
element = "elements::Application",
severity = ValidationSeverity.WARNING,
reason = "Short explanation",
description = "More detailed description"
)
@ValidationGroup("Missing Defaults")
public class MyNewRule implements ValidatableRule<ApplicationComposite>, ConditionalRule<ApplicationComposite> {
@Override
public boolean guard(ApplicationComposite application) {
// implement check when the rule is applicable
}
@Override
public void validate(ApplicationComposite application, Critiques critiques) {
// implement validation
}
}
Formatting critiques
To provide the user with clear critiques, you can use formatting to include variables into the message.
...
@Override
public void validate(ApplicationComposite app, Critiques critiques) {
// both {element} and {<elementName>} can be used to substitue a reference
critiques.add(app, "{element} has an issue");
critiques.add(app, "{application} has an issue");
// additional arguments can be referenced through {<index>}, starting at 1
critiques.add(app, "{element} did not contain {1}", "components");
// or they can be passed as a Map and referenced by {<key>}
Map<String,Object> arguments = Map.of("missing", "components");
critiques.add(app, "{element} did not contain {missing}", arguments);
}
...
Writing tests
To test your validation rules, there is a ValidationRuleTester
class.
class MyNewRuleTest {
private final TestModelBuilder modelBuilder = new TestModelBuilder();
private final ValidationRuleTester<ApplicationComposite> tester = new ValidationRuleTester<>(this);
// Create model test rule
private ApplicationComposite baseModel() {
ApplicationSpec spec = application("testApp");
return modelBuilder.build(spec);
}
@Test
public void testPassing() {
tester.testPassing(baseModel());
}
@Test
public void testFailing() {
ApplicationComposite model = baseModel();
// Do some changes
tester.testFailing(model, "expected errors");
}
@Test
public void testGuard() {
tester.testGuard(baseModel());
}
@Test
public void testFailGuard() {
ApplicationComposite model = baseModel();
// Do some changes
tester.testFailGuard(model);
}
}
Creating a new validation project
To create a new validation resource project you will need to create a maven project.
Add the following dependencies to the project:
<dependencies>
<!-- Provides metamodel classes, like ApplicationComposite -->
<dependency>
<groupId>net.democritus.metamodel</groupId>
<artifactId>prime-core</artifactId>
<version>2024.8.0</version>
</dependency>
<!-- Provides annotations and interfaces for the validation rules -->
<dependency>
<groupId>net.democritus.validations.model</groupId>
<artifactId>validations-core</artifactId>
<version>3.7.0</version>
</dependency>
<!-- Provides tester class -->
<dependency>
<groupId>net.democritus.validations.model</groupId>
<artifactId>validations-test-support</artifactId>
<version>3.7.0</version>
<scope>test</scope>
</dependency>
</dependencies>
Then, add the expansionResource
goal (if not already present):
<plugins>
<plugin>
<groupId>net.democritus.maven.plugins</groupId>
<artifactId>expanders-maven-plugin</artifactId>
<version>${expanders-maven-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>expansionResource</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>