迭代中介vs salesforce连接器和queryMore查询重复项

迭代中介vs salesforce连接器和queryMore查询重复项,salesforce,wso2,wso2esb,connector,Salesforce,Wso2,Wso2esb,Connector,我在wso2esb中使用salesforce连接器中的queryMore时遇到问题。我需要从帐户中获取所有记录,然后将它们合并到一条消息中,并进一步将其转换为csv并保存 说我应该用 <salesforce.query> <batchSize>200</batchSize> <queryString>select id,name from Account</queryString> <

我在wso2esb中使用salesforce连接器中的queryMore时遇到问题。我需要从帐户中获取所有记录,然后将它们合并到一条消息中,并进一步将其转换为csv并保存

说我应该用

    <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>
但这永远不会增加queryLocator,并且一遍又一遍地查询同一批

我试着这样改进它:

<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将递增,但并不总是如此,它会多次执行相同的查询,从而生成重复数据。在聚合消息中,消息只是响应之一,它从不查询帐户中的所有记录。见日志:

[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


有人能解释我的这种行为吗?谢谢你的描述,我的理解是你想做的是一个边做边做的循环。我最近遇到了一个类似的情况,我找到的唯一解决方案是创建一个服务,在最后向自己发送消息

在我的例子中,我使用这个消息来传递一些分页参数start record和page size,在Salesforce的例子中,这些参数相当于batchSize和query locator参数

代理的伪代码如下所示:

if ( first call ) then
    do "query" api call;
else
    set "salesforce.query.queryLocator" property from request data;
    do "query more" api call;
end if;

process query results;

if ( "salesforce.query.done" property is not 'true') then
   create continuation message using the value of
   'salesforce.query.queryLocator' property;
   send one-way message to ESB;
end if;

请注意,此方法仅适用于由计划任务或仅用于触发第一次调用的客户端启动调解序列的场景。

根据您的描述,我的理解是您希望执行的是do-while循环。我最近遇到了一个类似的情况,我找到的唯一解决方案是创建一个服务,在最后向自己发送消息

在我的例子中,我使用这个消息来传递一些分页参数start record和page size,在Salesforce的例子中,这些参数相当于batchSize和query locator参数

代理的伪代码如下所示:

if ( first call ) then
    do "query" api call;
else
    set "salesforce.query.queryLocator" property from request data;
    do "query more" api call;
end if;

process query results;

if ( "salesforce.query.done" property is not 'true') then
   create continuation message using the value of
   'salesforce.query.queryLocator' property;
   send one-way message to ESB;
end if;

请注意,此方法仅适用于由计划任务或仅用于触发第一次调用的客户端启动中介序列的场景。

使用ESB 490和最新的salesforce connector,您可以使用迭代器中介来实现这一点。找到样品

     <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>

使用ESB490和最新的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>

是的,你是对的。这是ESB490之前的唯一解决方案。ESB490引入了阻塞调用,我们可以通过迭代器支持do-while


您建议的递归调用的方法对querymore调用的数量有限制,而迭代器中介的情况不是这样。

是的,您是正确的。这是ESB490之前的唯一解决方案。ESB490引入了阻塞调用,我们可以通过迭代器支持do-while

您建议的递归调用方法对querymore调用的数量有限制,而迭代器中介的情况并非如此