我在wso2esb中使用来自salesforce连接器的queryMore时遇到问题。我需要从Accounts中获取所有记录,然后将它们合并为一条消息并进一步处理(转换为csv并保存)。
Documentation for connector说我应该使用
<salesforce.query>
<batchSize>200</batchSize>
<queryString>select id,name from Account</queryString>
</salesforce.query>
<!-- Execute the following to get the other batches -->
<iterate xmlns:sfdc="http://wso2.org/salesforce/adaptor" continueParent="true" expression="//sfdc:iterator">
<target>
<sequence>
<salesforce.queryMore>
<batchSize>200</batchSize>
</salesforce.queryMore>
</sequence>
</target>
</iterate>
但是这永远不会增加&#34; queryLocator&#34;并一遍又一遍地查询同一批次。
我试图像这样改进它:
<salesforce.query>
<batchSize>200</batchSize>
<queryString>select id,name from Account limit 2042</queryString>
</salesforce.query>
<property name="MujQueryLocator" expression="get-property('salesforce.query.queryLocator')" scope="operation" type="STRING"/>
<log level="custom">
<property name="FirstQuery" expression="get-property('salesforce.query.queryLocator')"/>
<property xmlns:ns="urn:partner.soap.sforce.com" name="FirstQ --" expression="//ns:result/ns:queryLocator/text()"/>
<property name="MyLocator" expression="get-property('operation','MujQueryLocator')"/>
</log>
<iterate xmlns:sfdc="http://wso2.org/salesforce/adaptor" continueParent="true" expression="//sfdc:iterator" sequential="true">
<target>
<sequence>
<property name="salesforce.query.queryLocator" expression="get-property('operation','MujQueryLocator')" scope="default" type="STRING"/>
<log level="custom">
<property name=" BEFORE QueryMore" expression="get-property('salesforce.query.queryLocator')"/>
<property xmlns:ns="urn:partner.soap.sforce.com" name=" second " expression="//ns:result/ns:queryLocator/text()"/>
<property name="Muj locator -- " expression="get-property('operation','MujQueryLocator')"/>
</log>
<salesforce.queryMore>
<batchSize>200</batchSize>
</salesforce.queryMore>
<property xmlns:ns="urn:partner.soap.sforce.com" name="MujQueryLocator" expression="//ns:result/ns:queryLocator/text()" scope="operation" type="STRING"/>
<log level="custom">
<property name="AFTER QueryMore" expression="get-property('salesforce.query.queryLocator')"/>
<property xmlns:ns="urn:partner.soap.sforce.com" name="AFTER QM" expression="//ns:result/ns:queryLocator/text()"/>
<property name="AFTER MyQueryLocator " expression="get-property('operation','MujQueryLocator')"/>
</log>
<property xmlns:ns="urn:partner.soap.sforce.com" name="salesforce.query.queryLocator" expression="//ns:result/ns:queryLocator/text()" scope="default" type="STRING"/>
<log level="full"/>
<loopback/>
</sequence>
</target>
</iterate>
<respond/>
</inSequence>
<outSequence>
<aggregate>
<completeCondition>
<messageCount min="-1" max="-1"/>
</completeCondition>
<onComplete xmlns:ns="urn:partner.soap.sforce.com" expression="//ns:queryResponse|//ns:queryMoreResponse">
<enrich>
<source clone="true" xpath="//ns:records"/>
<target type="body" action="child"/>
</enrich>
<!-- HERE I WANTED FURTHER PROCESSING OF WHOLE MESSAGE>
</onComplete>
</aggregate>
</outSequence>
从现在开始,queryLocator正在递增,但并非总是如此,因此它会多次进行相同的查询,从而生成重复数据。在聚合消息中只有一个响应,它永远不会查询Account中的所有记录。见日志:
[2015-08-11 17:16:49,240] INFO - LogMediator Connection = Login to Salesforce .....
[2015-08-11 17:16:50,869] INFO - EndAFTERintContext EndAFTERint : AnonymousEndAFTERint currently SUSPENDED will now be marked active since it processed its last message
[2015-08-11 17:16:52,553] INFO - LogMediator PrvniQuery = 01gb0000023KfHsAAK-200, PrvniQuery vytazena -- = 01gb0000023KfHsAAK-200, MyQueryLocator = 01gb0000023KfHsAAK-200
[2015-08-11 17:16:52,572] INFO - LogMediator BEFORE QueryMore = 01gb0000023KfHsAAK-200, BEFORE QM in msg = , MyQueryLocator = 01gb0000023KfHsAAK-200
[2015-08-11 17:16:52,588] INFO - LogMediator BEFORE QueryMore = 01gb0000023KfHsAAK-200, BEFORE QM in msg = , MyQueryLocator = 01gb0000023KfHsAAK-200
[2015-08-11 17:16:52,722] INFO - LogMediator BEFORE QueryMore = 01gb0000023KfHsAAK-200, BEFORE QM in msg = , MyQueryLocator = 01gb0000023KfHsAAK-200
[2015-08-11 17:16:52,847] INFO - LogMediator BEFORE QueryMore = 01gb0000023KfHsAAK-200, BEFORE QM in msg = , MyQueryLocator = 01gb0000023KfHsAAK-200
[2015-08-11 17:16:52,982] INFO - LogMediator BEFORE QueryMore = 01gb0000023KfHsAAK-200, BEFORE QM in msg = , MyQueryLocator = 01gb0000023KfHsAAK-200
[2015-08-11 17:16:53,107] INFO - LogMediator BEFORE QueryMore = 01gb0000023KfHsAAK-200, BEFORE QM in msg = , MyQueryLocator = 01gb0000023KfHsAAK-200
[2015-08-11 17:16:53,247] INFO - LogMediator BEFORE QueryMore = 01gb0000023KfHsAAK-200, BEFORE QM in msg = , MyQueryLocator = 01gb0000023KfHsAAK-200
[2015-08-11 17:16:53,274] INFO - LogMediator --> AFTER QueryMore = 01gb0000023KfHsAAK-400, -- AFTER QM in msg = 01gb0000023KfHsAAK-400, MyQueryLocator = 01gb0000023KfHsAAK-400
[2015-08-11 17:16:53,281] INFO - LogMediator To: http://www.w3.org/2005/08/addressing/anonymous, WSAction: , SOAPAction: , MessageID: urn:uuid:112d95e0-df2c-4d39-acdc-88f0a3e82249, Direction: request, Envelope: <?xml version="1.0" encoding="utf-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="urn:partner.soap.sforce.com" xmlns:sf="urn:sobject.partner.soap.sforce.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Header><LimitInfoHeader><limitInfo><current>3390</current><limit>15000</limit><type>API REQUESTS</type></limitInfo></LimitInfoHeader></soapenv:Header><soapenv:Body><queryMoreResAFTERnse><result xsi:type="QueryResult"><done>false</done><queryLocator>01gb0000023KfHsAAK-400</queryLocator><records /records><size>2042</size></result></queryMoreResAFTERnse></soapenv:Body></soapenv:Envelope>
[2015-08-11 17:16:53,419] INFO - LogMediator BEFORE QueryMore = 01gb0000023KfHsAAK-400, BEFORE QM in msg = , MyQueryLocator = 01gb0000023KfHsAAK-400
[2015-08-11 17:16:53,576] INFO - LogMediator BEFORE QueryMore = 01gb0000023KfHsAAK-400, BEFORE QM in msg = , MyQueryLocator = 01gb0000023KfHsAAK-400
[2015-08-11 17:16:53,674] INFO - LogMediator --> AFTER QueryMore = 01gb0000023KfHsAAK-400, -- AFTER QM in msg = 01gb0000023KfHsAAK-400, MyQueryLocator = 01gb0000023KfHsAAK-400
...again message for 01gb0000023KfHsAAK-400
[2015-08-11 17:16:53,810] INFO - LogMediator --> AFTER QueryMore = 01gb0000023KfHsAAK-400, -- AFTER QM in msg = 01gb0000023KfHsAAK-400, MyQueryLocator = 01gb0000023KfHsAAK-400
...again message for 01gb0000023KfHsAAK-400
[2015-08-11 17:16:53,810] INFO - LogMediator --> AFTER QueryMore = 01gb0000023KfHsAAK-400, -- AFTER QM in msg -- = 01gb0000023KfHsAAK-400, MyQueryLocator = 01gb0000023KfHsAAK-400
....
.....after some time and repeats it increments to 01gb0000023KfHsAAK-600
...and so on
我不知道的另一件事是如何组合来自salesforce.query的响应和那些来自salesforce.queryMore的响应
ESB版本4.8.1
有人能够解释我这种行为吗?感谢
答案 0 :(得分:0)
根据你的描述,我的理解是你想要做的是“做什么”循环。我最近遇到了类似的情况,我发现的唯一解决方案是创建一个最终向自己发送消息的服务。
在我的情况下,我使用此消息来传递一些分页参数(开始记录和页面大小),这些参数在Salesforce案例中等同于batchSize和查询定位器参数。
代理的伪代码是这样的:
frameBox.WPointXChanged
请注意,此方法仅适用于调度序列由计划任务启动的情况或仅用于触发第一次调用的客户端。
答案 1 :(得分:0)
使用ESB 490和最新的salesforce连接器,您可以使用迭代器介体实现此目的。找到样本。
<salesforce.init>
<username>xxxxxx@gmail.com</username>
<password>xxxxxx</password>
<loginUrl>https://login.salesforce.com/services/Soap/u/34.0</loginUrl>
<blocking>true</blocking>
</salesforce.init>
<log level="custom">
<property name="salesforce" value="logged in, executing query"/>
</log>
<salesforce.query>
<batchSize>20</batchSize>
<queryString>select id,name from Account</queryString>
</salesforce.query>
<property name="opt.salesforce.query.queryLocator"
expression="$ctx:salesforce.query.queryLocator"
scope="operation"
type="STRING"/>
<iterate xmlns:sfdc="http://wso2.org/salesforce/adaptor"
expression="//sfdc:iterator"
sequential="true">
<target>
<sequence>
<property name="salesforce.query.queryLocator"
expression="get-property('operation','opt.salesforce.query.queryLocator')"
type="STRING"/>
<log level="custom">
<property name="Before ......................"
expression="$ctx:salesforce.query.queryLocator"/>
</log>
<salesforce.queryMore>
<batchSize>20</batchSize>
</salesforce.queryMore>
<property name="opt.salesforce.query.queryLocator"
expression="$ctx:salesforce.query.queryLocator"
scope="operation"
type="STRING"/>
<log level="custom">
<property name="After ......................"
expression="$ctx:salesforce.query.queryLocator"/>
</log>
</sequence>
</target>
</iterate>
答案 2 :(得分:0)
是的,你是对的。这是esb 490之前的唯一解决方案。使用esb 490引入了阻塞调用,并且我们可以使用iterator支持do-while。
您建议的方法(递归调用)对querymore调用的数量有限制,而迭代器调解器则不然。