Custom Validation in Mule 4 Using Mule SDK

Custom Validation in Mule

Validators are operations that validate the Mule Message without changing the message. Validators can produce these effects:

  • If the condition the validator demands is fulfilled, the flow continues, and the Mule Message remains the same.
  • If the condition the validator demands is not fulfilled, an error is thrown.

Today we will be creating a custom validation that will validate whether a currency is valid or not.

Prerequisites

Steps to Create Custom Validator

  • Create Project: Go to your project folder and run the Maven command to generate the project for the Mule validator extension. mvn org.mule.extensions:mule-extensions-archetype-maven-plugin:1.2.0:generate 
> mvn org.mule.extensions:mule-extensions-archetype-maven-plugin:1.2.0:generate

[INFO] Scanning for projects...
[INFO] 
[INFO] ------------------< org.apache.maven:standalone-pom >-------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] --------------------------------[ pom ]---------------------------------
[INFO] 
[INFO] --- mule-extensions-archetype-maven-plugin:1.2.0:generate (default-cli) @ standalone-pom ---
* Enter the name of the extension (empty for default): 
Mule Currency Validator
* Enter the extension's groupId (empty for default): 
org.shyam.mule.extension
* Enter the extension's artifactId (empty for default): 
mule-currency-validator
* Enter the extension's version (empty for default): 
1.0.0
* Enter the extension's main package (empty for default): 
currency
[INFO] Generating project in Batch mode
[INFO] Archetype repository not defined. Using the one from [org.mule.extensions:mule-extensions-archetype:1.2.0] found in catalog remote
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Archetype: mule-extensions-archetype:1.2.0
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: mule-currency-validator
[INFO] Parameter: artifactId, Value: mule-currency-validator
[INFO] Parameter: version, Value: 1.0.0
[INFO] Parameter: package, Value: currency
[INFO] Parameter: packageInPathFormat, Value: currency
[INFO] Parameter: extensionNameNoSpaces, Value: Mulecurrencyvalidator
[INFO] Parameter: extensionName, Value: Mule-currency-validator
[INFO] Parameter: package, Value: currency
[INFO] Parameter: groupId, Value: mule-currency-validator
[INFO] Parameter: artifactId, Value: mule-currency-validator
[INFO] Parameter: version, Value: 1.0.0
[WARNING] Don't override file /Users/shyamrajprasad/mule/mule-currency-validator/src/main/java/currency
[WARNING] Don't override file /Users/shyamrajprasad/mule/mule-currency-validator/src/test/java/currency
[WARNING] Don't override file /Users/shyamrajprasad/mule/mule-currency-validator/src/test/resources
[INFO] Project created from Archetype in dir: /Users/shyamrajprasad/mule/mule-currency-validator
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  55.274 s
[INFO] Finished at: 2022-06-12T20:19:28+05:30
[INFO] ------------------------------------------------------------------------

  • Remove Connector Configurations: Delete the below four Java classes. These files will be used for the custom connectors.
    • CurrencyValidatorConfiguration 
    • CurrencyValidatorConnection 
    • CurrencyValidatorConnectionProvider 
    • CurrencyValidatorOperationsTestCase
  • Currency Dependency: Add the below dependency in pom.xml for currency.
<dependencies>
    <dependency>
        <groupId>org.javamoney</groupId>
        <artifactId>moneta</artifactId>
        <version>1.1</version>
    </dependency>
</dependencies>
  • CurrencyValidatorExtension: This is a currency validator extension class. Add the below lines in this class.
@Xml(prefix = "currency-validator")
@Extension(name = "Currency Validator")
@ErrorTypes(CurrencyError.class)
@Operations(CurrencyValidatorOperations.class)
public class CurrencyValidatorExtension {

} 
  • CurrencyValidatorOperations: The CurrencyValidatorOperations class below adds a validation method that is annotated with @Validator. The method throws an error type that comes from the generic validation error type. Note that you can also annotate the class CurrencyValidatorOperations with @Validatorbut if you do, any other operations in it will be flagged as validators.
public class CurrencyValidatorOperations {

    @Validator
    @Throws(CurrencyErrorsProvider.class)
    public void isValidCurrencyCode(String currencyCode) throws Exception {
        Collection<CurrencyUnit> currencyUnits= Monetary.getCurrencies();
        Set<String> currencyCodes = new HashSet<String>();
        for (CurrencyUnit c : currencyUnits) {
            currencyCodes.add(c.getCurrencyCode());
        }

        if(!currencyCodes.contains(currencyCode)) {
            throw new ModuleException(CurrencyError.INVALID_CURRENCY_CODE, new IllegalArgumentException("Invalid currency : " + currencyCode));
        }
    }

}
  • CurrencyError: This creates the error to throw if the currency validation fails. Notice that it is named according to the validation failure.
    public enum CurrencyError implements ErrorTypeDefinition<CurrencyError> {
        INVALID_CURRENCY_CODE(MuleErrors.VALIDATION);
    
        private ErrorTypeDefinition<? extends Enum<?>> parent;
    
        CurrencyError(ErrorTypeDefinition<? extends Enum<?>> parent) {
            this.parent = parent;
        }
    
        @Override
        public Optional<ErrorTypeDefinition<? extends Enum<?>>> getParent() {
            return Optional.ofNullable(parent);
        }
    }
  • CurrencyErrorsProvider: The validator method needs a ErrorTypeProvider that knows all the error types that the validation can throw. This example creates a ErrorTypeProvider that says that the only error the method can throw is of type CURRENCY-VALIDATOR:INVALID_CURRENCY_CODE
    public class CurrencyErrorsProvider implements ErrorTypeProvider {
    
        @Override
        public Set<ErrorTypeDefinition> getErrorTypes() {
            HashSet<ErrorTypeDefinition> errors = new HashSet<>();
            errors.add(CurrencyError.INVALID_CURRENCY_CODE);
            return errors;
        }
    }
  • Validator Icon: Go to the project root directory and create an icon folder. Place an SVG file image in this folder, and the icon file name should be icon.svg.
  • Maven Build: Go to the project directory and run terminal. Run mvn clean install to build the project.

How To Use Custom Validators in Mule Application

  • Create a Mule Application: Go to Anypoint Studio and create a Mule application for testing the custom validation.
  • Add Custom Validator Mule Plugin: Go to pom.xml and add the dependency for the custom validator Mule plugin for currency. Make sure you have added the classifier as mule-plugin and the dependency information will come from the Mule SDK validator.
<dependency>
          <groupId>org.shyam</groupId>
          <artifactId>mule-currency-validator</artifactId>
          <version>1.0.1</version>
          <classifier>mule-plugin</classifier>
        </dependency>

  • HTTP Listener: Add an HTTP listener with default configuration in the testing Mule application.
  • Currency Validation: Drag the currency validation and pass the currency. We are reading the currency from query params.
    <currency-validator:is-valid-currency-code doc:name="Is valid currency code" doc:id="e9b8a803-ef0f-437e-b337-e33eb5cfc614" currencyCode="#[attributes.queryParams.currencyCode]"/>

  • Failed Validation Execution: Below are the error logs from the Mule application for invalid currency.
ERROR 2022-06-12 22:52:37,285 [[MuleRuntime].uber.01: [helloworldtesting].currencyValidatoFlow.CPU_LITE @398d10a9] [processor: currencyValidatoFlow/processors/0; event: 4132b1b0-ea74-11ec-bf77-f84d89960c47] org.mule.runtime.core.internal.exception.OnErrorPropagateHandler: 
********************************************************************************
Message               : Invalid currency : RUPEE
Element               : currencyValidatoFlow/processors/0 @ helloworldtesting:helloworldtesting.xml:48 (Is valid currency code)
Element DSL           : <currency-validator:is-valid-currency-code doc:name="Is valid currency code" doc:id="467879a6-8c4c-49be-93bd-f510a029e842" currencyCode="#[attributes.queryParams.currency]"></currency-validator:is-valid-currency-code>
Error type            : CURRENCY-VALIDATOR:INVALID_CURRENCY_CODE
FlowStack             : at currencyValidatoFlow(currencyValidatoFlow/processors/0 @ helloworldtesting:helloworldtesting.xml:48 (Is valid currency code))

  (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************

  • Curl Command: curl --location --request GET 'localhost:8081/currency?currency=RUPEE'
  • Success Execution: If we pass the correct currency, we will get no validation error and response as currency INR. The curl command is: curl --location --request GET 'localhost:8081/currency?currency=INR'

Github Repository For Mule Custom Validation

https://github.com/shyamrajprasad/mule-currency-validator

Conclusion

Today we have learned how we can develop the Mule custom validation using Mule JAVA SDK. In a future tutorial, I will cover the Mule SDK for the REST API.

.

Leave a Comment