Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I overwrite the payload in mule

Tags:

mule

I've a Soap request coming into mule flow. Am tasked with getting information out of payload and depending on outcome, push the original request to different jms queues.

To get the desired information out of payload, I'm using XSLT tranformer (not XPath, because I need to get IDREF attribute from an element, based on IDREF, get the element and then a child element out of the IDREF object).

Based on the outcome of the of XSLT tranformation, I use choice element to push original payload. Am storing original payload in a Session (can do it in Inbound as well). After XSLT tansformation, apply choice router to find out appropriate queue, and then want to push the original payload into queue(original payload in stored in a session variable). I am using <expression-component> element. Below is the snippet of mule-flow:

<flow name="ProcessXML121Order">
    <jms:inbound-endpoint queue="mviq.121.order" exchange-pattern="one-way" />
    <logger message="121 order payload is #[payload]" level="INFO" />
    <message-properties-transformer scope="session">
        <add-message-property key="mviPayload" value="#[payload]"/>
    </message-properties-transformer>
    <xm:xslt-transformer xsl-file="chooseVendor.xslt" />
    <logger message="After xsl file payload is #[payload]" level="INFO" />      
    <choice>
        <when expression="'EMSI'">
            <logger message="Vendor is EMSI" level="INFO" />
            <expression-component>payload=#[header:SESSION:mviPayload]</expression-component>
            <jms:outbound-endpoint queue="mviq.121.order.emsi" />
        </when>
        <when expression="'PRMD'">
            <logger message="Vendor is PRMD" level="INFO" />
            <jms:outbound-endpoint queue="mviq.121.order.prmd" />
        </when>
        <when expression="'RSA'">
            <logger message="Vendor is RSA" level="INFO" />
            <logger message="RSA payload is #[payload]" level="INFO" />
            <jms:outbound-endpoint queue="mviq.121.order.rsa" />
        </when>
        <otherwise>
            <logger message="Vendor is Error" level="INFO" />
            <logger message="Vendor error payload is #[payload]" level="INFO" />
            <jms:outbound-endpoint queue="mviq.error" />
        </otherwise>
    </choice>
</flow>

Following exception is thrown when evaluating payload=#[header:SESSION:mviPayload]

[ProcessXML121Order.stage1.02] exception.AbstractExceptionListener (AbstractExceptionListener.java:296) - 
********************************************************************************
Message               : Execution of the expression "payload=#[header:SESSION:mviPayload]" failed. (org.mule.api.expression.ExpressionRuntimeException). Message payload is of type: byte[]
Code                  : MULE_ERROR-29999
--------------------------------------------------------------------------------
Exception stack is:
1. [Error: illegal use of operator: +]
[Near : {... Unknown ....}]
             ^
[Line: 1, Column: 0] (org.mvel2.CompileException)
  org.mvel2.ast.OperatorNode:46 (null)
2. Execution of the expression "payload=#[header:SESSION:mviPayload]" failed. (org.mule.api.expression.ExpressionRuntimeException)
  org.mule.el.mvel.MVELExpressionLanguage:211 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/expression/ExpressionRuntimeException.html)
3. Execution of the expression "payload=#[header:SESSION:mviPayload]" failed. (org.mule.api.expression.ExpressionRuntimeException). Message payload is of type: byte[] (org.mule.api.MessagingException)
  org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor:35 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/MessagingException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
[Error: illegal use of operator: +]
[Near : {... Unknown ....}]
             ^
[Line: 1, Column: 0]
    at org.mvel2.ast.OperatorNode.getReducedValueAccelerated(OperatorNode.java:46)
    at org.mvel2.MVELRuntime.execute(MVELRuntime.java:85)
    at org.mvel2.compiler.CompiledExpression.getValue(CompiledExpression.java:105)
    + 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************

I've 2 questions:

  1. How can I overwrite the original payload? (Not saying this is the best way to go)
  2. What is the better approach in this scenario? Is it advisable to keep original payload intact (in this case) and store XSLT output in other variable? How can I do that? What is the path (mule component) I can use to achieve that? I'm very new to Mule and seek community advice.

Thanks for your time looking into this.

like image 499
Charu Khurana Avatar asked Dec 21 '12 15:12

Charu Khurana


People also ask

How do I change payload in Mule 4?

The Set Payload ( set-payload ) component lets you update the payload of the message. The payload can be a literal string or a DataWeave expression. The set-payload component, however, is not recommended for complex expressions or transformations but rather, simple ones, such as selections.

How do you update variables in Mule 4?

You can create or update variables in these ways:Using the Set Variable component. Using a Target Variable from within an operation, such as the Read operation to the File connector or the Store operation to the Database connector. Using the Datwave Transform Component (EE-Only).

What is mule4 payload?

In Mule 4, any component that needs to deal with multiple messages can simply set the payload of the message to a List of Mule Messages. You can then iterate over these messages using DataWeave, For Each, or other components. For example, the <file:list> operation retrieves a List of Messages.


1 Answers

Before answering your questions, let's rewrite this broken expression:

<expression-component>payload=#[header:SESSION:mviPayload]</expression-component>

as:

<set-payload value="#[sessionVars.mviPayload]" />

The following would work too but would be more complex for no good reason:

<expression-component>payload=sessionVars.mviPayload</expression-component>

Also this:

<message-properties-transformer scope="session">
    <add-message-property key="mviPayload" value="#[payload]"/>
</message-properties-transformer>

would be better written:

<set-session-variable variableName="mviPayload" value="#[message.payload]" />

Now to your questions:

  1. Use set-payload
  2. What you are doing is the best: transformers, like XSL-T, applies naturally to the current message payload so saving the original in a property then transforming the main payload is OK. Just one thing: prefer a flow variable instead of a session variable. Indeed, in your case, I don't think you need the original payload outside this flow, so storing in session is overkill.

So I suggest you use:

<set-variable variableName="mviPayload" value="#[message.payload]" />

to store the original payload and the following to re-establish it:

<set-payload value="#[mviPayload]" />
like image 199
David Dossot Avatar answered Sep 28 '22 10:09

David Dossot