Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Mule ESB: File Outbound Endpoint With Transformers and Variables

DZone's Guide to

Mule ESB: File Outbound Endpoint With Transformers and Variables

This article shows how we can use inline transformers for writing flow variable content to file in Mule.

· Integration Zone
Free Resource

Modernize your application architectures with microservices and APIs with best practices from this free virtual summit series. Brought to you in partnership with CA Technologies.

In this post, we will see how we can use inline transformers for writing flow variable content to file. At the end of this post, you will know how to achieve these things in Mule:

  1. Generate multiple transformation outputs with DataWeave.
  2. Write flow variable content to file in Mule.
  3. Use inline transformer-ref’s to pre-process payload for file:outbound-endpoint.

Sample Flow

Here is our flow that achieves all of the above objectives:
File_Flow_Variable

<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:file="http://www.mulesoft.org/schema/mule/file"
    xmlns:dw="http://www.mulesoft.org/schema/mule/ee/dw" xmlns:json="http://www.mulesoft.org/schema/mule/json"
    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" 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 http://www.mulesoft.org/schema/mule/ee/dw http://www.mulesoft.org/schema/mule/ee/dw/current/dw.xsd http://www.mulesoft.org/schema/mule/json http://www.mulesoft.org/schema/mule/json/current/mule-json.xsd">
    <expression-transformer expression="#[return flowVars.file2content]"
        name="ExpressionForFile2" doc:name="Expression" />
    <expression-transformer expression="#[return flowVars.file3content]"
        name="Expression" doc:name="Expression" />
    <json:json-to-xml-transformer name="JSON_to_XML"
        doc:name="JSON to XML" />
    <flow name="mule1Flow">
        <file:inbound-endpoint path="input"
            responseTimeout="10000" doc:name="File" />
        <dw:transform-message doc:name="Transform Message">
            <dw:input-payload doc:sample="json.json" />
            <dw:set-payload><![CDATA[%dw 1.0 %output application/json   --- { (payload.file1) }]]></dw:set-payload>
            <dw:set-variable variableName="file2content"><![CDATA[%dw 1.0 %output application/json   --- { (payload.file2) }]]></dw:set-variable>
            <dw:set-variable variableName="file3content"><![CDATA[%dw 1.0 %output application/json   --- { (payload.file3) }]]></dw:set-variable>
        </dw:transform-message>
        <file:outbound-endpoint path="output"
            outputPattern="file1.json" responseTimeout="10000" doc:name="File" />
        <file:outbound-endpoint path="output"
            outputPattern="file2.json" responseTimeout="10000" transformer-refs="ExpressionForFile2"
            doc:name="File" />
        <file:outbound-endpoint path="output"
            outputPattern="file3.xml" responseTimeout="10000" transformer-refs="Expression JSON_to_XML"
            doc:name="File" />
    </flow>
</mule>

DataWeave

In our flow, we have three <dw:set-*> tags.

  1. <dw:set-payload>: The output of this transformation will be set as a payload to the next transformer in the flow.
  2. <dw:set-variable>: We have 2 of such tags. Each tag specifies a unique variableName attribute. The output of this transformation will be set as a flowVariable with a key specified in the variableName attribute. So, now we know how to set DataWeave outputs to a flow variable and generate multiple transformations with a single DataWeave.

File Outbound Endpoint

We have three file outbound endpoints in our flow. Let’s look at each of them:

  • Write file1.json: This is a normal file outbound endpoint that writes the flow payload to file1.json. If we look back to our DataWeave, the first transformation sets the payload content for this endpoint.
  • <file:outbound-endpoint path="output"
    outputPattern="file1.json" responseTimeout="10000" doc:name="File" />
  • Write file2.json: Now this is the file outbound endpoint that writes the content of a flow variable to file2.json. The first snippet below shows a file outbound endpoint defined with additional attribute transformer-refs="ExpressionForFile2" . ExpressionForFile2 is a global expression-transformer as shown in the second snippet. The expression of this transformer is a Mule Expression that returns a flow variable content that we want to write to the file. I have added a simple form here, but you can write any complex expression that resolves to some content. The output of this expression will be the payload for this file outbound endpoint. One important thing to note here is this payload scope is local to this endpoint, i.e. it will NOT override your flow’s current payload. So, now we know how to write a flow variable—in fact any content like session variable, properties, etc. to a file using a file outbound endpoint.
  • <file:outbound-endpoint path="output"
    outputPattern="file2.json" responseTimeout="10000" <strong>transformer-refs="ExpressionForFile2"</strong>
    doc:name="File" />
    <expression-transformer expression="#[return flowVars.file2content]"
    name="ExpressionForFile2" doc:name="Expression" />

    Write file3.xml: To further demonstrate the inline transformers, let’s look at the third file outbound endpoint. This endpoint uses two inline transformers as shown in the two snippets below. When we specify more than one transformers then Mule will always apply them in the sequence as specified in the declaration. First, the endpoint’s payload will be set as file3content flow variable which is a JSON generated by DataWeave. Then we apply the JSON_to_XML transformer to convert that JSON into XML. At the end, this XML will be written to file3.xml. So, now we know how we can use multiple transformers to pre-process the input of an endpoint.

    <file:outbound-endpoint path="output"
    outputPattern="file3.xml" responseTimeout="10000" <strong>transformer-refs="Expression JSON_to_XML"</strong>
    doc:name="File" />
    <expression-transformer expression="#[return flowVars.file3content]"
    name="Expression" doc:name="Expression" />
    <json:json-to-xml-transformer name="JSON_to_XML"
    doc:name="JSON to XML" />

    Note: This example uses file:outbound-endpoint but transformer-refs attribute is available on other endpoints too, and this post may be extended to apply similar concept on other endpoints.

    Finally, let’s see our input and files generated by this flow:

    Input JSON:

    {
    "file1": {
    "text": "This content is for file 1"
    },
    "file2": {
    "text": "This content is for file 2"
    },
    "file3": {
    "text": "This content is for file 3"
    }
    
    }

    file1.json:

    {
      "text": "This content is for file 1"
    }

    file2.json:

    {
      "text": "This content is for file 2"
    }

    file3.xml:

    <?xml version='1.0'?>
    <text>This content is for file 3</text>

    Hope This Helps! Let me know your thoughts about this.

    The Integration Zone is proudly sponsored by CA Technologies. Learn from expert microservices and API presentations at the Modernizing Application Architectures Virtual Summit Series.

    Topics:
    mule esb ,endpoints ,integrations

    Published at DZone with permission of Manik Magar. See the original article here.

    Opinions expressed by DZone contributors are their own.

    THE DZONE NEWSLETTER

    Dev Resources & Solutions Straight to Your Inbox

    Thanks for subscribing!

    Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

    X

    {{ parent.title || parent.header.title}}

    {{ parent.tldr }}

    {{ parent.urlSource.name }}