Venkat
Venkat

Reputation: 21

Usage of Mule Message Properties

Good morning I am trying to set a property and access it. But failed to access the property set. I was trying to access a property in SplitterAggregator that is set from the client. Following is the mule config.

<flow name="statementRequestFlow">
<vm:inbound-endpoint path="statementRequest" /> 
<vm:outbound-endpoint path="statementSplit" />
</flow>
<flow name="statementSplitFlow">
<vm:inbound-endpoint path="statementSplit" /> 
<splitter evaluator="xpath" expression="/DocumentJournal/StatementsData/Statement" />
<vm:outbound-endpoint path="statementResponse" transformer-refs="domToXml" />
</flow>

<flow name="statementResponseFlow">
<vm:inbound-endpoint path="statementResponse" transformer-refs="XmlToStatement"/> 
<custom-aggregator timeout="5000" class="com.test.splitter.SplitterAggregator"/>
<component class="com.test.splitter.StatementAggregator"> 
<method-entry-point-resolver>
<include-entry-point method="collectStatements"/>
</method-entry-point-resolver>
</component>
</flow>

Following is the client code:

In this version I simply created a HashMap as props and put a property by name "my_key" and passed it to sendAsync.

String applicationDataAsXml = "<DocumentJournal>...........</DocumentJournal>";
MuleClient muleClient = MuleClientSingleton.getMuleClient();
try {
Map<String,Object> props = new HashMap<String,Object>();
props.put("MessageProperties", "MessageProperties");
props.put("my_key", "my_value");
muleClient.sendAsync("vm://statementRequest", applicationDataAsXml, props);
}catch(Exception e) {
e.printStackTrace();
}

Following is the custom aggregator:

public class SplitterAggregator extends AbstractAggregator {

@Override
public MuleEvent process(MuleEvent event) throws MuleException {
MuleMessage message = event.getMessage();
System.out.println("SPlitterAggregator.process(): my_key value: "+ message.getOutboundProperty("my_key"));
Statement statement = (Statement) message.getPayload();
System.out.println("SPlitterAggregator.process(): Statement: "+statement.toString());
return super.process(event);
}

My intent is to access the property "my_key" that is set in the client and access it in SplitterAggregator.process() method. It is printed as null.

Following is the second version of the client code:

In this version I created DefaultMessage and set "my_key" property with session scope.

String applicationDataAsXml = "<DocumentJournal>...........</DocumentJournal>";
MuleClient muleClient = MuleClientSingleton.getMuleClient();
try {
DefaultMuleMessage message = new DefaultMuleMessage(applicationDataAsXml, muleClient.getMuleContext());
message.setSessionProperty("my_key", "my_value");
muleClient.sendAsync("vm://statementRequest", message);
}catch(Exception e) {
e.printStackTrace();
}

When I run the above version of client code I get java.lang.IllegalStateException: Only owner thread can write to message:

Could someone let me know how to make use of properties.

Thanks Venkat

Upvotes: 2

Views: 8219

Answers (1)

David Dossot
David Dossot

Reputation: 33413

Your first client code is mostly correct, but use the following instead of sendAsync (which makes sense only if your endpoint endpoint is request-response):

muleClient.dispatch("vm://statementRequest", applicationDataAsXml, props);

Now you need to understand the notion of message properties scope. For this, I suggest you read http://www.mulesoft.org/documentation/display/MULE3USER/Message+Property+Scopes

Then consider your flows:

  • you set my_key on the message and dispatch it to a first VM endpoint in statementRequestFlow,
  • when the message arrives in statementRequestFlow, my_key is in the inbound scope,
  • you dispatch the message to the statementSplitFlow via the statementSplit VM endpoint but do not copy the my_key property from the inbound to the outbound scope: hence it is lost,
  • in statementSplitFlow you do a second dispatch to statementResponseFlow over yet another VM endpoint, no hope at all my_key ever reaches your splitter...

Why so many VM endpoints and flows? If re-use is your concern, consider using sub-flows and flow references instead of VM endpoints, otherwise get ready to deal with property copying across scopes (via the standard message-properties-transformer)...

Upvotes: 3

Related Questions