1
votes

We are migrating from Mule 3 to Mule 4 and in one of our functionalities we need to publish messages to a topic and downstream another mule component is consuming from the queue which is bridged to the topic.
Nothing special here .
To ensure we are able to trace the flow via logs we were sending a 'TrackingId' attribute while publishing messages to the topic ( Mule 3 )

message.setOutboundProperty("XYZ_TrackingID", flowVars['idFromUI']);
            return payload;

However when I try the same in Mule 4 we get the following exception :

ERROR 2020-12-20 10:09:12,214 [[MuleRuntime].cpuIntensive.14: [mycomponent].my_Flow.CPU_INTENSIVE 
@66024695] org.mule.runtime.core.internal.exception.OnErrorPropagateHandler: 
Message : groovy.lang.MissingMethodException: No signature of method: 
org.mule.runtime.api.el.BindingContextUtils$MessageWrapper.setOutboundProperty() is applicable for 
argument types: (java.lang.String, org.mule.weave.v2.el.ByteArrayBasedCursorStream) values: 
[XYZ_TrackingID, "1234567"].\nError type            :   (set debug level logging or '- 
Dmule.verbose.exceptions=true' for 
everything)\n********************************************************************************

Checked internet and it seems in Mule4 setting outbound properties is removed as per here

So how do I achieve the same in Mule 4 ?

2

2 Answers

1
votes

Don't even try to do that for several reasons. For one message structure is different, so output properties doesn't exist anymore and that method doesn't even exists. On the other hand, in Mule 4 components like the Groovy component can only return a value and cannot change the event. They can not decide to what that value is going to be assigned. You can set the target in the configuration (payload or a variable) and not change the attributes. Note that variables in Mule 4 are referenced by var., not by flowVars. like in Mule 3 (ie vars.idFromUI).

There is a simpler way to set message properties in the Mule 4 JMS connector. Use the properties element and pass it an object with the properties.

For example it could be something like this:

<jms:publish config-ref="JMS_config" destination="${bridgeDestination}" destinationType="TOPIC">
    <jms:message>
        <jms:body>#["bridged_" ++ payload]</jms:body>
        <jms:properties>#[{
            XYZ_TrackingID: vars.idFromUI
        }]</jms:properties>
    </jms:message>
</jms:publish>

It is in the documentation: https://docs.mulesoft.com/jms-connector/1.0/jms-publish#setting-user-properties. I adapted my example from there.

1
votes

I am not sure if Correlation Id serves the purpose of a tracking ID for your scenario. But you can pass a CID as below. It's there in the mule documentation. https://docs.mulesoft.com/jms-connector/1.7/jms-publish

<jms:publish config-ref="JMS_config" sendCorrelationId="ALWAYS" destination="#[attributes.headers.replyTo.destination]">
    <jms:message correlationId="#[attributes.headers.correlationId]"/>
</jms:publish>

If your priority is to customise the Tracking ID you want to publish, then try passing below format. The key names may differ as per your use case.

<jms:publish config-ref="JMS_config" destination="${bridgeDestination}" destinationType="TOPIC">
    <jms:message>
        <jms:body>#["bridged_" ++ payload]</jms:body>
        <jms:properties>#[{
            AUTH_TYPE: 'jwt',
            AUTH_TOKEN: attributes.queryParams.token
        }]</jms:properties>
    </jms:message>
</jms:publish>

In the above the expression attributes.queryParams.token is basically trying to access a token query parameters which is passed to JMS as a property AUTH_TOKEN key-name , consumed by the API through a HTTP Listener or Requestor earlier. However, attributes.headers.correlationId is a header. Both queryParams and headers are part of attributes in Mule 4.