3
votes

In Mule ESB, I'm trying to forward custom HTTP headers through foreach loop without storing my data in session variables.

About my use case : I have a 20 different flows in mule that have HTTP inbound and between 2 and 5 HTTP outbounds. I'm trying to forward about 10 HTTP headers from the inbound to all the outbounds.

I've tried to put a private flow that copy inbound variables to outbound variables

<flow name="add_http_headers" doc:name="add headers">
    <message-properties-transformer scope="outbound">
        <add-message-property value="#[message.inboundProperties.X-HeaderName1]" key="X-HeaderName1"/>
    </message-properties-transformer>
</flow>

It works correctly except in one case : the http outbound tag is in a for-each tag : the for-each create a new context. The Outbound and Inbound variables are no longer accessible. But I can still have access to session variables.

Therefore I have a patch but I'm not happy with it : Before my fore-each I transform all my headers in session variables

<message-properties-transformer  scope="session" >
    <add-message-property value="#[message.inboundProperties.X-HeaderName1]" key="X-HeaderName1"/>
</message-properties-transformer>

Then in my for-each tag I retransform those session variables in outbound variables :

<message-properties-transformer  scope="outbound" >
    <add-message-property value="#[sessionVars.X-defaultDistributor]" key="X-defaultDistributor"/>
</message-properties-transformer>

It works but I have a lot of duplications, is there a way of limiting duplication and forwarding http headers even when a new mule context is created ?

2

2 Answers

1
votes

For those that may still run into this issue (as I did), here is an alternative option. Inside foreach loop you can still access original headers in "rootMessage" variable, so a simple script like this can transfer (all or some of) those into outbound properties:

<scripting:component doc:name="Groovy">
      <scripting:script engine="Groovy"><![CDATA[
           rootMessage.getInboundPropertyNames().each{ inKey ->
             if (rootMessage.getInboundProperty(inKey) != null) {
                message.setOutboundProperty(inKey, rootMessage.getInboundProperty(inKey))
             }
           }
         return payload; 
      ]]></scripting:script>
    </scripting:component>
0
votes

There are flowvars that you could use. Putting everything into session vars is not a good idea as Mule will pass it on to following flows and vm's. It even attaches it to the http header as serialized variables. So if your session grows too big you might get issues in some services not accepting your http request as the header is too big. You always need to unset session vars. Sometimes you can't avoid it but generally I would prefer flowvars. The scope of the flowvar is limited to the flow or sub flow. So you do not need to take care about unsetting them or side effects because the variables are carried a cross the entire application, through every VM and flow or Mule trying to serialize it.

So my best guess would be: Use flowvars.