Sam Lloyd
Sam Lloyd

Reputation: 21

Maintaining Mule Message

Similar to this discussion Maintain Payload State during mule flow execution

I would like to know how to maintain an entire Mule Message throughout my flow. I am trying to call a jersey resource component after I have received information that the user is authorized to call it. In this authorization request the payload and original http request gets altered.

My predicament is that I don't want to call the resource first as that would be inefficient and insecure however I cannot see any other plausible way to do this.

<flow name="test">
    <http:inbound-endpoint exchange-pattern="request-response" host="0.0.0.0" port="1234" path="test" doc:name="HTTP"/>
    <!-- sub-flow here which changes the MuleMessage and loses all original inbound properties -->

    <jersey:resources doc:name="REST">
        <component class="com.Test" />
    </jersey:resources>
</flow>

Thanks for any help in advance

Upvotes: 1

Views: 1741

Answers (5)

vikram kumar u
vikram kumar u

Reputation: 205

best way to store the mule message into session , whether you flow contains subflows are private flow session vars carry till end of the execeution.

Upvotes: 0

Sam Lloyd
Sam Lloyd

Reputation: 21

Thanks for all your help. The final solution answer was:

<flow name="test">
    <http:inbound-endpoint exchange-pattern="request-response" host="0.0.0.0" port="1234" path="test" doc:name="HTTP"/>

    <enricher target="#[variable:unwantedPayload]" source="#[payload]">
        <flow-ref name="anotherFlowCalled" />
    </enricher>

    <jersey:resources doc:name="REST">
        <component class="com.Test" />
    </jersey:resources>
</flow>

Upvotes: 0

Ryan Hoegg
Ryan Hoegg

Reputation: 2475

Mule 3 includes two scopes that will allow you to preserve the original message, while executing other message processors:

  1. If you must wait for the sub-flow to complete because you need to use information produced by the sub-flow, use a message enricher like so. This example assigns the variable "authorized" to whatever the payload is once the sub-flow finishes processing the message.

    <enricher target="#[variable:authorized]"> <flow-ref name="checkAuthorization" /> </enricher>

  2. If you do not need to wait for the sub-flow to complete before allowing your Jersey Resource to run, use the async scope like so:

    <async> <flow-ref name="goForthAndDoSomething" /> </async>

Upvotes: 1

Anirban Sen Chowdhary
Anirban Sen Chowdhary

Reputation: 8311

There are multiple ways to save a mule message and it's properties so that it could be retrieve when required .. In your case you could save the entire Mule message in a variable and retrieve it when required for example :

<flow name="test">
    <http:inbound-endpoint exchange-pattern="request-response" host="0.0.0.0" port="1234" path="test" doc:name="HTTP"/>
   <!-- You save your entire message in a session variable named entireMessage before calling a subflow-->
<set-session-variable variableName="entireMessage" value="#[message.payload]" />
 <!-- You can now call your Sub flow -->

    <jersey:resources doc:name="REST">
        <component class="com.Test" />
    </jersey:resources>
</flow>

Here in the above flow you store your Mule message in a session variable named entireMessage .. You can easily retrieve the value of this session variable whenever you need in any flow anywhere like the following :-

<logger level="INFO" message="#[sessionVars['entireMessage']]"/>

This will print you Mule message

There is also an alternative way to store the http headers before it get altered .. you can also use the following :-

<flow name="test">
 <http:inbound-endpoint exchange-pattern="request-response" host="0.0.0.0" port="1234" path="test" doc:name="HTTP"/>
       <!-- You copy all the HTTP headers before calling a subflow-->
 <copy-properties propertyName="http.*" doc:name="Copy All HTTP Headers"/>  
  <!-- You can now call your Sub flow -->

   <jersey:resources doc:name="REST">
      <component class="com.Test" />
    </jersey:resources>
</flow>

The above flow will copy all the HTTP headers before calling any other flow

UPDATED FLOW :-

If you need the original unaltered payload for your Jersy component , please overwrite the current payload with the original payload stored in session variable using set payload component

 <flow name="test">
        <http:inbound-endpoint exchange-pattern="request-response" host="0.0.0.0" port="1234" path="test" doc:name="HTTP"/>
       <!-- You save your entire message in a session variable named entireMessage before calling a subflow-->
    <set-session-variable variableName="entireMessage" value="#[message.payload]" />
     <!-- You can now call your Sub flow -->

 <!-- overwrite current payload with original unaltered payload -->   
<set-payload value="#[sessionVars['entireMessage']]" doc:name="Set Payload"/>
        <jersey:resources doc:name="REST">
            <component class="com.Test" />
        </jersey:resources>
    </flow>

Upvotes: 1

Andres
Andres

Reputation: 10707

Try somthing like this to store the original message in session:

    <message-properties-transformer scope="session" doc:name="Save original message">
        <add-message-property key="originalMessage" value="#[message:payload]"></add-message-property>
    </message-properties-transformer>

Then try something like this to get it from session:

<expression-transformer evaluator="..." expression="SESSION:originalMessage" doc:name="Restore original message"></expression-transformer>

Upvotes: 0

Related Questions