Introduction
Electronic Data Interchange (EDI) is the computer-to-computer exchange of business documents in a standard electronic format between business partners. EDI standards have been the dominant format for e-commerce data exchange for decades, and give organizations a fast and accurate method of transmitting transaction data. EDI comes even before the prevalent integrated business technologies like ERP, CRM, database formats, and many other supply chain enabling technologies, making data mapping and transformation an important component of any EDI implementation. This article describes the step by step process to achieve such transformations in Mule using smooks library.
Pre-requisites
The reader of this article needs to possess basic knowledge on EDI document standards, smooks library.
Steps in detail
1. We shall use the following edi sample as an input for the transformation process:
HDR*1*0*59.97*64.92*4.95*Wed Jan 15 13:45:28 EST 2015
CUS*user1*Harry^Fletcher*SD
ORD*1*1*364*Demo user*29.98
ORD*2*1*299*Pulp Fiction*29.99
2. Create a new mule project and name it as “EDITransformation”
3. Add following dependency to the project pom.xml:
<dependency>
<groupId>org.milyn</groupId>
<artifactId>milyn-smooks-edi</artifactId>
<version>1.5.1</version>
</dependency>
4. Define the mapping model. In this case, we use the order mapping as shown below. Name this file as edi-to-xml-order-mapping.xml.
<medi:edimap xmlns:medi="http://www.milyn.org/schema/edi-message-mapping-1.2.xsd">
<medi:description name="Product Order" version="1.0" />
<medi:delimiters segment=" " field="*" component="^" sub-component="~" />
<medi:segments xmltag="Order">
<medi:segment segcode="HDR" xmltag="header">
<medi:field xmltag="order-id" />
<medi:field xmltag="status-code" />
<medi:field xmltag="net-amount" />
<medi:field xmltag="total-amount" />
<medi:field xmltag="tax" />
<medi:field xmltag="date" />
</medi:segment>
<medi:segment segcode="CUS" xmltag="customer-details">
<medi:field xmltag="username" />
<medi:field xmltag="name">
<medi:component xmltag="firstname" />
<medi:component xmltag="lastname" />
</medi:field>
<medi:field xmltag="state" />
</medi:segment>
<medi:segment segcode="ORD" xmltag="order-item" maxOccurs="-1">
<medi:field xmltag="position" />
<medi:field xmltag="quantity" />
<medi:field xmltag="product-id" />
<medi:field xmltag="title" />
<medi:field xmltag="price" />
</medi:segment>
</medi:segments>
</medi:edimap>
5. Now refer this mapping from your smooks-config.xml.
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd"
xmlns:edi="http://www.milyn.org/xsd/smooks/edi-1.2.xsd">
<edi:reader mappingModel="edi-to-xml-order-mapping.xml" validate="false" />
</smooks-resource-list>
Alternatively out of the box mapping models can be used. For example, a d98b message set can be parsed using following configuration.
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd"
xmlns:unedifact="http://www.milyn.org/xsd/smooks/unedifact-1.4.xsd">
<!-
Configure the EDI Reader to parse the UN/EDIFACT d98b message set. Reader configured with the a URN, which is based on the maven repo artifact group:name:version info...
-->
<unedifact:reader mappingModel="urn:org.milyn.edi.unedifact:d98b-mapping:*" />
</smooks-resource-list>
6. Make sure the files created in 4, 5 are on classpath.
7.Create a custom java transformer by extending
org.mule.transformer.AbstractMessageTransformer.
8. Define a method named transformEdi as below:
protected String transformEdi (MuleMessage message) {
Smooks smooks = null;
try {
StringResult result = new StringResult();
//Instantiate Smooks with the config defined in step5 ...
smooks = new Smooks("smooks-config.xml");
smooks.filterSource(new StreamSource(new ByteArrayInputStream(
message.getPayloadAsBytes())), result);
return result.getResult();
} catch (Exception e) {
//handle exception
} finally {
if (smooks != null) {
smooks.close();
}
}
return null;
}
9. Now override the transformMessage method of the custom transformer as below:
@Override
public Object transformMessage(MuleMessage message, String outputEncoding)
throws TransformerException {
String messageOut;
try {
messageOut = transformEdi(message);
message.setPayload(messageOut);
return message;
} catch (SmooksException e) {
//handle exception
} catch (IOException e) {
//handle exception
} catch (SAXException e) {
//handle exception
}
return null;
}
10. Define mule config file to use this java transformer. The sample below shows a file inbo und endpoint to read the edi file followed by a custom java transformer which would refe r to the transformer code as defined above and then followed by a logger to log the outu put XML.
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:file="http://www.mulesoft.org/schema/mule/file"
xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans" version="EE-3.5.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/file http://www.mulesoft.org/schema/mule/file/current/mule-file.xsd">
<flow name="editransformationFlow1" doc:name="editransformationFlow1">
<file:inbound-endpoint path="C:ediinput" responseTimeout="10000" doc:name="File"/>
<component class="com.mymule.edi.transformers.EdifactTransformer" doc:name="Java"/>
<logger message="EDI CONVERTED OUTPUT: #[payload]" level="INFO"doc:name="Logger"/>
</flow>
</mule>
11. Place the edi input file in the file location defined. Upon successful execution, the output of your mule flow will be :
References
http://www.mulesoft.org/documentation/display/current/Creating+Custom+Transformers
http://www.smooks.org/mediawiki/index.php?title=Main_Page
http://en.wikipedia.org/wiki/Electronic_data_interchange
If you would like to find out more about how Systems Integration could help you make the most out of your current infrastructure while enabling you to open your digital horizons, do give us a call at +44 (0)203 475 7980 or email us at Salesforce@coforge.com
Other useful links:
API Recipes with MuleSoft Anypoint Platform