如何停止camel doWhile循环

时间:2018-06-11 13:39:52

标签: apache-camel cxf

我们有一个独立的捆绑包,根据一些头变量[direct-vm:createPartService]创建工厂部件。

我的应用程序需要循环遍历部件列表并重复调用此捆绑包。我的partBean.update方法只是从零件列表中检索零件信息,设置头变量然后调用createPartService。

我使用以下doWhile循环。我发现当createPartService返回状态为ERROR时,以下循环完美地工作。工作流从循环退出并转到异常处理部分。但是,当createPartService返回状态永远不会出错时,即每个createPartService都是SUCCESS时,while循环永远不会停止。

        <loop doWhile="true">
          <simple>${header.STATUS} == 'SUCCESS'</simple>              
          <bean ref="partBean" method="update"/>
          <to uri="direct-vm:createPartService"/>
            <choice>
                <when>
                    <simple>${header.STATUS} == 'ERROR'</simple>
                    <throwException exceptionType="java.lang.Exception message="${header.ERROR_MESSAGE}"/>
                    <to uri="mock:endPartsError"/>
                </when>
                <otherwise>
                    <log message="### update part succeeded" loggingLevel="DEBUG"/>
                </otherwise>
            </choice>
        </loop>

然后,我尝试了另一种情况,

<simple>${header.STATUS} == 'SUCCESS' &amp;&amp; ${exchangeProperty[CamelLoopIndex]} &lt; ${headers.PART_COUNT}</simple>

Camel似乎不接受逻辑&#39;和&#39;。上述评估总是返回false。我也尝试过替换&amp;&amp;&amp;&#39;与&#39;和&#39;,或相应的html实体。没有区别。有没有关于循环遍历列表并在没有错误时优雅退出的建议?

2 个答案:

答案 0 :(得分:0)

您没有正确设置循环终止条件。

  

使用bean来控制循环终止条件

Camel Spring XML

<loop doWhile="true">
    <simple resultType="java.lang.Boolean">${bean:partBean?method=isContinueLoop}</simple>
    ... do stuff here ...
</loop>

Java Bean

public Boolean isContinueLoop(Exchange exchange) throws Exception {
    // System.out.println("LoopIndex: " + exchange.getProperty(Exchange.LOOP_INDEX));

    Boolean result = false;

    String status = exchange.getIn().getHeader("STATUS", String.class);
    Integer loopIndex = exchange.getProperty(Exchange.LOOP_INDEX, -1, Integer.class);
    int maxSize = exchange.getIn().getHeader("PART_COUNT", Integer.class);

    if (status != null && status.equals("SUCCESS") && loopIndex < maxSize) {
        result = Boolean.TRUE;
    }

    return result;
}

条件${header.STATUS} == 'SUCCESS' && ${exchangeProperty[CamelLoopIndex]} < ${headers.PART_COUNT}的主要问题不在于AND运算符,而是${exchangeProperty[CamelLoopIndex]}的值。

如果取消注释java bean中的系统print,您可以观察到CamelLoopIndex的值更改为:null - &gt; 0 - &gt; 1 - &gt; 2 - &gt; ...,null值是使条件返回false的根问题。要在Camel Spring XML Simple语言中避免这种情况,您需要使用OR运算符对CamelLoopIndex进行空检查。

从这个意义上说,你需要一个AND运算符和一个OR运算符。但是,目前Simple language page部分&#39;使用和/或&#39;中的状态不支持此功能。

答案 1 :(得分:0)

<split>为我的用例提供了一个很好的解决方案。在下面的代码示例中,findParts方法返回Part对象的列表。更新方法将设置Web服务调用(createPartService)所需的标头变量。

<route id="WebServiceUpdateParts">
    <from uri="direct:updateParts"/>
      <split stopOnException="true">
            <method ref="partBean" method="findParts"/>
        <bean ref="partBean" method="update"/>
        <to uri="direct-vm:createPartService"/>
    </split>
    <to uri="mock:endUpdateParts"/>
</route>