Tuesday, October 8, 2013

EDI to XML using WSO2 ESB - Smooks mediator.

1. What is an EDI file ? 

EDI (Electronic Data Interchange) is a stand way of sharing the business data like orders, invoice, tax, cheques ..etc between business applications.

X12 and Un/EDIFACT are the most commonly used EDI standards.

2. Why we need EDI than paper documents ?

i. Less man hours required to process.
ii. Less user errors (data input and process by computer applications)
iii. Fast business flows.

3. Why we need to transform EDI to XML ?

I) Some business applications can't understand  the EDI formats when they are integrate with the other system.

II) Need  more processing/routing ..etc based on the attributes of the EDI, in that case XML is more readable and widely use standard.

Simple use case using WSO2 ESB.

i. Drop order type EDI file to VFS input directory.
ii. ESB pick the file and send to smooks mediator.
iii. Smooks mediator transform the EDI file to XML format.
iv. Base on the message type sending file to correct endpoints.

For this we need a smooks mapping file for order type EDI file.

You can download the EDI mapping model jar from [1]

[1]http://mvnrepository.com/artifact/org.milyn.edi.unedifact/d97b-mapping/1.4

You can find the ORDER.xml and __modelset_definitions.xml inside the jar.

Steps to setup.

1. Download the latest WSO2 ESB version from product download site. http://wso2.com/products/enterprise-service-bus/

2. Enable the VFS transport in axis2.xml file. - Un-comment the following two lines.

<transportReceiver name="vfs" class="org.apache.synapse.transport.vfs.VFSTransportListener"/>
<ransportSender name="vfs" class="org.apache.synapse.transport.vfs.VFSTransportSender"/>

3.Copy the content of ORDER.xml to <ESB_HOME>/repository/samples/resources/smooks/xml-mapping-order.xml .

4. Copy  __modelset_definitions.xml to  <ESB_HOME>/repository/samples/resources/smooks.

WSO2 developer studio is our development platform which is going to use for creating the ESB artifacts. http://wso2.com/more-downloads/developer-studio/

5. Create a ESB config project and draw a simple mediation flow.

6. Create a new local entry to add the smooks configuration file.

<localEntry xmlns="http://ws.apache.org/ns/synapse" key="smooks-config">
   <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">
      <resource-config selector="org.xml.sax.driver">
         <resource>org.milyn.smooks.edi.EDIReader</resource>
         <param name="mapping-model">repository/samples/resources/smooks/xml-mapping-order.xml</param>
      </resource-config>
   </smooks-resource-list>
   <description/>
</localEntry>

7. Create a ProxyService  add  mediation flow.

<proxy xmlns="http://ws.apache.org/ns/synapse" name="EDITransformProxy" transports="http https vfs" startOnLoad="true" trace="disable">
    <target>
        <inSequence>
            <smooks config-key="smooks-config">
                <input type="text"/>
                <output type="xml"/>
            </smooks>
            <log level="full"/>
            <property xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" name="MESSAGE_TYPE" expression="name(//soapenv:Body/*)" scope="default" type="STRING"/>
            <switch source="/default/xpath">
                <case regex="ORDERS">
                    <send>
                        <endpoint>
                            <address uri="http://www.example.org/service/order"/>
                        </endpoint>
                    </send>
                </case>
                <case regex="INVOICE">
                    <send>
                        <endpoint>
                            <address uri="http://www.example.org/service/invoice"/>
                        </endpoint>
                    </send>
                </case>
                <default>
                    <send>
                        <endpoint>
                            <address uri="http://www.example.org/default"/>
                        </endpoint>
                    </send>
                </default>
            </switch>
        </inSequence>
        <outSequence/>
        <faultSequence/>
    </target>
    <parameter name="transport.vfs.ActionAfterProcess">MOVE</parameter>
    <parameter name="transport.PollInterval">5</parameter>
    <parameter name="transport.vfs.MoveAfterProcess">C:\wso2\original</parameter>
    <parameter name="transport.vfs.FileURI">C:\wso2\in</parameter>
    <parameter name="transport.vfs.MoveAfterFailure">C:\wso2\failed</parameter>
    <parameter name="transport.vfs.FileNamePattern">.*.edi</parameter>
    <parameter name="transport.vfs.ContentType">text/plain</parameter>
    <parameter name="transport.vfs.ActionAfterFailure">MOVE</parameter>
</proxy>


8. Add new Carbon Application project and include the ESB-Cofig artifact.
9. Build your Capp project.
10. Start the ESB server and Deploy the Capp file.
11. Create sample file test.edi using the following content, and copy that file to VFS “in” directory.

BGM+380+342459+9'
DTM+3:20060515:102'
RFF+ON:521052'
NAD+BY+792820524::16++CUMMINS MID-RANGE ENGINE PLANT'
NAD+SE+005435656::16++GENERAL WIDGET COMPANY'
CUX+1:USD'
LIN+1++157870:IN'
IMD+F++:::WIDGET'
QTY+47:1020:EA'
ALI+US'
MOA+203:1202.58'
PRI+INV:1.179'
LIN+2++157871:IN'
IMD+F++:::DIFFERENT WIDGET'
QTY+47:20:EA'
ALI+JP'
MOA+203:410'
PRI+INV:20.5'
UNS+S'
MOA+39:2137.58'
ALC+C+ABG'
MOA+8:525'

12. Out put in console.

<ORDERS>
    <Beginning_of_message>
        <DOCUMENT_MESSAGE_NAME>
            <Document_name_code>380</Document_name_code>
        </DOCUMENT_MESSAGE_NAME>
        <DOCUMENT_MESSAGE_IDENTIFICATION>
            <Document_identifier>342459</Document_identifier>
        </DOCUMENT_MESSAGE_IDENTIFICATION>
        <Message_function_code>9</Message_function_code>
    </Beginning_of_message>
    <Date_time_period>
        <DATE_TIME_PERIOD>
            <Date_or_time_or_period_function_code_qualifier>3</Date_or_time_or_period_function_code_qualifier>
            <Date_or_time_or_period_text>20060515</Date_or_time_or_period_text>
            <Date_or_time_or_period_format_code>102</Date_or_time_or_period_format_code>
        </DATE_TIME_PERIOD>
    </Date_time_period>
    <Segment_group_1>
        <Reference>
            <REFERENCE>
                <Reference_code_qualifier>ON</Reference_code_qualifier>
                <Reference_identifier>521052</Reference_identifier>
            </REFERENCE>
        </Reference>
    </Segment_group_1>
    <Segment_group_2>
        <Name_and_address>
            <Party_function_code_qualifier>BY</Party_function_code_qualifier>
            <PARTY_IDENTIFICATION_DETAILS>
                <Party_identifier>792820524</Party_identifier>
                <Code_list_identification_code/>
                <Code_list_responsible_agency_code>16</Code_list_responsible_agency_code>
            </PARTY_IDENTIFICATION_DETAILS>
            <NAME_AND_ADDRESS>
            </NAME_AND_ADDRESS>
            <PARTY_NAME>
                <Party_name_-_-1>CUMMINS MID-RANGE ENGINE PLANT</Party_name_-_-1>
            </PARTY_NAME>
        </Name_and_address>
    </Segment_group_2>
    <Segment_group_2>
        <Name_and_address>
            <Party_function_code_qualifier>SE</Party_function_code_qualifier>
            <PARTY_IDENTIFICATION_DETAILS>
                <Party_identifier>005435656</Party_identifier>
                <Code_list_identification_code/>
                <Code_list_responsible_agency_code>16</Code_list_responsible_agency_code>
            </PARTY_IDENTIFICATION_DETAILS>
            <NAME_AND_ADDRESS>
            </NAME_AND_ADDRESS>
            <PARTY_NAME>
                <Party_name_-_-1>GENERAL WIDGET COMPANY</Party_name_-_-1>
            </PARTY_NAME>
        </Name_and_address>
    </Segment_group_2>
    <Segment_group_7>
        <Currencies>
            <CURRENCY_DETAILS_-_-1>
                <Currency_usage_code_qualifier>1</Currency_usage_code_qualifier>
                <Currency_identification_code>USD</Currency_identification_code>
            </CURRENCY_DETAILS_-_-1>
        </Currencies>
    </Segment_group_7>
    <Segment_group_28>
        <Line_item>
            <Line_item_identifier>1</Line_item_identifier>
            <Action_request_notification_description_code/>
            <ITEM_NUMBER_IDENTIFICATION>
                <Item_identifier>157870</Item_identifier>
                <Item_type_identification_code>IN</Item_type_identification_code>
            </ITEM_NUMBER_IDENTIFICATION>
        </Line_item>
        <Item_description>
            <Description_format_code>F</Description_format_code>
            <ITEM_CHARACTERISTIC>
            </ITEM_CHARACTERISTIC>
            <ITEM_DESCRIPTION>
                <Item_description_code/>
                <Code_list_identification_code/>
                <Code_list_responsible_agency_code/>
                <Item_description_-_-1>WIDGET</Item_description_-_-1>
            </ITEM_DESCRIPTION>
        </Item_description>
        <Quantity>
            <QUANTITY_DETAILS>
                <Quantity_type_code_qualifier>47</Quantity_type_code_qualifier>
                <Quantity>1020</Quantity>
                <Measurement_unit_code>EA</Measurement_unit_code>
            </QUANTITY_DETAILS>
        </Quantity>
        <Additional_information>
            <Country_of_origin_name_code>US</Country_of_origin_name_code>
        </Additional_information>
        <Monetary_amount>
            <MONETARY_AMOUNT>
                <Monetary_amount_type_code_qualifier>203</Monetary_amount_type_code_qualifier>
                <Monetary_amount>1202.58</Monetary_amount>
            </MONETARY_AMOUNT>
        </Monetary_amount>
        <Segment_group_32>
            <Price_details>
                <PRICE_INFORMATION>
                    <Price_code_qualifier>INV</Price_code_qualifier>
                    <Price_amount>1.179</Price_amount>
                </PRICE_INFORMATION>
            </Price_details>
        </Segment_group_32>
    </Segment_group_28>
    <Segment_group_28>
        <Line_item>
            <Line_item_identifier>2</Line_item_identifier>
            <Action_request_notification_description_code/>
            <ITEM_NUMBER_IDENTIFICATION>
                <Item_identifier>157871</Item_identifier>
                <Item_type_identification_code>IN</Item_type_identification_code>
            </ITEM_NUMBER_IDENTIFICATION>
        </Line_item>
        <Item_description>
            <Description_format_code>F</Description_format_code>
            <ITEM_CHARACTERISTIC>
            </ITEM_CHARACTERISTIC>
            <ITEM_DESCRIPTION>
                <Item_description_code/>
                <Code_list_identification_code/>
                <Code_list_responsible_agency_code/>
                <Item_description_-_-1>DIFFERENT WIDGET</Item_description_-_-1>
            </ITEM_DESCRIPTION>
        </Item_description>
        <Quantity>
            <QUANTITY_DETAILS>
                <Quantity_type_code_qualifier>47</Quantity_type_code_qualifier>
                <Quantity>20</Quantity>
                <Measurement_unit_code>EA</Measurement_unit_code>
            </QUANTITY_DETAILS>
        </Quantity>
        <Additional_information>
            <Country_of_origin_name_code>JP</Country_of_origin_name_code>
        </Additional_information>
        <Monetary_amount>
            <MONETARY_AMOUNT>
                <Monetary_amount_type_code_qualifier>203</Monetary_amount_type_code_qualifier>
                <Monetary_amount>410</Monetary_amount>
            </MONETARY_AMOUNT>
        </Monetary_amount>
        <Segment_group_32>
            <Price_details>
                <PRICE_INFORMATION>
                    <Price_code_qualifier>INV</Price_code_qualifier>
                    <Price_amount>20.5</Price_amount>
                </PRICE_INFORMATION>
            </Price_details>
        </Segment_group_32>
    </Segment_group_28>
    <Section_control>
        <SECTION_IDENTIFICATION>S</SECTION_IDENTIFICATION>
    </Section_control>
    <Monetary_amount>
        <MONETARY_AMOUNT>
            <Monetary_amount_type_code_qualifier>39</Monetary_amount_type_code_qualifier>
            <Monetary_amount>2137.58</Monetary_amount>
        </MONETARY_AMOUNT>
    </Monetary_amount>
    <Segment_group_60>
        <Allowance_or_charge>
            <Allowance_or_charge_code_qualifier>C</Allowance_or_charge_code_qualifier>
            <ALLOWANCE_CHARGE_INFORMATION>
                <Allowance_or_charge_identifier>ABG</Allowance_or_charge_identifier>
            </ALLOWANCE_CHARGE_INFORMATION>
        </Allowance_or_charge>
        <Monetary_amount>
            <MONETARY_AMOUNT>
                <Monetary_amount_type_code_qualifier>8</Monetary_amount_type_code_qualifier>
                <Monetary_amount>525</Monetary_amount>
            </MONETARY_AMOUNT>
        </Monetary_amount>
    </Segment_group_60>
</ORDERS>