WSO2 Enterprise Integrator 迭代和聚合,聚合问题

huangapple go评论65阅读模式
英文:

WSO2 Enterprise Integrator iterate and aggregate, issue with aggregation

问题

我想在迭代中执行并行API调用,然后使用聚合中介器对响应进行分组。格式为JSON。我正在使用以下代码:

[...iterate中的代码]
<script language="js">var c = mc.getProperty("account");
                                      
                                        print("Value : "+ c );
                                        mc.setProperty("concatValue", c);
                                        mc.setPayloadJSON({"result":{"account" : c}});</script>
                                        
    <log>
                     <property expression="json-eval($)" name="JSON-Payload in sequence"/>
                  </log>
                  
   
                 </sequence>
           

            </target>
         </iterate>
			
        <property name="Aggregated_Responses" scope="default" value = "{}"/>
			
        <aggregate id="it1">
            <completeCondition>
              <messageCount max="-1" min="-1"/>
            </completeCondition>
            <onComplete expression="json-eval($)" enclosingElementProperty="Aggregated_Responses">
                 <log>
                     <property expression="json-eval($)" name="JSON-Payload in oncomplete"/>
                  </log>
            </onComplete>
       </aggregate>
      <loopback/>
    </sequence>

聚合没有起作用,如果我在oncomplete中添加loopback,它将返回一个JSON,第二个JSON将在日志中打印一条消息,指示响应已发送。有人可以帮助我解决这个问题吗?
另外一个问题:在迭代中的工作通常是并行进行还是串行进行的?

(注意:这里只是提供了翻译好的代码部分,不包括问题的回答部分。)

英文:

I want to perform parallel API calls in iterate mediator then to group the responses using the aggregate mediator. The format is JSON. I am using this code:

 [...code in iterate]
&lt;script language=&quot;js&quot;&gt;var c = mc.getProperty(&quot;account&quot;);
                                  
                                    print(&quot;Value : &quot;+ c );
                                    mc.setProperty(&quot;concatValue&quot;, c);
                                    mc.setPayloadJSON({&quot;result&quot;:{&quot;account&quot; : c}});&lt;/script&gt;
                                    
&lt;log&gt;
                 &lt;property expression=&quot;json-eval($)&quot; name=&quot;JSON-Payload in sequence&quot;/&gt;
              &lt;/log&gt;
              

             &lt;/sequence&gt;
       

        &lt;/target&gt;
     &lt;/iterate&gt;
		
	&lt;property name=&quot;Aggregated_Responses&quot; scope=&quot;default&quot; value = &quot;{}&quot;/&gt;
		
    &lt;aggregate id=&quot;it1&quot;&gt;
        &lt;completeCondition&gt;
          &lt;messageCount max=&quot;-1&quot; min=&quot;-1&quot;/&gt;
        &lt;/completeCondition&gt;
        &lt;onComplete expression=&quot;json-eval($)&quot; enclosingElementProperty=&quot;Aggregated_Responses&quot;&gt;
             &lt;log&gt;
                 &lt;property expression=&quot;json-eval($)&quot; name=&quot;JSON-Payload in oncomplete&quot;/&gt;
              &lt;/log&gt;
        &lt;/onComplete&gt;
   &lt;/aggregate&gt;
  &lt;loopback/&gt;
&lt;/sequence&gt;

The aggregation is not working, if i add loopback isnide the on complete, it will return one json and the second one will print a message in the logs saying that the response was already sent. Can someone help me solve this issue?
And an additional question: do the work inside the iterate is usually done in parallel or in series?

答案1

得分: 0

如果您正在使用迭代中介器,则在迭代流程中应该包含一个调用中介器,该中介器执行外部调用。如果没有,您必须使用ForEach中介器

迭代示例

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;sequence name=&quot;iterate-aggregate-example&quot; trace=&quot;disable&quot; xmlns=&quot;http://ws.apache.org/ns/synapse&quot;&gt;
  &lt;property description=&quot;countRequests&quot; expression=&quot;count(//Account)&quot;
    name=&quot;countRequests&quot; scope=&quot;default&quot; type=&quot;STRING&quot;/&gt;
  &lt;iterate expression=&quot;//Account&quot; id=&quot;IterateAccountCreate&quot;
sequential=&quot;true&quot;&gt;
    &lt;target&gt;
      &lt;sequence&gt;
        &lt;payloadFactory media-type=&quot;xml&quot;&gt;
          &lt;format&gt;
            &lt;echo:echoString xmlns_echo=&quot;http://echo.services.core.carbon.wso2.org&quot;&gt;
              &lt;in xmlns=&quot;&quot;&gt;$1&lt;/in&gt;
            &lt;/echo:echoString&gt;
          &lt;/format&gt;
          &lt;args&gt;
            &lt;arg evaluator=&quot;xml&quot; expression=&quot;//Account/text()&quot;/&gt;
          &lt;/args&gt;
        &lt;/payloadFactory&gt;
        &lt;property action=&quot;remove&quot; description=&quot;TRANSPORT_HEADERS&quot;
          name=&quot;TRANSPORT_HEADERS&quot; scope=&quot;axis2&quot;/&gt;
        &lt;property description=&quot;OperationName&quot; name=&quot;OperationName&quot;
          scope=&quot;default&quot; type=&quot;STRING&quot; value=&quot;echoString&quot;/&gt;
        &lt;header action=&quot;remove&quot; name=&quot;To&quot; scope=&quot;default&quot;/&gt;
        &lt;header name=&quot;Action&quot; scope=&quot;default&quot; value=&quot;urn:echoString&quot;/&gt;
        &lt;header name=&quot;SOAPAction&quot; scope=&quot;transport&quot; value=&quot;urn:echoString&quot;/&gt;
        &lt;log category=&quot;DEBUG&quot; description=&quot;***Request***&quot;&gt;
          &lt;property expression=&quot;$body&quot; name=&quot;request&quot;/&gt;
        &lt;/log&gt;
        &lt;call&gt;
          &lt;endpoint key=&quot;echo&quot;/&gt;
        &lt;/call&gt;
        &lt;log category=&quot;DEBUG&quot; description=&quot;***Response***&quot; separator=&quot;***Response***&quot;&gt;
          &lt;property expression=&quot;$body&quot; name=&quot;create_instanties_response&quot;/&gt;
        &lt;/log&gt;
      &lt;/sequence&gt;
    &lt;/target&gt;
  &lt;/iterate&gt;
  &lt;aggregate description=&quot;&quot; id=&quot;IterateAccountCreate&quot;&gt;
    &lt;completeCondition timeout=&quot;10&quot;&gt;
      &lt;messageCount max=&quot;{get-property(&#39;countRequests&#39;)}&quot; min=&quot;{get
property(&#39;countRequests&#39;)}&quot;/&gt;
    &lt;/completeCondition&gt;
    &lt;onComplete expression=&quot;//ns:echoStringResponse&quot; xmlns_ns=&quot;http://echo.services.core.carbon.wso2.org&quot;&gt;
      &lt;log description=&quot;***aggregated***&quot; separator=&quot;***aggregated***&quot;&gt;
        &lt;property expression=&quot;$body&quot; name=&quot;aggregated_body&quot;/&gt;      &lt;/log&gt;
    &lt;/onComplete&gt;
  &lt;/aggregate&gt;
&lt;/sequence&gt;
英文:

If you are using the Iterate Mediator you should have a Call Mediator within the iterate flow which does an external call. If not you have to use the Foreach Mediator instead.

Iterate Example

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;sequence name=&quot;iterate-aggregate-example&quot; trace=&quot;disable&quot; xmlns=&quot;http://ws.apache.org/ns/synapse&quot;&gt;
  &lt;property description=&quot;countRequests&quot; expression=&quot;count(//Account)&quot;
    name=&quot;countRequests&quot; scope=&quot;default&quot; type=&quot;STRING&quot;/&gt;
  &lt;iterate expression=&quot;//Account&quot; id=&quot;IterateAccountCreate&quot;
sequential=&quot;true&quot;&gt;
    &lt;target&gt;
      &lt;sequence&gt;
        &lt;payloadFactory media-type=&quot;xml&quot;&gt;
          &lt;format&gt;
            &lt;echo:echoString xmlns_echo=&quot;http://echo.services.core.carbon.wso2.org&quot;&gt;
              &lt;in xmlns=&quot;&quot;&gt;$1&lt;/in&gt;
            &lt;/echo:echoString&gt;
          &lt;/format&gt;
          &lt;args&gt;
            &lt;arg evaluator=&quot;xml&quot; expression=&quot;//Account/text()&quot;/&gt;
          &lt;/args&gt;
        &lt;/payloadFactory&gt;
        &lt;property action=&quot;remove&quot; description=&quot;TRANSPORT_HEADERS&quot;
          name=&quot;TRANSPORT_HEADERS&quot; scope=&quot;axis2&quot;/&gt;
        &lt;property description=&quot;OperationName&quot; name=&quot;OperationName&quot;
          scope=&quot;default&quot; type=&quot;STRING&quot; value=&quot;echoString&quot;/&gt;
        &lt;header action=&quot;remove&quot; name=&quot;To&quot; scope=&quot;default&quot;/&gt;
        &lt;header name=&quot;Action&quot; scope=&quot;default&quot; value=&quot;urn:echoString&quot;/&gt;
        &lt;header name=&quot;SOAPAction&quot; scope=&quot;transport&quot; value=&quot;urn:echoString&quot;/&gt;
        &lt;log category=&quot;DEBUG&quot; description=&quot;***Request***&quot;&gt;
          &lt;property expression=&quot;$body&quot; name=&quot;request&quot;/&gt;
        &lt;/log&gt;
        &lt;call&gt;
          &lt;endpoint key=&quot;echo&quot;/&gt;
        &lt;/call&gt;
        &lt;log category=&quot;DEBUG&quot; description=&quot;***Response***&quot; separator=&quot;***Response***&quot;&gt;
          &lt;property expression=&quot;$body&quot; name=&quot;create_instanties_response&quot;/&gt;
        &lt;/log&gt;
      &lt;/sequence&gt;
    &lt;/target&gt;
  &lt;/iterate&gt;
  &lt;aggregate description=&quot;&quot; id=&quot;IterateAccountCreate&quot;&gt;
    &lt;completeCondition timeout=&quot;10&quot;&gt;
      &lt;messageCount max=&quot;{get-property(&#39;countRequests&#39;)}&quot; min=&quot;{get
property(&#39;countRequests&#39;)}&quot;/&gt;
    &lt;/completeCondition&gt;
    &lt;onComplete expression=&quot;//ns:echoStringResponse&quot; xmlns_ns=&quot;http://echo.services.core.carbon.wso2.org&quot;&gt;
      &lt;log description=&quot;***aggregated***&quot; separator=&quot;***aggregated***&quot;&gt;
        &lt;property expression=&quot;$body&quot; name=&quot;aggregated_body&quot;/&gt;      &lt;/log&gt;
    &lt;/onComplete&gt;
  &lt;/aggregate&gt;
&lt;/sequence&gt;

答案2

得分: 0

最终的工作解决方案,附带一些解释:

<payloadFactory media-type="json">
    <format>
        {               
            "payloadss": [{
                "account":"99999999999"
            },{
                "account":"6666666666"
            }]
        }
    </format>
    <args/>
</payloadFactory>
<iterate attachPath="json-eval($.payloadss)" expression="json-eval($.payloadss)" 
 id="iterate-over" preservePayload="true" continueParent="false">
    <target>
        <sequence>
            <property expression="json-eval($.payloadss.account)" name="accounte" scope="default" type="STRING"/>
            <call-template target="call_template_a">
                <with-param name="url" value="/getaccount"/>
                <with-param name="method_type" value="get"/>
            </call-template>
            [应用错误检查等...]
        </sequence>
    </target>
</iterate>
[使用与迭代相同的id,否则它将不起作用]
<property name="Aggregated_Responses" scope="default">
    <jsonObject/>
</property>
<aggregate description="iterate-over" id="iterate-over">
    <completeCondition timeout="120">
        <messageCount max="-1" min="-1"/>
    </completeCondition>
    [使用类似这样的表达式,否则它将不起作用,如果需要,您甚至可以在末尾添加/您的字段名称]
    <onComplete xmlns:ns="http://org.apache.synapse/xsd" expression="$body/*[1]" 
       enclosingElementProperty="Aggregated_Responses">
        [在这里,JSON将作为有效载荷,您可以选择使用脚本中介器来映射值并更改其名称,否则您只需返回结果,它将被聚合在一起]
        <property expression="json-eval($)" name="bbbb"/>
        <script language="js"><![CDATA[
            var dataFull = JSON.parse(mc.getProperty('bbbb')); 
            var responseList = [];
            var newJson = JSON.parse("{}");

            for (i = 0; i < dataFull.length; i++) {
                item = dataFull[i];
                newJson.newAccountNumber = item.accountNumber;
                responseList.push(newJson);
            }

            mc.setProperty("responseList", JSON.stringify(responseList));
        ]]></script>
        <payloadFactory media-type="json">
            <format>
                {
                    "data": $2
                }
            </format>
            <args>
                <arg evaluator="xml" expression="get-property('responseList')"/>
            </args>
        </payloadFactory>
        [发送应该在此级别,之后的代码将不会被执行]
        <send/>
    </onComplete>
</aggregate>
</sequence>

希望这可以帮助您!如果您需要进一步的帮助,请随时告诉我。

英文:

Final working solution with some explanation:

&lt;payloadFactory media-type=&quot;json&quot;&gt;
&lt;format&gt;
{               
&quot;payloadss&quot;: [{
&quot;account&quot;:&quot;99999999999&quot;
},{
&quot;account&quot;:&quot;6666666666&quot;
}]
}
&lt;/format&gt;
&lt;args/&gt;
&lt;/payloadFactory&gt;
&lt;iterate attachPath=&quot;json-eval($.payloadss)&quot; expression=&quot;json-eval($.payloadss)&quot; 
id=&quot;iterate-over&quot; preservePayload=&quot;true&quot; continueParent=&quot;false&quot;&gt;
&lt;target&gt;
&lt;sequence&gt;
&lt;property expression=&quot;json-eval($.payloadss.account)&quot; name=&quot;accounte&quot; scope=&quot;default&quot; type=&quot;STRING&quot;/&gt;
&lt;call-template target=&quot;call_template_a&quot;&gt;
&lt;with-param name=&quot;url&quot; value=&quot;/getaccount&quot;/&gt;
&lt;with-param name=&quot;method_type&quot; value=&quot;get&quot;/&gt;
&lt;/call-template&gt;
[.. apply error check etc .. ] 
&lt;/sequence&gt;
&lt;/target&gt;
&lt;/iterate&gt;
[ use same id as the iterate otherwise it wont work ]
&lt;property name=&quot;Aggregated_Responses&quot; scope=&quot;default&quot;&gt;
&lt;jsonObject/&gt;
&lt;/property&gt;
&lt;aggregate description=&quot;iterate-over&quot; id=&quot;iterate-over&quot;&gt;
&lt;completeCondition timeout=&quot;120&quot;&gt;
&lt;messageCount max=&quot;-1&quot; min=&quot;-1&quot;/&gt;
&lt;/completeCondition&gt;
[ use expression like this otherwise it wont work, you can even add at the end / 
your field name if needed ]
&lt;onComplete xmlns:ns=&quot;http://org.apache.synapse/xsd&quot; expression=&quot;$body/*[1]&quot; 
enclosingElementProperty=&quot;Aggregated_Responses&quot;&gt;
[ here the json will be as payload, optionnally you can have a script mediator 
to map the value and change in their names, otherwise you can just return the 
result and it
will be aggregated together]
&lt;property expression=&quot;json-eval($)&quot; name=&quot;bbbb&quot;/&gt;
&lt;script language=&quot;js&quot;&gt;&lt;![CDATA[
var dataFull = JSON.parse(mc.getProperty(&#39;bbbb&#39;)); 
var responseList = [];
var newJson = JSON.parse(&quot;{}&quot;);
for (i = 0; i &lt; dataFull.length; i++) {
item = dataFull[i];
newJson.newAccountNumber = item.accountNumber;
responseList.push(newJson);
}
mc.setProperty(&quot;responseList&quot;, JSON.stringify(responseList));
]]&gt;&lt;/script&gt;
&lt;payloadFactory media-type=&quot;json&quot;&gt;
&lt;format&gt;
{
&quot;data&quot;: $2
}
&lt;/format&gt;
&lt;args&gt;
&lt;arg evaluator=&quot;xml&quot; expression=&quot;get-property(&#39;responseList&#39;)&quot;/&gt;
&lt;/args&gt;
&lt;/payloadFactory&gt;
[ the send should be at this level, the code just after will not be executed] 
&lt;send/&gt;
&lt;/onComplete&gt;

</aggregate>
</sequence>

huangapple
  • 本文由 发表于 2023年7月10日 22:02:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76654531.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定