WSO2 MI 4.0.0中Iterate中介器首调用失败后终止后续调用问题
解决方案:在WSO2 MI 4.0.0中实现Iterate失败即终止
核心思路
默认Iterate中介器会预先生成所有子线程,即便设置isError属性,后续子线程仍会启动(仅被丢弃)。要实现第一个API调用失败就直接停止后续迭代、不启动新线程,需结合异常抛出+父序列捕获中断的机制,同时确保Iterate以顺序模式执行(sequential="true")。
修改后的完整序列代码
<?xml version="1.0" encoding="UTF-8"?> <sequence name="Iterator" trace="disable" xmlns="http://ws.apache.org/ns/synapse"> <property name="isError" scope="operation" type="BOOLEAN" value="false"/> <!-- 捕获子序列抛出的异常,终止后续迭代 --> <catch> <property name="isError" scope="operation" type="BOOLEAN" value="true"/> <log level="ERROR"> <property name="message" value="迭代执行中断,因API调用失败"/> </log> <!-- 返回错误响应给客户端 --> <payloadFactory media-type="json"> <format>{"error": "API调用失败,迭代已终止"}</format> <args/> </payloadFactory> <respond/> </catch> <iterate continueParent="false" expression="json-eval($)" sequential="true"> <target> <sequence> <log> <property expression="get-property('operation','isError')" name="filter_flag"/> </log> <filter regex="false" source="get-property('operation','isError')"> <then> <property expression="json-eval($.quantity)" name="QUANTITY" scope="default" type="STRING"/> <property expression="json-eval($.price)" name="FINAL_PRICE" scope="default" type="STRING"/> <property expression="json-eval($.final_price)" name="PRICE" scope="default" type="STRING"/> <script language="js"><![CDATA[var log = mc.getServiceLog(); log.info("Logging inside Script Mediator"); var value1 = mc.getProperty("FINAL_PRICE"); var value2 = mc.getProperty("PRICE"); var divide = value1 / value2; log.info("divide "+divide); var formattedNumber = parseFloat(divide.toFixed(2)); log.info("result "+formattedNumber); log.info("PRICECOMPARE"+(value1===divide)); mc.setProperty("LIST_PRICE", formattedNumber); mc.setProperty("PRICECOMPARE", value1===divide);]]></script> <filter regex="false" source="boolean($ctx:PRICECOMPARE)"> <then> <payloadFactory media-type="json"> <format>{&#xd; "line_item": {&#xd; "quantity": $1,&#xd; "list_price": $2&#xd }&#xd; }</format> <args> <arg evaluator="xml" expression="$ctx:QUANTITY"/> <arg evaluator="xml" expression="$ctx:LIST_PRICE"/> </args> </payloadFactory> <endpoint> <http format="soap11" method="GET" uri-template="http://myendpoint/services/GuestIdentityService"/> </endpoint> <property expression="get-property('axis2', 'HTTP_SC')" name="HTTP_STATUS_CODE" scope="default" type="STRING"/> <log> <property expression="json-eval($)" name="status"/> </log> <filter xpath="$axis2:HTTP_SC != '200'"> <then> <property name="isError" scope="operation" type="BOOLEAN" value="true"/> <!-- 抛出异常,触发父序列的catch,终止Iterate后续迭代 --> <throw faultcode="API_ERROR" faultreason="API调用返回非200状态码"/> </then> <else/> </filter> </then> <else/> </filter> </then> <else> <drop/> </else> </filter> </sequence> </target> </iterate> <!-- 所有迭代正常完成时返回成功响应 --> <filter source="get-property('operation','isError')" regex="false"> <then> <payloadFactory media-type="json"> <format>{"status": "所有迭代执行完成"}</format> <args/> </payloadFactory> <respond/> </then> </filter> </sequence>
关键修改点说明
- 设置
continueParent="false":确保父序列等待Iterate的所有子线程执行完成后再继续,避免提前返回响应。 - 添加
<catch>中介器:捕获子序列抛出的异常,立即设置错误状态并返回错误响应,同时终止Iterate的后续迭代。 - 错误分支添加
<throw>:当API调用失败时,抛出异常触发父序列的中断逻辑,而非仅设置isError,以此阻止Iterate生成后续子线程。 - 调整响应逻辑:区分正常完成和错误中断两种情况,分别返回对应响应。
注意事项
- 必须保持Iterate的
sequential="true":仅在顺序执行模式下,子线程的异常才能及时触发父序列的中断,避免并行线程继续执行。 operation范围的isError属性:用于在正常流程中判断是否出现错误,保证最终响应的正确性。
内容的提问来源于stack exchange,提问作者sathish Sankarzz
相关产品推荐
相关产品推荐

