Create Custom Validation Rules
Custom validators are project-specific rules you create when built-in validators don’t meet your needs. Implement the validator in Java, package it as a JAR, and deploy it to the server.
Validation rules prevent saving or deploying a CI if its properties do not meet the specified constraints.
When to Use a Custom Validator
- To enforce business-specific logic
- Validate formats not expressible through built-in validators
- Compare multiple properties
- Call external services
- Raise warnings instead of errors
For information about the built-in rules that are available in Deploy, see Built-in Validation Rules
Prerequisites
Before creating custom validation rules, ensure the following tools are installed and configured:
If you are unsure which build tool to choose, check this Gradle and Maven Comparison to help you decide. You will also need a local Java development environment that matches the Java version used by your Digital.ai Deploy server.
Creating Custom Validation Rule in Java
This section provides a complete, working example of how to create, package, and use a custom validation rule in Digital.ai Deploy.
1. Project Structure
Package Name Requirements Custom validation rules must use one of these approved package structures:
ai.digitalcom.xebialabsext.deployit
Using other package names will cause the validation to fail.
custom-validation-rule/
├── src/
│ └── main/
│ └── java/
│ └── ai/
│ └── digital/
│ └── StaticContent.java
├── pom.xml or build.gradle
2. Implement the Java Validation Rule
StaticContent.java:
package ai.digital;
import com.xebialabs.deployit.plugin.api.validation.Rule;
import com.xebialabs.deployit.plugin.api.validation.ValidationContext;
import com.xebialabs.deployit.plugin.api.validation.ApplicableTo;
import com.xebialabs.deployit.plugin.api.reflect.PropertyKind;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@ApplicableTo(PropertyKind.STRING)
@Retention(RetentionPolicy.RUNTIME)
@Rule(clazz = StaticContent.Validator.class, type = "static-content")
@Target(ElementType.FIELD)
public @interface StaticContent {
String content();
public static class Validator
implements com.xebialabs.deployit.plugin.api.validation.Validator<String> {
private String content;
@Override
public void validate(String value, ValidationContext context) {
if (value != null && !value.equals(content)) {
context.error("Value should be %s but was %s", content, value);
}
}
}
}
3. Configure the Build
You can use either Maven or Gradle to compile and package your rule. Check the Digital.ai Public Repository to find the latest compatible version of the plugins.
Maven Example:
pom.xml:
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ai.digital</groupId>
<artifactId>custom-validation-rule</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<repositories>
<repository>
<id>xebialabs-public</id>
<url>https://dist.xebialabs.com/public/maven2/com/xebialabs/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.xebialabs.deployit</groupId>
<artifactId>udm-plugin-api</artifactId>
<version>LATEST_COMPATIBLE_VERSION</version>
</dependency>
<!-- Add other plugin modules here if needed -->
</dependencies>
</project>
To build the JAR with Maven, run:
mvn clean package
Gradle Example:
build.gradle:
plugins {
id 'java'
}
group = 'ai.digital'
version = '1.0.0'
repositories {
mavenCentral() // Add Maven Central for standard dependencies
maven {
name = 'xebialabs-public'
url = 'https://dist.xebialabs.com/public/maven2'
name = 'xebialabs-public'
url = 'https://dist.xebialabs.com/public/maven2'
}
}
dependencies {
implementation 'com.xebialabs.deployit:udm-plugin-api:LATEST_COMPATIBLE_VERSION'
// Add other plugin modules here if needed
}
To build the JAR with Gradle, run:
gradle clean build
If you are using dependencies hosted in the Digital.ai Public Repository, you must explicitly declare the repository url in your pom.xml under the <repositories> section. This ensures that Maven can resolve and download the required artifacts.
Always use the version of the module that matches your Deploy server version to ensure compatibility. When Deploy upgrades change public APIs, rebuild your custom JAR against the new API versions and test it thoroughly before putting it into production.
4. Locate the JAR
After the build completes, you will find a JAR file in:
target/directory for Mavenbuild/libs/directory for Gradle- Copy the JAR file to the
hotfix/libdirectory of your Deploy server.
5. Use the Custom Rule
After placing the JAR file, you need to define how your custom validation rule should be used by creating or modifying CI types in the synthetic.xml file, which is found inside the ext/ folder of your Deploy server.
Option 1: Modify Existing CI Types
To add validation rules to existing CI types, use type-modification in your ext/synthetic.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<synthetic xsi:schemaLocation="http://www.xebialabs.com/deployit/synthetic synthetic.xsd" xmlns="http://www.xebialabs.com/deployit/synthetic" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- Using built-in regex validation on file.File -->
<type-modification type="file.File">
<property name="targetFileName" kind="string" required="false" description="Name of the file on bucket along with extension.">
<rule type="regex" pattern="^JIRA-[0-9]+$"
message="targetFileName should be of the form JIRA-[number]"/>
</property>
</type-modification>
</synthetic>
Option 2: Create New CI Types
To create completely new CI types with validation rules, define them in your ext/synthetic.xml file like below:
Example 1: New WAR module type with built-in regex validation
<?xml version="1.0" encoding="UTF-8"?>
<synthetic xsi:schemaLocation="http://www.xebialabs.com/deployit/synthetic synthetic.xsd" xmlns="http://www.xebialabs.com/deployit/synthetic" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<type type="tc.WarModule" extends="udm.BaseDeployedArtifact" deployable-type="jee.War" container-type="tc.Server">
<generate-deployable type="tc.Server" extends="jee.War" description="TC server Container"/>
<property name="changeTicketNumber" required="true">
<rule type="regex" pattern="^JIRA-[0-9]+$"
message="Ticket number should be of the form JIRA-[number]"/>
</property>
</type>
</synthetic>
Example 2: New Embedded Server with custom staticContent validation
<?xml version="1.0" encoding="UTF-8"?>
<synthetic xsi:schemaLocation="http://www.xebialabs.com/deployit/synthetic synthetic.xsd" xmlns="http://www.xebialabs.com/deployit/synthetic" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<type type="test.EmbeddedServer" extends="udm.BaseContainer">
<property name="host" kind="ci" referenced-type="overthere.Host" as-containment="true"/>
<property name="temporaryDirectory">
<rule type="staticContent" content="/tmp"/>
</property>
</type>
</synthetic>
Apply the Changes
After copying the JAR and updating your synthetic.xml file:
- Save your changes.
- Restart the Deploy server to load the new validation rules.
Testing the Validation
After restarting Deploy:
- For the
file.Filemodification: Create a new file CI and try setting Target File Name to a value that doesn't match theJIRA-[number]pattern - For the
tc.WarModuletype: Create a new WAR module and try setting Change Ticket Number to an invalid format. - For the
test.EmbeddedServertype: Create an overthere -> LocalHost infrastructure CI first, then create a new test.EmbeddedServer CI and try setting temporaryDirectory to any value other than/tmp
Deploy will display validation errors if the values don't meet the specified criteria.