Skip to main content
Version: Early Access

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.

note

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

warning

Package Name Requirements Custom validation rules must use one of these approved package structures:

  • ai.digital
  • com.xebialabs
  • ext.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.

note

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 Maven
  • build/libs/ directory for Gradle
  • Copy the JAR file to the hotfix/lib directory 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.File modification: Create a new file CI and try setting Target File Name to a value that doesn't match the JIRA-[number] pattern
  • For the tc.WarModule type: Create a new WAR module and try setting Change Ticket Number to an invalid format.
  • For the test.EmbeddedServer type: 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.