Message Transformation on JBossESB is supported by the SmooksTransformer component. This is an ESB Action component that allows the Smooks Data Transformation/Processing Framework to be plugged into an ESB Action Processing Pipeline.
A wide range of source (XML, CSV, EDI etc) and target (XML, Java, CSV, EDI etc) data formats are supported by the SmooksTransformer component. A wide range of Transformation Technologies are also supported, all within a single framework. See Smooks for more details.
Samples & Tutorials
A number of Transformation Quickstart samples accompany the JBossESB distribution. Check out the "transform_" Quickstarts.
A number of tutorials are available online on the Smooks website. Any of these samples can be easily ported to JBossESB.
Smooks Testimonials. Real-life use cases.
The basic configuration of this action simply takes a "resource-config" property that references a Smooks configuration file. The resource-config property value is any valid URI based resource, as defined by the URIResourceLocator class.
<action name="transform" class="org.jboss.soa.esb.actions.converters.SmooksTransformer"> <property name="resource-config" value="/smooks-config.xml" ></property> </action>
This action uses the MessagePayloadProxy to access the message payload. This means that, by default, it will get the payload to be processed from the Message.Body.DEFAULT_LOCATION location and will set the processed message back on the Message.Body.DEFAULT_LOCATION location. Of course the MessagePayloadProxy supports overriding this via the "get-payload-location" and "set-payload-location" action properties.
Java Output Configuration
As stated above, this action supports source (XML, CSV, EDI etc) to Java object transformation/binding. See the "Transform_XML2POJO" quickstarts for examples of this and also check out the Smooks Tutorials.
The constructed Java object model(s) can be used as part of a model driven transform, or can
simply be used by other ESB action instances that follow the SmooksTransformer in an action
Such Java object graphs are available to subsequent pipeline action instances because they are attached to the ESB Message output by this action and input to the following action(s). They are bound to the Message instance Body (Message.getBody().add(...)) under a key based directly on the objects "beanId" as defined in the Smooks Javabean config. This means that the objects are available through the ESB Message Body by performing Body.get(beanId) calls.
The full Java object Map can also be made available on the output message by adding a "java-output-location" property e.g.
<action name="transform" class="org.jboss.soa.esb.actions.converters.SmooksTransformer"> <property name="resource-config" value="/smooks-config.xml" ></property> <property name="java-output-location" value="order-message-objects-map" ></property> </action>
Or, shorthand for binding the map to the "Default Message Body Location":
<action name="transform" class="org.jboss.soa.esb.actions.converters.SmooksTransformer"> <property name="resource-config" value="/smooks-config.xml" ></property> <property name="java-output-location" value="$default" ></property> </action>
Profile Based Transformation
In the following example we have messages being exchanged between 3 different Sources and 1 Target. The ESB needs to transform the messages supplied by each of the 3 Sources (supplied in different formats) into Java Objects before supplying them to the "Target" Service. Basically, we've 3 possible transformations for messages being exchanged to the Target. We'll call these transformations "source1", "source2" and "source3" respectfully.
From an ESB configuration perspective, we have a single Service configuration for the "Target" Service. The configuration might look something like the following.
<service category="ServiceCat" name="TargetService" description="Target Service"> <listeners> <!-- Message listners for getting the message into the action pipeline... --> <jms-listener name="Gateway-Listener" busidref="quickstartGwChannel" is-gateway="true"></jms-listener> <jms-listener name="Service-Listener" busidref="quickstartEsbChannel"></jms-listener> </listeners> <actions> <!-- A SmooksTransform action to transform the source message into the Target Java Object(s) --> <action name="transform" class="org.jboss.soa.esb.actions.converters.SmooksTransformer"> <property name="resource-config" value="/smooks-config.xml"></property> </action> <!-- An action to process the Java Object(s) --> <action name="process" class="com.acme.JavaProcessor" ></action> </actions> </service>
As can be seen by the SmooksTransformer configuration, we only define a single transformation configuration file called "/smooks-config.xml". We need to define 3 different transformation, one for each source. This is done using a Smooks Message Profiling.
Basically, we define the 3 separate transformations in 3 separate Smooks configuration files (from_source1.xml, from_source2.xml and from_source3.xml) and them into the top-level smooks-config.xml. In each of these configuration files we specify the "default-target-profile" for that configuration set e.g.
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.0.xsd" default-target-profile="from:source1"> <!-- Source1 to Target Java message transformation resource configurations... --> </smooks-resource-list>
The top-level smooks-config.xml looks as follows:
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.0.xsd"> <import file="classpath:/from_source1.xml" ></import> <import file="classpath:/from_source2.xml" ></import> <import file="classpath:/from_source3.xml" ></import> </smooks-resource-list>
So what this does (effectively) is to load a single SmooksTransformer instance with 3 different transformations, each transformation defined under it's own unique "profile" name. There are actually more uses for message profiling than this, but this view of profiling works fine for this example.
In order for the SmooksTransfromer to know which of the 3 transformations needs to be applied on a given message, the message (ESB Message) needs to have it's "from" property set before the message flows into the SmooksTransformer. This can be done anywhere that makes sense - at the Source itself (source1, source2 etc), or in a content based action that precedes the SmooksTransformer. See details of the transform_XML2POJO2 quickstart (below).
JBossESB also supports profiles additional to the "from" profile, namely "from-type", "to" and "to-type". These can be used in combination, leading to more intricate exchange based transforms - n possible inputs to n possible outputs, sharing profile sets etc. See the "profiling" tutorial on the Smooks website.
The basic scenario outlined above is implemented as a quickstart within the JBossESB distribution. The quickstart is named "[transform_XML2POJO2|http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/samples/quickstarts/transform_XML2POJO2/]". In this quickstart there are 2 message sources. It utilises a Groovy script on the action pipeline to detect and set the "from" profile for the incoming message.
jboss-esb.xml: JBossESB Configuration File.
smooks-config.xml: Top Level Transformation Configuration.
from-dvdstore.xml: DVD Store message Transformations Configuration - imported into top-level smooks-config.xml (notice the profile configuration?). Designed to transform a DVD Store message into Java Objects.
from-petstore.xml: Pet Store message Transformations Configuration - imported into top-level smooks-config.xml (notice the profile configuration?). Designed to transform a Pet Store message into Java Objects (the same Java object model).
check-origin.groovy: Simple Groovy script for checking the origin of the message based on it's content.