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 classCurrencyValidatorOperations
with@Validator
, but 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 aErrorTypeProvider
that says that the only error the method can throw is of typeCURRENCY-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 asmule-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.