I need a while loop in my Mule Flow to load data in chunks from a custom DAO (I use an Expression Transformer to access the DAO) until he does not provide any more items. (I don't know the total amount of items the DAO provides.) There is no build-in while loop in Mule 3.4.
My first Idea was to use a recursive backreference in a SubFlow. The SubFlow calls itself until the work is done. But I ge a springframework exception for an "unresolvable circular reference". A Flow cannot call itself.
My next Idea was to write a Custom Transformer and inject the SubFlow to call in a loop. I use some techics David Dossot described in his answer for this question: https://stackoverflow.com/a/16532977/2629741
The Problem I have is not only that the flowVars from the original Flow are not accessable in the SubFlow but also that I get an exception if I try to set a flowVar (and I use flowVars for the communication between the original Flow and the SubFlow):
org.mule.api.transformer.TransformerMessagingException: null (java.lang.NullPointerException). Message payload is of type: NullPayload
My Question ist: How do I make the flowVars from the original Flow accessable in the SubFlow (and vice versa) I called inside a Custom Transformer (see class Loop below)?
The Mule flow:
<flow name="test_loopFlow1" doc:name="test_loopFlow1">
<vm:inbound-endpoint exchange-pattern="request-response" path="test_loop" doc:name="VM"/>
<custom-transformer class="com.example.transformer.Loop" doc:name="Java">
<spring:property name="flow" ref="loopTask"/>
</custom-transformer>
</flow>
<sub-flow name="loopTask" doc:name="loopTask">
<logger message="loop" level="WARN" doc:name="Logger"/>
<set-variable variableName="stop" value="true" doc:name="set flowVar"/>
</sub-flow>
Loop Transformer:
public class Loop
extends AbstractMessageTransformer
implements FlowConstructAware
{
private InterceptingChainLifecycleWrapper _flow = null;
public void setFlow(
final Object value
) {
this._flow = InterceptingChainLifecycleWrapper.class.cast(value);
}
@Override
public Object transformMessage(
final MuleMessage message,
final String outputEncoding
) throws TransformerException
{
try {
final MuleEvent muleEvent = new DefaultMuleEvent(
message,
MessageExchangePattern.REQUEST_RESPONSE,
this.flowConstruct
);
message.setInvocationProperty("stop", "false");
do {
/*final MuleEvent resultEvent =*/ this._flow.process(muleEvent);
} while(
((String) message.getInvocationProperty("stop")).equals("false")
);
} catch (final MuleException e) {
throw new TransformerException(
MessageFactory.createStaticMessage("SubFlow exception."),
this
);
}
return message;
}
FlowConstruct flowConstruct;
@Override
public void setFlowConstruct(final FlowConstruct flowConstruct)
{
this.flowConstruct = flowConstruct;
}
}
Unit Test:
public class LoopTest
extends FunctionalTestCase
{
private LocalMuleClient _muleClient = null;
public LoopTest(
) throws Exception
{
super.setUpMuleContext();
this._muleClient = new DefaultLocalMuleClient(
AbstractMuleContextTestCase.muleContext
);
}
@Override
protected String getConfigResources(
) {
return "src/main/app/test_loop.xml";
}
@Test
public void testVm(
) throws Exception
{
this._muleClient.send("vm://test_loop", null, null);
}
}
A much simple approach that does not require any java code would be:
<flow name="stackoverflowFlow1" doc:name="stackoverflowFlow1">
<vm:inbound-endpoint exchange-pattern="one-way" path="in" doc:name="VM"/>
<set-variable variableName="#['counter']" value="#[0]" doc:name="Variable"/>
<flow-ref name="stackoverflowFlow2" doc:name="Flow Reference"/>
</flow>
<flow name="stackoverflowFlow2" doc:name="stackoverflowFlow2">
<logger level="INFO" doc:name="Logger"/>
<set-variable variableName="counter" value="#[flowVars['counter']+1]" doc:name="Variable"/>
<choice doc:name="Choice">
<when expression="#[flowVars['counter']==10]">
<logger level="INFO" doc:name="Logger"/>
</when>
<otherwise>
<flow-ref name="stackoverflowFlow2" doc:name="Flow Reference"/>
</otherwise>
</choice>
</flow>
In this case I'm stopping the the while after 10 iterations
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With