Charu Khurana
Charu Khurana

Reputation: 4551

How can I overwrite the payload in 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.

Upvotes: 5

Views: 12397

Answers (4)

user3366906
user3366906

Reputation: 149

You can keep the payload intact and store the value of the xslt transformation in a variable using message enricher. Use the variable inside choice to determine which queue to go to. Below is a code snippet

 <enricher doc:name="Message Enricher" target="#[flowVars.transformResultVar]">
               <!--perform transformation logic here-->
 </enricher>

Reference: https://dzone.com/articles/content-enrichment-using-mule-message-enricher-com

Upvotes: 0

Alex Fernandez
Alex Fernandez

Reputation: 1942

You could do this with lot of ways.

  1. Use set-payload
  2. Use expression, #[payload='']
  3. Use an transformer/component

Upvotes: 0

Anshu Sk Mishra
Anshu Sk Mishra

Reputation: 36

Use Set-Payload and provide the data to be overwritten.

Upvotes: 0

David Dossot
David Dossot

Reputation: 33413

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]" />

Upvotes: 16

Related Questions