4

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);
   }
}
4

2 に答える 2

9

Javaコードを必要としない非常に単純なアプローチは次のとおりです。

<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>

この場合、10 回の反復後に while を停止しています

于 2013-10-29T15:39:50.623 に答える
5

Flow を再帰的に呼び出すと、最終的に StackOverflowError が発生します。それを試してみたところ、70回以上の反復でスローされました。

代替手段の 1 つは、カスタム トランスフォーマー内にループを配置し、フロー/エンドポイントをプログラムで呼び出すことでした。

于 2016-06-17T16:17:18.153 に答える