john.demic on Wednesday, November 30, 2011

Implementing Custom Validation with DevKit


Validating data can be easy with Mule if your message payloads are in certain formats.  XML payloads, for instance, can be verified for correctness via XML schema or XPath filters. Payload type filters and OGNL expression evaluation can go a long way in asserting your POJO payloads are correct.
Payloads with less structure, like Map or JSON data, are a little bit trickier to validate.  This is particularly true on the front-end of web-services where leniency in data format, particularly JSON, can be beneficial.  In these cases a custom Message Processor is usually necessary to filter or sanitise the data.

Creating a Module for Custom Validation

As previously demonstrated Mule is an excellent way to add first-class, configuration-schema aware support for your custom message processors. Let’s implement a Message Processor for Acme Software, Inc that accepts a JSON array on a HTTP endpoint and filters out invalid products from it.

We’ll start by creating a module for our fictional company’s validation extensions using the devkit mvn archetype:

This gives us a Maven project we can use to host our company’s custom validators. These validators will be “first class” citizens in the Mule config file, happily living alongside Mule’s built in message processors.

Implementing the Custom Validator

The mvn command we executed above will have created a ValidatorModule class in the com.acmesoft.integration package. This is where we’ll implement the code for our custom processor. We’ll modify the stub implementation to look as follows:

The “name” attribute on the @Module annotation on the class indicates the namespace of the module. Similarly the “name” attribute on the @Processor annotation defines the name of the XML element in the configuration. The XML configuration for our message processor will subsequently look like this:

Let’s take a look at the implementation of validateProducts. Specifying the @Payload annotation to one of the arguments lets us identify the payload. In this case we’re expecting a List of Maps, which is valid return type of Mule’s json-to-object-transformer.

We’re then iterating over each Map representation of a product and filtering out those that don’t contain “sku” or “product_id” keys. Finally we’re returning the filtered list which will propagate to the next processor in the chain.

Configuring the Custom Validator

Now we’re ready to place the validator in a flow. We’ll accept JSON product data on an HTTP inbound-endpoint, filter out invalid products and pass the filtered results out on an VM outbound-endpoint:

The payload is first being converted from a byte-array to a String. The json-to-object transformer moves the JSON encoded data to a List of Maps format. This is easier to use then the raw JSON for our use case. Our product validator then comes into play, filtering out invalid messages before finally sending the results to the “products.out” VM queue.

Using DevKit with a Mule module has benefits over a “one-off” implementation with a custom- processor element. By using a module we now have the ability to share the validators across multiple Mule projects. The deep integration with the Mule schema allows code completion and documentation in most IDEs, lowering the barrier of entry for others to leverage the custom functionality. Finally the level of effort to accomplish the above is trivialized with the use of DevKit’s annotations.



No related posts.

Interested in 3 days of knowledge sharing, hands-on labs, industry focused sessions, and plenty of networking? Register for the premier integration event, CONNECT London »

One Response to “Implementing Custom Validation with DevKit”

Sougandh March 25th, 2012, 7:56 am

I’ve been trying to create a validator which checks for certain inbound headers and sets my specific outbound header value as true for the next message processor to consume.
How do I do that?

Also, please explain how to set a payload and some message properties in a session so that it can be consumed over an mflow 2 or 3 message processors after being set. Question here is how do we propogate a payload and properties to be consumed in the same mflow later down the mflow lane and not immediately?

Leave a Comment