Skip to Content
Technical Articles

EIPinCPI – Message Translator

Previous – Message Broker | Index | Next – Envelope Wrapper

This week, we’ll begin studying Message Transformation patterns and the first one is known as Message Translator.

When do I use this pattern?

I like to think of middleware software as a translator similar to a language translator. A language translator can translate one language into another. For example, word Hello in English is Hola in Spanish or Namaskāra in Marathi or Kon’nichiwa in Japanese.

Similarly, if system A speaks in XML and system B speaks in JSON, middleware software can translate. If system A calls unique identification of a customer as CustomerID and system B calls it KUNNR, middleware software can translate.

When two systems have different ways of representing the data such as JSON, XML, etc. or when two systems have a different data model to represent the same entity, Message Translator pattern can be applied.

Message Translator in CPI

In CPI, we can tackle both kinds of translations. Converters can be used to translate messages from one format into another. Whereas, Mappings can be used to translate messages from one data model to another.

Converter

In essence, CPI supports translating 3 formats: XML, JSON, and CSV. There are 4 converters supported out of the box:

How would you convert JSON to CSV and vice versa? Simply combine the two converters. For converting a message from JSON to CSV, use JSON to XML Converter first and then use XML to CSV Converter. For converting the message from CSV to JSON, use CSV to XML Converter first and then use XML to JSON Converter.

Let’s look at the examples for each of these converters below. I’ll show simple examples to get started. To learn more and dive deep, please go through Help Documentation on each converter linked above or below in the References/Further Readings section.

JSON to XML Converter

Integration Flow

The Integration Flow used for this exercise is simple. It uses the Command Message pattern to Get the Customer ‘ALFKI’ in JSON format using HTTP Receiver Adapter, passes the payload through JSON to XML Converter, and logs the output using Groovy Script.

Configuration of HTTP Receiver Adapter
Tab Parameter Value
Connection Address https://services.odata.org/V2/Northwind/Northwind.svc/Customers(‘ALFKI’)
Connection Query $format=json
Connection Method GET
Connection Authentication None
Configuration of JSON to XML Converter
Tab Parameter Value
Processing Use Namespace Mapping Unchecked
Processing JSON Prefix Separator Colon (:)
Processing Add XML Root Element Unchecked

Input to Converter

{
    "d": {
        "__metadata": {
            "uri": "https://services.odata.org/V2/Northwind/Northwind.svc/Customers('ALFKI')",
            "type": "NorthwindModel.Customer"
        },
        "CustomerID": "ALFKI",
        "CompanyName": "Alfreds Futterkiste",
        "ContactName": "Maria Anders",
        "ContactTitle": "Sales Representative",
        "Address": "Obere Str. 57",
        "City": "Berlin",
        "Region": null,
        "PostalCode": "12209",
        "Country": "Germany",
        "Phone": "030-0074321",
        "Fax": "030-0076545",
        "Orders": {
            "__deferred": {
                "uri": "https://services.odata.org/V2/Northwind/Northwind.svc/Customers('ALFKI')/Orders"
            }
        },
        "CustomerDemographics": {
            "__deferred": {
                "uri": "https://services.odata.org/V2/Northwind/Northwind.svc/Customers('ALFKI')/CustomerDemographics"
            }
        }
    }
}

Output from Converter

<d>
    <__metadata>
        <uri>https://services.odata.org/V2/Northwind/Northwind.svc/Customers('ALFKI')</uri>
        <type>NorthwindModel.Customer</type>
    </__metadata>
    <CustomerID>ALFKI</CustomerID>
    <CompanyName>Alfreds Futterkiste</CompanyName>
    <ContactName>Maria Anders</ContactName>
    <ContactTitle>Sales Representative</ContactTitle>
    <Address>Obere Str. 57</Address>
    <City>Berlin</City>
    <Region/>
    <PostalCode>12209</PostalCode>
    <Country>Germany</Country>
    <Phone>030-0074321</Phone>
    <Fax>030-0076545</Fax>
    <Orders>
        <__deferred>
            <uri>https://services.odata.org/V2/Northwind/Northwind.svc/Customers('ALFKI')/Orders</uri>
        </__deferred>
    </Orders>
    <CustomerDemographics>
        <__deferred>
            <uri>https://services.odata.org/V2/Northwind/Northwind.svc/Customers('ALFKI')/CustomerDemographics</uri>
        </__deferred>
    </CustomerDemographics>
</d>

CSV to XML Converter

Integration Flow

The Integration Flow uses the Content Modifier to set the CSV input, passes the payload through CSV to XML Converter, and logs the output using Groovy Script.

Configuration of CSV to XML Converter
Tab Parameter Value
Processing XML Schema /xsd/Customers.xsd
Processing Path to Target Element in XSD /Customers/Customer
Processing Record Marker in CSV
Processing Field Separator in CSV Comma(,)
Processing Exclude First Line Header Checked
Processing Configure CSV Headers to match CSV Fields Sequence

Input to Converter

CompanyName,Address,Phone,Region,PostalCode,Country,CustomerID,City,Fax,ContactName,ContactTitle
Alfreds Futterkiste,Obere Str. 57,030-0074321,,12209,Germany,ALFKI,Berlin,030-0076545,Maria Anders,Sales Representative

Output from Converter

<Customers>
    <Customer>
        <CompanyName>Alfreds Futterkiste</CompanyName>
        <Address>Obere Str. 57</Address>
        <Phone>030-0074321</Phone>
        <Region/>
        <PostalCode>12209</PostalCode>
        <Country>Germany</Country>
        <CustomerID>ALFKI</CustomerID>
        <City>Berlin</City>
        <Fax>030-0076545</Fax>
        <ContactName>Maria Anders</ContactName>
        <ContactTitle>Sales Representative</ContactTitle>
    </Customer>
</Customers>

XML to CSV Converter

Integration Flow

Similar to Integration flow used for JSON to XML Converter, this Integration Flow uses the Command Message pattern to Get the Customer ‘ALFKI’ in XML format using OData Receiver Adapter, passes the payload through XML to CSV Converter, and logs the output using Groovy Script.

Configuration of OData Receiver Adapter
Tab Parameter Value
Connection Address https://services.odata.org/V2/Northwind/Northwind.svc
Connection CSRF Protected Unchecked
Processing Operation Details Read (GET)
Processing Resource Path Customers(‘ALFKI’)
Configuration of XML to CSV Converter
Tab Parameter Value
Processing Path to Source Element in XSD /Customers/Customer
Processing Field Separator in CSV Comma (,)
Processing Include Field Name as Headers Checked
Processing Include Parent Element Unchecked
Processing Include Attribute Values Unchecked

Input to Converter

<Customers>
    <Customer>
        <CompanyName>Alfreds Futterkiste</CompanyName>
        <Address>Obere Str. 57</Address>
        <Phone>030-0074321</Phone>
        <Region/>
        <PostalCode>12209</PostalCode>
        <Country>Germany</Country>
        <CustomerID>ALFKI</CustomerID>
        <City>Berlin</City>
        <Fax>030-0076545</Fax>
        <ContactName>Maria Anders</ContactName>
        <ContactTitle>Sales Representative</ContactTitle>
    </Customer>
</Customers>

Output from Converter

CompanyName,Address,Phone,Region,PostalCode,Country,CustomerID,City,Fax,ContactName,ContactTitle
Alfreds Futterkiste,Obere Str. 57,030-0074321,,12209,Germany,ALFKI,Berlin,030-0076545,Maria Anders,Sales Representative

XML to JSON Converter

Integration Flow

Similar to Integration flow used for JSON to XML Converter, this Integration Flow uses the Command Message pattern to Get the Customer ‘ALFKI’ in XML format using OData Receiver Adapter, passes the payload through XML to JSON Converter, and logs the output using Groovy Script.

Configuration of OData Receiver Adapter
Tab Parameter Value
Connection Address https://services.odata.org/V2/Northwind/Northwind.svc
Connection CSRF Protected Unchecked
Processing Operation Details Read (GET)
Processing Resource Path Customers(‘ALFKI’)
Configuration of XML to JSON Converter
Tab Parameter Value
Processing Use Namespace Mapping Unchecked
Processing JSON Prefix Separator Colon (:)
Processing JSON Output Encoding From Header or Property
Processing Suppress JSON Root Element Unchecked
Processing Streaming Unchecked

Input to Converter

<Customers>
    <Customer>
        <CompanyName>Alfreds Futterkiste</CompanyName>
        <Address>Obere Str. 57</Address>
        <Phone>030-0074321</Phone>
        <Region/>
        <PostalCode>12209</PostalCode>
        <Country>Germany</Country>
        <CustomerID>ALFKI</CustomerID>
        <City>Berlin</City>
        <Fax>030-0076545</Fax>
        <ContactName>Maria Anders</ContactName>
        <ContactTitle>Sales Representative</ContactTitle>
    </Customer>
</Customers>

Output from Converter

{
    "Customers": {
        "Customer": {
            "CompanyName": "Alfreds Futterkiste",
            "Address": "Obere Str. 57",
            "Phone": "030-0074321",
            "Region": "",
            "PostalCode": "12209",
            "Country": "Germany",
            "CustomerID": "ALFKI",
            "City": "Berlin",
            "Fax": "030-0076545",
            "ContactName": "Maria Anders",
            "ContactTitle": "Sales Representative"
        }
    }
}

Mapping

CPI supports Message Mapping and XSLT Mapping. Message Mapping uses a visual editor to map the value of a node from a source data model to target data model. Whereas, XSLT mapping, as the name suggests, uses XSLT stylesheets to transform a source XML document into the target XML document.

Message Mapping

A sample message mapping looks like below:

XSLT Mapping

An example of an XSL Stylesheet is like below:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:template match="/">
	    <Customers>
	        <xsl:for-each select="/DEBMAS07/IDOC">
	            <Customer>
	                <CompanyName><xsl:value-of select="E1KNA1M/NAME1" /></CompanyName>
	                <Address>N/A</Address>
	                <Phone><xsl:value-of select="E1KNA1M/TELF1" /></Phone>
	                <Region><xsl:value-of select="E1KNA1M/REGIO" /></Region>
	                <PostalCode><xsl:value-of select="E1KNA1M/PSTLZ" /></PostalCode>
	                <Country><xsl:value-of select="E1KNA1M/LAND1" /></Country>
	                <CustomerID><xsl:value-of select="E1KNA1M/KUNNR" /></CustomerID>
	                <City><xsl:value-of select="E1KNA1M/ORT01" /></City>
	                <Fax><xsl:value-of select="E1KNA1M/TELFX" /></Fax>
	                <ContactName><xsl:value-of select="E1KNA1M/E1KNA11/PSON1" /></ContactName>
	                <ContactTitle><xsl:value-of select="E1KNA1M/E1KNA11/PSOTL" /></ContactTitle>
	            </Customer>
	        </xsl:for-each>
	    </Customers>
	</xsl:template>
</xsl:stylesheet>

Example

Input

<?xml version="1.0" encoding="UTF-8"?>
<DEBMAS07>
	<IDOC BEGIN="1">
		<EDI_DC40 SEGMENT="1">
			<TABNAM>EDI_DC40</TABNAM>
			<DIRECT>1</DIRECT>
			<IDOCTYP>DEBMAS07</IDOCTYP>
			<SNDPOR>SNDPOR</SNDPOR>
			<SNDPRT>SNDPRT</SNDPRT>
			<SNDPRN>SNDPRN</SNDPRN>
			<RCVPOR>RCVPOR</RCVPOR>
			<RCVPRN>RCVPRN</RCVPRN>
		</EDI_DC40>
		<E1KNA1M SEGMENT="1">
			<KUNNR>ALFKI</KUNNR>
			<LAND1>DE</LAND1>
			<NAME1>Alfreds Futterkiste</NAME1>
			<ORT01>Berlin</ORT01>
			<PSTLZ>12209</PSTLZ>
			<REGIO></REGIO>
			<TELF1>030-0074321</TELF1>
			<TELFX>030-0076545</TELFX>
			<E1KNA11>
				<PSON1>Maria Anders</PSON1>
				<PSOTL>Sales Representative</PSOTL>
			</E1KNA11>
		</E1KNA1M>
	</IDOC>
</DEBMAS07>

Please note that the above is simply a created example and is not an actual IDoc XML created from an ECC system.

Output

<Customers>
    <Customer>
        <CompanyName>Alfreds Futterkiste</CompanyName>
        <Address>N/A</Address>
        <Phone>030-0074321</Phone>
        <Region/>
        <PostalCode>12209</PostalCode>
        <Country>DE</Country>
        <CustomerID>ALFKI</CustomerID>
        <City>Berlin</City>
        <Fax>030-0076545</Fax>
        <ContactName>Maria Anders</ContactName>
        <ContactTitle>Sales Representative</ContactTitle>
    </Customer>
</Customers>

Daniel has listed the advantages of using XSLT mappings in his blog I *heart* XSLT mappings.

Groovy Mapping

Groovy Mapping is a way of using Groovy Script to transform source payload into target payload. Eng Swee argues that Groovy Mappings are a way to go for mapping in his blog I *heart* Groovy mapping.

Which kind of mapping to use and when?

For understanding Pros and Cons of each type of mappings offered by CPI, read Morten‘s blog Cloud Integration mapping: Your options explained and compared.

Conclusion

Message Translator pattern is applied when two systems use a different format of representing data or different schema to represent the same entity.

References/Further Readings

Hope this helps,
Bala

Previous – Message Broker | Index | Next – Envelope Wrapper

1 Comment
You must be Logged on to comment or reply to a post.