如何停止骆驼做 While 循环

How to stop camel doWhile loop

我们有一个独立的包,它基于几个 header 变量 [direct-vm:createPartService] 创建工厂部件。

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

我使用以下 doWhile 循环。我发现当 createPartService return status 为 ERROR 时,以下循环完美运行。工作流退出循环并转到异常处理部分。但是,当 createPartService return 状态永远不会出错时,即每个 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>

骆驼似乎不接受逻辑'and'。上面的评价总是returns false。我还尝试用 'and' 或相应的 html 实体替换“&&”。没有区别。关于遍历列表并在没有错误时优雅退出的任何建议?

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


Use a bean to control your looping terminate condition

驼色SpringXML

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

Java豆子

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 中的系统打印,您可以观察到 CamelLoopIndex 的值更改为:null -> 0 -> 1 -> 2 -> ...,null 值为使您的条件 return 为假的根本问题。为了在 Camel Spring XML 简单语言中避免这种情况,您需要使用 OR 运算符对 CamelLoopIndex 进行空检查。

从这个意义上讲,您将需要 AND 运算符和 OR 运算符。但是,目前 Simple language page 节 'Using and / or'.

中的简单语言不支持此功能

<split> 为我的用例提供了一个很好的解决方案。在下面的代码示例中,findParts 方法 returns 部分 object 的列表。更新方法设置 header 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>

如果你想在特定回合后停止循环,你可以使用这个:

from("direct:test").setProperty("CamelLoopIndex",constant(0)).loopDoWhile(simple("${exchangeProperty.CamelLoopIndex} <= 3")).log("=====${exchangeProperty.CamelLoopIndex}");

注意你必须在循环之前显式声明CamelLoopIndex 属性,否则Camel在启动路由时将无法理解contiditon,因为CamelLoopIndex 属性是在循环开始后创建的。