Mule フローで while ループを使用して、カスタム DAO からチャンク単位でデータをロードする必要があります (私は Expression Transformer を使用して DAO にアクセスします)。(DAO が提供するアイテムの総数はわかりません。) Mule 3.4 には組み込みの while ループはありません。
私の最初のアイデアは、サブフローで再帰的な後方参照を使用することでした。サブフローは、作業が完了するまで自分自身を呼び出します。しかし、「解決できない循環参照」のスプリングフレームワーク例外が発生します。フローは自分自身を呼び出すことはできません。
私の次のアイデアは、カスタム トランスフォーマーを作成し、SubFlow を挿入してループで呼び出すことでした。この質問に対する彼の回答で説明されているいくつかの技術を使用します: https://stackoverflow.com/a/16532977/2629741
私が抱えている問題は、元の Flow の flowVars が SubFlow でアクセスできないことだけでなく、flowVar を設定しようとすると例外が発生することです (元の Flow と SubFlow 間の通信に flowVars を使用します)。 :
org.mule.api.transformer.TransformerMessagingException: null (java.lang.NullPointerException). Message payload is of type: NullPayload
私の質問は次のとおりです: カスタム トランスフォーマー内で呼び出した元のフロー (およびその逆) でアクセス可能な元のフローのフロー変数を作成するにはどうすればよいですか (以下のクラス ループを参照)。
Mule フロー:
<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>
ループトランス:
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;
}
}
単体テスト:
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);
}
}