在Mule 3.4中模拟while循环 [英] Simulate while loop in Mule 3.4

查看:214
本文介绍了在Mule 3.4中模拟while循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在Mule Flow中进行一个while循环,以从自定义DAO(我使用Expression Transformer访问DAO)中加载数据块,直到他不再提供其他项目为止. (我不知道DAO提供的项目总数.)Mule 3.4中没有内置的while循环.

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.

我的第一个想法是在SubFlow中使用递归反向引用. SubFlow会自行调用,直到工作完成.但是我为无法解决的循环参考"创建了一个springframework例外.流无法自我调用.

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.

我的下一个想法是编写一个Custom Transformer并注入SubFlow以在循环中调用.对于这个问题,我使用David Dossot在他的回答中描述的一些技巧: https://stackoverflow.com/a/16532977/2629741

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

我遇到的问题不仅是原始流中的flowVars在SubFlow中不可访问,而且如果尝试设置flowVar,我也会遇到异常(并且我将flowVars用于原始Flow与SubFlow):

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

我的问题专家:如何在我在自定义转换器中调用的子流中访问原始流中的flowVar(反之亦然)(见下面的类Loop)?

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

M子流:

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

推荐答案

一种不需要任何Java代码的简单方法是:

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>

在这种情况下,我要在10次迭代后停止片刻

In this case I'm stopping the the while after 10 iterations

这篇关于在Mule 3.4中模拟while循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆