如何在没有 send/call 中介的情况下使用聚合中介
How to use Aggregate Mediator with out send/call mediator
我们有一个用例,我们必须遍历 json 对象数组并根据特定键值调用外部端点。所以我们使用了迭代器中介器、开关中介器(以匹配条件)和聚合中介器。
<?xml version="1.0" encoding="UTF-8"?>
<api context="/propertycheck" name="propertyCheck" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST">
<inSequence>
<iterate attachPath="json-eval($)" expression="json-eval($.main)" id="testingid" preservePayload="true" sequential="true">
<target>
<sequence>
<switch source="json-eval($.sub1)">
<case regex="a">
<log level="full" separator=","/>
<call>
<endpoint>
<http method="post" uri-template="http://localhost:3000/test">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>1</progressionFactor>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
</case>
<case regex="b">
<log level="full" separator=","/>
<call>
<endpoint>
<http method="post" uri-template="http://localhost:3000/test">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>1</progressionFactor>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
</case>
<case regex="c">
<log level="full" separator=","/>
<call>
<endpoint>
<http method="post" uri-template="http://localhost:3000/test">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>1</progressionFactor>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
</case>
<default>
<log>
<property name="default" value="defaultCase"/>
</log>
<payloadFactory media-type="json">
<format>{
"sub1":"My own Response"
}</format>
<args/>
</payloadFactory>
</default>
</switch>
</sequence>
</target>
</iterate>
<log/>
<aggregate id="testingid">
<correlateOn expression="json-eval($)"/>
<completeCondition>
<messageCount max="-1" min="-1"/>
</completeCondition>
<onComplete aggregateElementType="root" expression="json-eval($)">
<log>
<property expression="json-eval($)" name="outout"/>
</log>
</onComplete>
</aggregate>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
以上用例工作正常,当调用外部端点并将响应返回到聚合中介时,但我们必须在默认情况下构建响应而不调用端点,这如何实现?由于聚合中介只有在收到后端服务的响应后才会被触发。
我们也遵循了 post 中提供的答案:
这似乎也行不通,下面是根据 post 答案
的实施
<?xml version="1.0" encoding="UTF-8"?>
<api context="/propertycheck" name="propertyCheck" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST">
<inSequence>
<iterate attachPath="json-eval($)" expression="json-eval($.main)" id="testingid" preservePayload="true" sequential="true">
<target>
<sequence>
<switch source="json-eval($.sub1)">
<case regex="a">
<log level="full" separator=","/>
<call>
<endpoint>
<http method="post" uri-template="http://localhost:3000/test">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>1</progressionFactor>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
</case>
<case regex="b">
<log level="full" separator=","/>
<call>
<endpoint>
<http method="post" uri-template="http://localhost:3000/test">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>1</progressionFactor>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
</case>
<case regex="c">
<log level="full" separator=","/>
<call>
<endpoint>
<http method="post" uri-template="http://localhost:3000/test">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>1</progressionFactor>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
</case>
<default>
<log>
<property name="default" value="defaultCase"/>
</log>
<payloadFactory media-type="json">
<format>{
"sub1":"My own Response"
}</format>
<args/>
</payloadFactory>
<property name="RESPONSE" scope="default" type="STRING" value="true"/>
<sequence key="AggregateSequence"/>
</default>
</switch>
</sequence>
</target>
</iterate>
<log/>
<aggregate id="testingid">
<correlateOn expression="json-eval($)"/>
<completeCondition>
<messageCount max="-1" min="-1"/>
</completeCondition>
<onComplete aggregateElementType="root" expression="json-eval($)">
<log>
<property expression="json-eval($)" name="outout"/>
</log>
</onComplete>
</aggregate>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
聚合序列
<?xml version="1.0" encoding="UTF-8"?>
<sequence name="AggregateSequence" statistics="enable" trace="enable" xmlns="http://ws.apache.org/ns/synapse">
<log>
<property expression="json-eval($)" name="request to mediator"/>
</log>
<aggregate id="testingid">
<correlateOn expression="json-eval($)"/>
<completeCondition>
<messageCount max="-1" min="-1"/>
</completeCondition>
<onComplete aggregateElementType="root" expression="json-eval($)">
<log>
<property expression="json-eval($)" name="inside Aggregator"/>
</log>
</onComplete>
</aggregate>
</sequence>
要求
{
"main":[
{
"sub1":"a"
},
{
"sub1":"b"
},
{
"sub1":"c"
},
{
"sub1":"d"
}
]
}
感谢任何帮助。谢谢
当没有调用后端时,我认为我遇到了完全相同的问题。不确定它是否在文档中说明,无论如何我解决了它调用本地“echo”EI/ESB 服务”,而无需进行后端调用。
这是我如何解决它的片段。
<iterate xmlns:m0="http://ws.wso2.org/dataservice" expression="$body//m0:Entry" id="iteratorID" sequential="true">
<target>
<sequence>
<filter xpath="contains(get-property('schedulerHour'), get-property('currentHour')) and (contains($ctx:schedulerMinutes, $ctx:currentMinute))">
<then>
.... real backend should be called...
<call>
<endpoint>
<http uri-template="https://someURL"/>
</endpoint>
</call>
....
</then>
<else>
.... fake backend call...
<payloadFactory media-type="xml">
<format>
<p:echoInt xmlns:p="http://echo.services.core.carbon.wso2.org">
<in>123</in>
</p:echoInt>
</format>
<args/>
</payloadFactory>
<call>
<endpoint>
<http method="POST" uri-template="http://localhost:8280/services/echo"/>
</endpoint>
</call>
.....
</else>
</filter>
</sequence>
</target>
</iterate>
我们有一个用例,我们必须遍历 json 对象数组并根据特定键值调用外部端点。所以我们使用了迭代器中介器、开关中介器(以匹配条件)和聚合中介器。
<?xml version="1.0" encoding="UTF-8"?>
<api context="/propertycheck" name="propertyCheck" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST">
<inSequence>
<iterate attachPath="json-eval($)" expression="json-eval($.main)" id="testingid" preservePayload="true" sequential="true">
<target>
<sequence>
<switch source="json-eval($.sub1)">
<case regex="a">
<log level="full" separator=","/>
<call>
<endpoint>
<http method="post" uri-template="http://localhost:3000/test">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>1</progressionFactor>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
</case>
<case regex="b">
<log level="full" separator=","/>
<call>
<endpoint>
<http method="post" uri-template="http://localhost:3000/test">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>1</progressionFactor>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
</case>
<case regex="c">
<log level="full" separator=","/>
<call>
<endpoint>
<http method="post" uri-template="http://localhost:3000/test">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>1</progressionFactor>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
</case>
<default>
<log>
<property name="default" value="defaultCase"/>
</log>
<payloadFactory media-type="json">
<format>{
"sub1":"My own Response"
}</format>
<args/>
</payloadFactory>
</default>
</switch>
</sequence>
</target>
</iterate>
<log/>
<aggregate id="testingid">
<correlateOn expression="json-eval($)"/>
<completeCondition>
<messageCount max="-1" min="-1"/>
</completeCondition>
<onComplete aggregateElementType="root" expression="json-eval($)">
<log>
<property expression="json-eval($)" name="outout"/>
</log>
</onComplete>
</aggregate>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
以上用例工作正常,当调用外部端点并将响应返回到聚合中介时,但我们必须在默认情况下构建响应而不调用端点,这如何实现?由于聚合中介只有在收到后端服务的响应后才会被触发。
我们也遵循了 post 中提供的答案:
这似乎也行不通,下面是根据 post 答案
的实施<?xml version="1.0" encoding="UTF-8"?>
<api context="/propertycheck" name="propertyCheck" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST">
<inSequence>
<iterate attachPath="json-eval($)" expression="json-eval($.main)" id="testingid" preservePayload="true" sequential="true">
<target>
<sequence>
<switch source="json-eval($.sub1)">
<case regex="a">
<log level="full" separator=","/>
<call>
<endpoint>
<http method="post" uri-template="http://localhost:3000/test">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>1</progressionFactor>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
</case>
<case regex="b">
<log level="full" separator=","/>
<call>
<endpoint>
<http method="post" uri-template="http://localhost:3000/test">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>1</progressionFactor>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
</case>
<case regex="c">
<log level="full" separator=","/>
<call>
<endpoint>
<http method="post" uri-template="http://localhost:3000/test">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>1</progressionFactor>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
</case>
<default>
<log>
<property name="default" value="defaultCase"/>
</log>
<payloadFactory media-type="json">
<format>{
"sub1":"My own Response"
}</format>
<args/>
</payloadFactory>
<property name="RESPONSE" scope="default" type="STRING" value="true"/>
<sequence key="AggregateSequence"/>
</default>
</switch>
</sequence>
</target>
</iterate>
<log/>
<aggregate id="testingid">
<correlateOn expression="json-eval($)"/>
<completeCondition>
<messageCount max="-1" min="-1"/>
</completeCondition>
<onComplete aggregateElementType="root" expression="json-eval($)">
<log>
<property expression="json-eval($)" name="outout"/>
</log>
</onComplete>
</aggregate>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
聚合序列
<?xml version="1.0" encoding="UTF-8"?>
<sequence name="AggregateSequence" statistics="enable" trace="enable" xmlns="http://ws.apache.org/ns/synapse">
<log>
<property expression="json-eval($)" name="request to mediator"/>
</log>
<aggregate id="testingid">
<correlateOn expression="json-eval($)"/>
<completeCondition>
<messageCount max="-1" min="-1"/>
</completeCondition>
<onComplete aggregateElementType="root" expression="json-eval($)">
<log>
<property expression="json-eval($)" name="inside Aggregator"/>
</log>
</onComplete>
</aggregate>
</sequence>
要求
{
"main":[
{
"sub1":"a"
},
{
"sub1":"b"
},
{
"sub1":"c"
},
{
"sub1":"d"
}
]
}
感谢任何帮助。谢谢
当没有调用后端时,我认为我遇到了完全相同的问题。不确定它是否在文档中说明,无论如何我解决了它调用本地“echo”EI/ESB 服务”,而无需进行后端调用。
这是我如何解决它的片段。
<iterate xmlns:m0="http://ws.wso2.org/dataservice" expression="$body//m0:Entry" id="iteratorID" sequential="true">
<target>
<sequence>
<filter xpath="contains(get-property('schedulerHour'), get-property('currentHour')) and (contains($ctx:schedulerMinutes, $ctx:currentMinute))">
<then>
.... real backend should be called...
<call>
<endpoint>
<http uri-template="https://someURL"/>
</endpoint>
</call>
....
</then>
<else>
.... fake backend call...
<payloadFactory media-type="xml">
<format>
<p:echoInt xmlns:p="http://echo.services.core.carbon.wso2.org">
<in>123</in>
</p:echoInt>
</format>
<args/>
</payloadFactory>
<call>
<endpoint>
<http method="POST" uri-template="http://localhost:8280/services/echo"/>
</endpoint>
</call>
.....
</else>
</filter>
</sequence>
</target>
</iterate>