Hear from Salesforce leaders on how to create and deploy Agentforce agents.
Contact Us 1-800-596-4880

Building a Custom Validator

If you want to perform complex validation logic, or reuse some code you already have on a separate JAR file, then the is-true and is-false fallback validators might not be the most convenient solution for you. You might then want to build your own validator. Leveraging the Validator APILeaving the Site, you can create your own validators, and there then are two mechanisms that allow you to execute them in a flow. Below are the necessary steps necessary to do that.

Implement the Validator Interface

Just like other components like the MessageProcessor, Filter, Router, etc., the validators also have a well defined contract inside Mule’s code:

/**
 * A component which performs a validation and expresses
 * its result through a {@link ValidationResult} object.
 * <p/>
 * The {@link #validate(MuleEvent)} method receives a
 * {@link MuleEvent} in order to make it generic and easy to extend.
 * However, that doesn't necessarily mean that all the validation
 * is performed with or over the event exclusively. Thread
 * safeness is not to be assumed over instances of this class
 * since the validator could be stateful.
 *
 * @since 3.7.0
 */
public interface Validator
{

    /**
     * Performs the validation and generates a
     * {@link ValidationResult} back.
     *
     * @param event the current {@link MuleEvent}
     * @return a {@link ValidationResult}
     */
    ValidationResult validate(MuleEvent event);
}
java

Below is what the ValidationResult looks like:

Your implementations of the Validator interface are required to:

  • Have a default constructor

  • Be thread-safe

  • Not have any side effects over the message payload or any of its variables

Once you’ve done that, you can execute the validator through the custom-validator message processor:

<validation:custom-validator class="com.myproject.CustomValidator" config-ref="validator" />
xml

Each instance of custom-validator creates its own instance of the given class and holds it, thus the requirement to be thread-safe. The recommended way of achieving thread safeness is by being stateless, but that’s up to the developer. Another option is to reference the custom validator via a registry name:

<mule>
  <spring:beans>
    <spring:bean id="customValidator" class="com.myproject.CustomValidator" />
  </spring:beans>
  <flow name="customValidator">
    <validation:custom-validator ref="customValidator" />
  </flow>
</mule>
xml

Notice that once more, the instance of the validator to be used is always the same across different executions and thus the validator needs to be thread-safe. Your implementation of Validator can be either within the project or in a jar you add to the classpath. It doesn’t matter as long as it’s instantiable by the application’s class loader.

Customizing Exception Class and Message

There are some cases in which the user might require low level control on how exceptions are created when a validation fails. For that, the following interface is used:

The above interface receives the Event that was rejected by the validation and the validator that raised the error. This method is intended to return the exception to be thrown but not to throw it. Implementations of this interface should never throw exceptions. They should also be thread-safe and have a public default constructor.

See Also