Showing posts with label WSO2 ESB. Show all posts
Showing posts with label WSO2 ESB. Show all posts

Thursday, March 15, 2018

Working with WSO2 kafka inbound endpoint

To use the Kafka inbound endpoint, download Apache Kafka.
To configure the Kafka inbound endpoint, copy the following client libraries from the <KAFKA_HOME>/lib directory to the <ESB_HOME>/repository/components/lib directory (Tested with ESB 4.9.0).
  • kafka_2.12-0.11.0.0.jar, 
  • scala-parser-combinators_2.12-1.0.4.jar, 
  • metrics-core-2.2.0.jar
  • kafka-clients-0.11.0.0.jar, 
  • zkclient-0.10.jar, 
  • metrics-core-3.2.2.jar, 
  • zookeeper-3.4.10.jar, 
  • scala-library-2.12.2.jar
Add jaas.conf file to <ESB_HOME>/repository/conf/security. Please refer this doc to get jaas.conf file.

Sample Inbound configuration

Following is a sample kafka configuration that can consume messages using the specified topic or topics :
<?xml version="1.0" encoding="UTF-8"?>
<inboundEndpoint xmlns="http://ws.apache.org/ns/synapse"
                 name="kafka"
                 sequence="request"
                 onError="fault"
                 class="org.wso2.carbon.inbound.kafka.KafkaMessageConsumer"
                 suspend="false">
   <parameters>
      <parameter name="coordination">true</parameter>
      <parameter name="interval">10</parameter>
      <parameter name="topic.names">test</parameter>
      <parameter name="value.deserializer">org.apache.kafka.common.serialization.StringDeserializer</parameter>
      <parameter name="bootstrap.servers">localhost:9092</parameter>
      <parameter name="poll.timeout">100</parameter>
      <parameter name="contentType">application/json</parameter>
      <parameter name="group.id">hello</parameter>
      <parameter name="key.deserializer">org.apache.kafka.common.serialization.StringDeserializer</parameter>
      <parameter name="inbound.behavior">polling</parameter>
      <parameter name="sequential">true</parameter>
   </parameters>
</inboundEndpoint>

It is also possible to add the above inbound configuration via the Management Console:














Run the following command to start the ZooKeeper server :

bin/zookeeper-server-start.sh config/zookeeper.properties

Run the following command to start the Kafka server :
bin/kafka-server-start.sh config/server.properties

Start the kafka producer using :
bin/kafka-console-producer.sh --broker-list localhost:9092 --topic test

After the executing the above command, a console will be prompt then send the following message using console producer :
{"test":"wso2"}

Configuring the sample scenario 

Create a sample sequence as below :
<?xml version="1.0" encoding="UTF-8"?>
<sequence name="request" onError="fault" xmlns="http://ws.apache.org/ns/synapse">
    <log level="full"/>
    <log level="custom">
        <property name="STATUS" value="Fetching inbound endpoint name"/>
        <property expression="$ctx:inbound.endpoint.name"
            name="inboundEndpointName" xmlns:ns="http://org.apache.synapse/xsd"/>
    </log>
</sequence>

The ESB console output will be like below :

[2018-03-15 15:08:38,436]  INFO - LogMediator To: , MessageID: 379c9c2a-7db1-4210-ba0f-7c550c93b9f3, Direction: request, Payload: {"test":"wso2"}
[2018-03-15 15:08:38,443]  INFO - LogMediator STATUS = Fetching inbound endpoint name, inboundEndpointName = kafka

Friday, September 15, 2017

WSO2 ESB Filter Mediator

Filter mediator is used to match or filter the message of a given xpath.

If we give only the xpath then it will return true or false. If we give regular expression, the string returned from evaluating the XPath will be matched against the regular expression.

There are two ways of operation

  • Specify the XPath (boolean expression), return true or false
  • XPath will be matched against the regular expression, return true or false

Examples :

<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="test"
       transports="http https"
       startOnLoad="true">
   <description/>
   <target>
      <inSequence>
         <property name="statusCode" value="200"/>
         <filter xpath="get-property('statusCode')!='204'">
            <then>
               <log level="custom">
                  <property name="----------Status Code--------------------------"
                            value="status code is not equals to 204"/>
               </log>
            </then>
         </filter>
      </inSequence>
      <outSequence>
         <send/>
      </outSequence>
   </target>
</proxy>

<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="test"
       transports="http https"
       startOnLoad="true">
   <description/>
   <target>
      <inSequence>
         <property name="statusCode" value="200"/>
         <filter source="get-property('statusCode')" regex="200">
            <then>
               <log level="custom">
                  <property name="----------Status Code--------------------------"
                            value="status code is equals to 200"/>
               </log>
            </then>
         </filter>
      </inSequence>
      <outSequence>
         <send/>
      </outSequence>
   </target>
</proxy>

Thursday, March 9, 2017

Invoke Salesforce REST API APEX classes using synapse mediators in WSO2 ESB

Invoke through sample synapse config(API/ Sequence/ Proxy) using following steps :

  • Download the salesforce REST connector from store.
  • Here, we use salesforce REST connector to maintain the access token and get the access token from the refresh token.
  • Open the <ESB_HOME>/repository/conf/axis2/axis2.xml and add the <parameter name="HttpsProtocols">TLSv1.1,TLSv1.2</parameter> entry inside the PassThroughHttpSSLSender element as below :
<transportSender name="https" class="org.apache.synapse.transport.passthru.PassThroughHttpSSLSender">
 .....
 <parameter name="HttpsProtocols">TLSv1.1,TLSv1.2</parameter>
 .....
</transportSender>
  • Start the WSO2 ESB Server.
  • Navigate to the management console and deploy the downloaded connector.
  • Click the Main tab on the Management Console, go to Manage -> Services and then click Proxy Service -> Custom Proxy. Click on switch to source view. Then add following and click on Save.
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="salesforceApex"
       startOnLoad="true"
       statistics="disable"
       trace="disable"
       transports="http">
   <target>
      <inSequence>
         <property expression="json-eval($.accessToken)" name="accessToken"/>
         <property expression="json-eval($.apiVersion)" name="apiVersion"/>
         <property expression="json-eval($.hostName)" name="hostName"/>
         <property expression="json-eval($.refreshToken)" name="refreshToken"/>
         <property expression="json-eval($.clientSecret)" name="clientSecret"/>
         <property expression="json-eval($.clientId)" name="clientId"/>
         <property expression="json-eval($.registryPath)" name="registryPath"/>
         <property expression="json-eval($.intervalTime)" name="intervalTime"/>
         <property expression="json-eval($.inputPayload)" name="inputPayload"/>
         <property expression="json-eval($.httpMethod)" name="httpMethod"/>
         <property expression="json-eval($.apexInstanceUrl)" name="apexInstanceUrl"/>
         <property expression="json-eval($.namespacePrefix)" name="namespacePrefix"/>
         <property expression="json-eval($.apexclassName)" name="apexclassName"/>
         <property expression="json-eval($.urlParameters)" name="urlParameters"/>
         <salesforcerest.init>
            <accessToken>{$ctx:accessToken}</accessToken>
            <apiVersion>{$ctx:apiVersion}</apiVersion>
            <clientId>{$ctx:clientId}</clientId>
            <clientSecret>{$ctx:clientSecret}</clientSecret>
            <refreshToken>{$ctx:refreshToken}</refreshToken>
            <hostName>{$ctx:hostName}</hostName>
            <registryPath>{$ctx:registryPath}</registryPath>
            <intervalTime>{$ctx:intervalTime}</intervalTime>
         </salesforcerest.init>
         <payloadFactory media-type="json">
<format>
                    $1
                </format>
            <args>
               <arg evaluator="xml" expression="get-property('inputPayload')"/>
            </args>
         </payloadFactory>
         <script language="js">//url param variables
                var namespacePrefix = mc.getProperty("namespacePrefix");
                var urlParameters = mc.getProperty("urlParameters");
                //url param processing start
                var urlParamString = '';
                if (namespacePrefix != "" &amp;&amp; namespacePrefix != null) {
                namespacePrefix = namespacePrefix + '/';
                }
                if (urlParameters != null &amp;&amp; urlParameters != "" &amp;&amp; urlParameters != {}) {
                var txt = '{"fieldValuesList":' + urlParameters + '}';
                var obj = eval ("(" + txt + ")");
                for(var key in obj.fieldValuesList){
                var fieldValue = obj.fieldValuesList[key];
                var field = key;
                urlParamString += field + "=" + fieldValue + "&amp;";
                }
                }
                if(urlParamString != '') {
                urlParamString = '?' + urlParamString.toString().substring(0, urlParamString.toString().lastIndexOf("&amp;"));
                }
                mc.setProperty('uri.var.namespacePrefix', namespacePrefix);
                mc.setProperty('uri.var.urlParamString', urlParamString);
                //url param processing end</script>
         <property action="remove" name="Accept-Encoding" scope="transport"/>
         <property expression="$ctx:apexInstanceUrl" name="uri.var.apexInstanceUrl"/>
         <property expression="$ctx:apexclassName" name="uri.var.apexclassName"/>
         <filter xpath="($ctx:httpMethod = 'post' or $ctx:httpMethod = 'POST')">
            <then>
               <call>
                  <endpoint>
                     <http method="POST"                           uri-template="{uri.var.apexInstanceUrl}/services/apexrest/{+uri.var.namespacePrefix}{uri.var.apexclassName}{+uri.var.urlParamString}"/>
                  </endpoint>
               </call>
            </then>
         </filter>
         <filter xpath="($ctx:httpMethod = 'get' or $ctx:httpMethod = 'GET')">
            <then>
               <call>
    <endpoint>
                     <http method="GET"                           uri-template="{uri.var.apexInstanceUrl}/services/apexrest/{+uri.var.namespacePrefix}{uri.var.apexclassName}{+uri.var.urlParamString}"/>
                  </endpoint>
               </call>
            </then>
         </filter>
         <filter xpath="($ctx:httpMethod = 'put' or $ctx:httpMethod = 'PUT')">
            <then>
               <call>
                  <endpoint>
                     <http method="PUT"                           uri-template="{uri.var.apexInstanceUrl}/services/apexrest/{+uri.var.namespacePrefix}{uri.var.apexclassName}{+uri.var.urlParamString}"/>
                  </endpoint>
               </call>
            </then>
         </filter>
         <filter xpath="($ctx:httpMethod = 'patch' or $ctx:httpMethod = 'PATCH')">
            <then>
               <call>
                  <endpoint>
                     <http method="PATCH"                           uri-template="{uri.var.apexInstanceUrl}/services/apexrest/{+uri.var.namespacePrefix}{uri.var.apexclassName}{+uri.var.urlParamString}"/>
                  </endpoint>
               </call>
            </then>
         </filter>
         <filter xpath="($ctx:httpMethod = 'delete' or $ctx:httpMethod = 'DELETE')">
            <then>
               <call>
                  <endpoint>
                     <http method="DELETE"                           uri-template="{uri.var.apexInstanceUrl}/services/apexrest/{+uri.var.namespacePrefix}{uri.var.apexclassName}{+uri.var.urlParamString}"/>
                  </endpoint>
               </call>
            </then>
         </filter>
         <filter xpath="($ctx:httpMethod = 'head' or $ctx:httpMethod = 'HEAD')">
            <then>
               <call>
                  <endpoint>
                     <http method="HEAD"                           uri-template="{uri.var.apexInstanceUrl}/services/apexrest/{+uri.var.namespacePrefix}{uri.var.apexclassName}{+uri.var.urlParamString}"/>
                  </endpoint>
</call>
            </then>
         </filter>
         <respond/>
      </inSequence>
   </target>
   <description/>
</proxy>             

  • Click the Main tab on the Management Console, go to Manage -> Services and then click List. Then click on “salesforceApex”. Under the Endpoints, you can find the http endpoint. With this http endpoint and the following request following payload, you can get the output. Here in this proxy service, we reuse the salesforce REST connector for refreshing the access token.
{ 
"accessToken":"00D6F000001Ndi6!ARMAQPHSxOeI3V1OOtHs8nm4v0cXJGRoqfEMWcPXsPy.1KP.LV_GA8uyM_VTLn3OuI8nWAAsA4Nrq4AGBUTBTBpg0dvEe7fy",
  "apiVersion": "v37.0",
  "clientId": "3MVG9YDQS5WtC11r7PwwtXgMbc11ddO8.v5fACou6XbISTmj5sWLnAFkgpXcjIxCJFtqfDsZL4.yunUQJaohk",
  "refreshToken": "5Aep861..zRMyCurAXnOWvxvIMAnUFVITuyCGAN6mPVNRczzrev5q9h0YI4m45COJYgeLgEorlUMZxm.YAeEE80",
  "clientSecret": "8631600822489897349",
  "hostName": "https://login.salesforce.com",
  "intervalTime" : "100000",
  "registryPath": "connectors/SalesforceRest",
  "apexInstanceUrl":"https://ap4.salesforce.com",
  "namespacePrefix": "TestOrgNew",
  "apexclassName":"AccountRestapiHandler",
  "httpMethod":"post",
  "urlParameters" : {
          "urlParameter1":"value1",
        "urlParameter2":"value2"
   },
  "inputPayload" : {
"AccountDetails":"[{\"getAccout\":{\"Phone\":\"95685695696\",\"Name\":\"TEST\",\"AccountNumber\":\"High\",\"Description\":\"Test\",\"SicDesc\":\"Test\"}}]",
       "TransactionId":"b22518b3",
       "SourceFile":"Sales"
    }
}

Tuesday, February 14, 2017

Sample ESB sequence and Inbound to receive the message from the queue using the ESB Amazon SQS streaming connector and then send that message into another queue using the ESB Amazon SQS connector

Sample ESB Sequence

<?xml version="1.0" encoding="UTF-8"?>
<sequence name="request" onError="fault" xmlns="http://ws.apache.org/ns/synapse">
    <log level="custom">
        <property expression="$body/*" name="------------" xmlns:ns="http://org.apache.synapse/xsd"/>
    </log>
    <property name="POST_TO_URI" scope="axis2" value="true"/>
    <call blocking="true">
        <endpoint>
            <http method="GET" uri-template="https://httpbin.org/get"/>
        </endpoint>
    </call>
    <property expression="$body/*" name="messageBody" xmlns:ns="http://org.apache.synapse/xsd"/>
    <amazonsqs.init>
        <secretAccessKey>xxxxxxxxxxxxxxxxxxxxx</secretAccessKey>
        <accessKeyId>xxxxxxxxxxxxxxxxxxxxx</accessKeyId>
        <version>2009-02-01</version>
        <region>us-east-1</region>
    </amazonsqs.init>
    <amazonsqs.sendMessage>
        <queueId>141823495686</queueId>
        <queueName>SQS_Inbound</queueName>
        <messageBody>{$ctx:messageBody}</messageBody>
    </amazonsqs.sendMessage>
</sequence>

Sample ESB Inbound

<?xml version="1.0" encoding="UTF-8"?>
<inboundEndpoint xmlns="http://ws.apache.org/ns/synapse"
                 name="amazon"
                 sequence="request"
                 onError="fault"
                 class="org.wso2.carbon.inbound.amazonsqs.AmazonSQSPollingConsumer"
                 suspend="false">
   <parameters>
      <parameter name="inbound.behavior">polling</parameter>
      <parameter name="interval">2000</parameter>
      <parameter name="sequential">true</parameter>
      <parameter name="coordination">true</parameter>
      <parameter name="attributeNames">attributeName1,contentType</parameter>
      <parameter name="accessKey">xxxxxxxxxxxxxxxxxxxxxxxxxx</parameter>
      <parameter name="waitTime">19</parameter>
      <parameter name="maxNoOfMessage">10</parameter>
      <parameter name="secretKey">xxxxxxxxxxxxxxxxxxxxxxxxxxxx</parameter>
      <parameter name="contentType">text/plain</parameter>
      <parameter name="destination">https://sqs.us-east-1.amazonaws.com/141823495686/SQS_Queue</parameter>
   </parameters>
</inboundEndpoint>

Wednesday, December 21, 2016

REQUEST_HOST_HEADER Property in WSO2 ESB

The value of this property will be set as the HTTP host header of outgoing request. ESB will set hostname of target endpoint as the HTTP host header.

Sample ESB Sequence


<?xml version="1.0" encoding="UTF-8"?>
<sequence name="request" onError="fault" xmlns="http://ws.apache.org/ns/synapse">
    <property name="REQUEST_HOST_HEADER" scope="axis2" value="httpbin.org"/>
    <log level="full"/>
    <call blocking="true">
        <endpoint>
            <http method="GET" uri-template="http://httpbin.org/get"/>
        </endpoint>
    </call>
</sequence>

Sample Response


[2016-12-21 22:09:08,496] DEBUG - headers http-outgoing-1 >> GET /get HTTP/1.1
[2016-12-21 22:09:08,497] DEBUG - headers http-outgoing-1 >> Host: httpbin.org
[2016-12-21 22:09:08,497] DEBUG - headers http-outgoing-1 >> Connection: Keep-Alive
[2016-12-21 22:09:08,497] DEBUG - headers http-outgoing-1 >> User-Agent: Synapse-PT-HttpComponents-NIO
[2016-12-21 22:09:08,498] DEBUG - wire HTTP-Sender I/O dispatcher-1 << "GET /get HTTP/1.1[\r][\n]"
[2016-12-21 22:09:08,498] DEBUG - wire HTTP-Sender I/O dispatcher-1 << "Host: httpbin.org[\r][\n]"
[2016-12-21 22:09:08,498] DEBUG - wire HTTP-Sender I/O dispatcher-1 << "Connection: Keep-Alive[\r][\n]"
[2016-12-21 22:09:08,498] DEBUG - wire HTTP-Sender I/O dispatcher-1 << "User-Agent: Synapse-PT-HttpComponents-NIO[\r][\n]"
[2016-12-21 22:09:08,498] DEBUG - wire HTTP-Sender I/O dispatcher-1 << "[\r][\n]"
[2016-12-21 22:09:08,866] DEBUG - wire HTTP-Sender I/O dispatcher-1 >> "HTTP/1.1 200 OK[\r][\n]"
[2016-12-21 22:09:08,866] DEBUG - wire HTTP-Sender I/O dispatcher-1 >> "Server: nginx[\r][\n]"
[2016-12-21 22:09:08,866] DEBUG - wire HTTP-Sender I/O dispatcher-1 >> "Date: Wed, 21 Dec 2016 16:39:08 GMT[\r][\n]"
[2016-12-21 22:09:08,867] DEBUG - wire HTTP-Sender I/O dispatcher-1 >> "Content-Type: application/json[\r][\n]"
[2016-12-21 22:09:08,867] DEBUG - wire HTTP-Sender I/O dispatcher-1 >> "Content-Length: 182[\r][\n]"
[2016-12-21 22:09:08,867] DEBUG - wire HTTP-Sender I/O dispatcher-1 >> "Connection: keep-alive[\r][\n]"
[2016-12-21 22:09:08,867] DEBUG - wire HTTP-Sender I/O dispatcher-1 >> "Access-Control-Allow-Origin: *[\r][\n]"
[2016-12-21 22:09:08,867] DEBUG - wire HTTP-Sender I/O dispatcher-1 >> "Access-Control-Allow-Credentials: true[\r][\n]"
[2016-12-21 22:09:08,867] DEBUG - wire HTTP-Sender I/O dispatcher-1 >> "[\r][\n]"
[2016-12-21 22:09:08,867] DEBUG - wire HTTP-Sender I/O dispatcher-1 >> "{[\n]"
[2016-12-21 22:09:08,867] DEBUG - wire HTTP-Sender I/O dispatcher-1 >> "  "args": {}, [\n]"
[2016-12-21 22:09:08,867] DEBUG - wire HTTP-Sender I/O dispatcher-1 >> "  "headers": {[\n]"
[2016-12-21 22:09:08,867] DEBUG - wire HTTP-Sender I/O dispatcher-1 >> "    "Host": "httpbin.org", [\n]"
[2016-12-21 22:09:08,868] DEBUG - wire HTTP-Sender I/O dispatcher-1 >> "    "User-Agent": "Synapse-PT-HttpComponents-NIO"[\n]"
[2016-12-21 22:09:08,868] DEBUG - wire HTTP-Sender I/O dispatcher-1 >> "  }, [\n]"
[2016-12-21 22:09:08,868] DEBUG - wire HTTP-Sender I/O dispatcher-1 >> "  "origin": "123.231.111.7", [\n]"
[2016-12-21 22:09:08,868] DEBUG - wire HTTP-Sender I/O dispatcher-1 >> "  "url": "http://httpbin.org/get"[\n]"
[2016-12-21 22:09:08,868] DEBUG - wire HTTP-Sender I/O dispatcher-1 >> "}[\n]"

Wednesday, December 14, 2016

Sample sequence to call https backend service

Here is the sample sequence to call HTTPS backend service


<?xml version="1.0" encoding="UTF-8"?>  
 <sequence xmlns="http://ws.apache.org/ns/synapse" name="request" onError="fault">  
   <log level="full"/>  
   <property name="POST_TO_URI" value="true" scope="axis2"/>  
   <call blocking="true">  
    <endpoint>  
      <http method="GET" uri-template="https://httpbin.org/get"/>  
    </endpoint>  
   </call>  
 </sequence>

Here the HTTP endpoint allows you to define REST endpoints using URI templates.

You can use HTTP endpoint Syntex as below,


<http uri-template="URI Template" method="GET|POST|PUSH|PUT|DELETE|OPTIONS|HEAD" />

HTTP Endpoint Attributes
  • uri-template - The URI template that constructs the RESTful endpoint URL at runtime.
  • method - The HTTP method to use during the invocation.
Call mediator

The Call mediator is used to send messages out of the ESB to an endpoint. You can call services either in blocking or non-blocking manner. When you call a service in non-blocking mode, the worker thread returns without waiting for the response from back-end service. In blocking mode, the underlying worker thread gets blocked and waits for the response after sending the request to the endpoint. Call mediator in blocking mode is similar to the Callout mediator.

Use Case – Salesforce REST Connector + Power Bi connector

This page describes a connector scenario by integrating the Salesforce REST Connector with the Power Bi connector. For example you can use the Salesforce REST Connector to get the account details (Eg :- Id, Name, Account type of the records in your organization) from Salesforce and add that account details into table in the dataset of Power Bi using addRows operation in the Power Bi connector.


  1. Get the account details from the Salesforce using query operation.
  2. Add the account details into the Power Bi using the addRows operation.

Environment setup for running the above use cases

  • Download ESB 5.0.0 from here.
  • Upload the following connectors to the ESB:
  • Follow the instructions given in the developer guide of the above connectors.
  •  Import the certificate into the ESB client keystore to use the Salesforce REST connector. Refer this link to import the certificate.  
  • Creating the credentials to use the Power Bi Connector:
    1. Create a Office 365 E3 trial account.
    2. Navigate to the URL https://login.microsoftonline.com/login.srf and login with Microsoft account which is created in step 1 .
    3. Navigate to the URL https://powerbi.microsoft.com/en-us/ and signup for a Power Bi account using the previously created Microsoft account.
    4. Create a dataset and keep the dataset name for further use.
    5. Enable PowerBI pro by using the popup by selecting the "Create Group" option.
    6. Create a group in PowerBI.
    7. Navigate to the URL https://app.powerbi.com/apps.
             Step 1 - Login using Power BI account which used in step 2 .
             Step 2 - Provide App Name, Redirect URL, App Type and Home Page URL and for App Type use "Server-side Web app". Note Redirect URL for further use.
             Step 3 - select all the check boxes to enable access for the api.
             Step 4 - Click "Register App" and note client-id and client-secret that are returned for further use.
    8. Generate the authorization code by sending a GET request using url https://login.windows.net/common/oauth2/authorize?response_type=code&client_id=<client-id>&resource=https://analysis.windows.net/powerbi/api&redirect_uri=<Redirect URL>.
  • Creating the credentials to use the Salesforce REST Connector:

    Sample configuration


    Following is a sample proxy service that illustrates how to test the above scenario.

    Sample proxy


     <?xml version="1.0" encoding="UTF-8"?>  
     <proxy xmlns="http://ws.apache.org/ns/synapse"  
         name="importdataintoPowerbi"  
         startOnLoad="true"  
         statistics="disable"  
         trace="disable"  
         transports="http,https">  
       <target>  
        <inSequence>  
          <property expression="json-eval($.salesforceRESTHostName)"  
               name="salesforceREST.hostName"/>  
          <property expression="json-eval($.salesforceRESTRefreshToken)"  
               name="salesforceREST.refreshToken"/>  
          <property expression="json-eval($.salesforceRESTClientSecret)"  
               name="salesforceREST.clientSecret"/>  
          <property expression="json-eval($.salesforceRESTClientId)"  
               name="salesforceREST.clientId"/>  
          <property expression="json-eval($.salesforceRESTAccessToken)"  
               name="salesforceREST.accessToken"/>  
          <property expression="json-eval($.salesforceRESTQueryString)"  
               name="salesforceREST.queryString"/>  
          <property expression="json-eval($.salesforceRESTApiVersion)"  
               name="salesforceREST.apiVersion"/>  
          <property expression="json-eval($.salesforceRESTApiUrl)"  
               name="salesforceREST.apiUrl"/>  
          <property expression="json-eval($.salesforceRESTIntervalTime)"  
               name="salesforceREST.intervalTime"/>  
          <property expression="json-eval($.salesforceRESTRegistryPath)"  
               name="salesforceREST.registryPath"/>  
          <property expression="json-eval($.powerbiAccessToken)" name="powerbi.accessToken"/>  
          <property expression="json-eval($.powerbiRefreshToken)"  
               name="powerbi.refreshToken"/>  
          <property expression="json-eval($.powerbiClientId)" name="powerbi.clientId"/>  
          <property expression="json-eval($.powerbiClientSecret)"  
               name="powerbi.clientSecret"/>  
          <property expression="json-eval($.powerbiApiUrl)" name="powerbi.apiUrl"/>  
          <property expression="json-eval($.datasetId)" name="powerbi.datasetId"/>  
          <property expression="json-eval($.tableName)" name="powerbi.tableName"/>  
          <property name="fields" scope="operation" value="["/>  
          <property name="length" scope="operation" value=""/>  
          <salesforcerest.init>  
           <apiVersion>{$ctx:salesforceREST.apiVersion}</apiVersion>  
           <hostName>{$ctx:salesforceREST.hostName}</hostName>  
           <accessToken>{$ctx:salesforceREST.accessToken}</accessToken>  
           <refreshToken>{$ctx:salesforceREST.refreshToken}</refreshToken>  
           <clientSecret>{$ctx:salesforceREST.clientSecret}</clientSecret>  
           <clientId>{$ctx:salesforceREST.clientId}</clientId>  
           <apiUrl>{$ctx:salesforceREST.apiUrl}</apiUrl>  
           <intervalTime>{$ctx:salesforceREST.intervalTime}</intervalTime>  
           <registryPath>{$ctx:salesforceREST.registryPath}</registryPath>  
          </salesforcerest.init>  
          <salesforcerest.query>  
           <queryString>{$ctx:salesforceREST.queryString}</queryString>  
          </salesforcerest.query>  
          <property expression="//records" name="records"/>  
          <iterate continueParent="true"  
              description=""  
              expression="//records"  
              id="records_iterator"  
              sequential="true">  
           <target>  
             <sequence>  
              <property expression="json-eval($.records)" name="records"/>  
              <property expression="get-property('operation','fields')" name="fields"/>  
              <script language="js">  
                   var records = mc.getProperty("records");                
                   var obj = eval ("(" + records + ")");  
                   var ans;  
                   var fields = mc.getProperty("fields");  
                   fields = fields.concat("{");               
                   var Id = obj['Id'];  
                   var Name = obj['Name'];  
                   var AccountType = obj.attributes['type'];  
                   if(Id !="" &amp;&amp; Id !=null &amp;&amp; Name !="" &amp;&amp; Name !=null){  
                     fields = fields.concat('"Id"' + ':"' + Id + '","Name"' + ':"' + Name + '","AccountType"' + ':"' + AccountType + '"');  
                   }  
                   fields = fields.concat("},");  
                   mc.setProperty("fields",fields);  
                   mc.setProperty("length",fields.length());  
              </script>  
              <property expression="get-property('fields')" name="fields" scope="operation"/>  
              <property expression="get-property('length')" name="length" scope="operation"/>  
             </sequence>  
           </target>  
          </iterate>  
          <property expression="get-property('operation','fields')"  
               name="fields"  
               scope="operation"/>  
          <property expression="get-property('operation','length')"  
               name="length"  
               scope="operation"/>  
          <property expression="fn:concat(fn:substring(get-property('operation','fields'),0,get-property('operation','length')),']')"  
               name="values"/>  
          <powerbi.init>  
           <accessToken>{$ctx:powerbi.accessToken}</accessToken>  
           <refreshToken>{$ctx:powerbi.refreshToken}</refreshToken>  
           <clientId>{$ctx:powerbi.clientId}</clientId>  
           <clientSecret>{$ctx:powerbi.clientSecret}</clientSecret>  
           <apiUrl>{$ctx:powerbi.apiUrl}</apiUrl>  
          </powerbi.init>  
          <powerbi.addRows>  
           <datasetId>{$ctx:powerbi.datasetId}</datasetId>  
           <tableName>{$ctx:powerbi.tableName}</tableName>  
           <rows>{$ctx:values}</rows>  
          </powerbi.addRows>  
          <property expression="$axis2:HTTP_SC" name="addRowsStatusCode"/>  
          <filter regex="true"  
              source="get-property('addRowsStatusCode') != 200">  
           <then>  
             <log level="full"/>  
             <property name="message" value="Unable to Insert the row "/>  
             <loopback/>  
           </then>  
           <else>  
             <log level="full"/>  
             <property name="message" value="Success: Successfully Import the Data"/>  
             <loopback/>  
           </else>  
          </filter>  
          <respond/>  
          <send/>  
        </inSequence>  
        <outSequence>  
          <property name="messageType" scope="axis2" value="application/json"/>  
          <payloadFactory media-type="json">  
           <format>  
               {  
               "Response":{  
               "process":"ImportDataIntoPowerBi",  
               "activityResponse":"$1"  
               }  
               }  
             </format>  
           <args>  
             <arg evaluator="xml" expression="get-property('message')"/>  
           </args>  
          </payloadFactory>  
          <log/>  
          <send/>  
        </outSequence>  
       </target>  
       <description/>  
     </proxy>
    
    Sample request


    {  
      "powerbiAccessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ikk2b0J3NFZ6QkhPcWxlR3JWMkFKZEE1RW1YYyIsImtpZCI6Ikk2b0J3NFZ6QkhPcWxlR3JWMkFKZEE1RW1YYyJ9.eyJhdWQiOiJodHRwczovL2FuYWx5c2lzLndpbmRvd3MubmV0L3Bvd2VyYmkvYXBpIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvNDg1NWRjNDEtNmU4MS00YTdkLWJhOGYtZGM5NGNiMGI3NTE3LyIsImlhdCI6MTQ3OTAzMTg1MywibmJmIjoxNDc5MDMxODUzLCJleHAiOjE0NzkwMzU3NTMsImFjciI6IjEiLCJhbXIiOlsicHdkIl0sImFwcGlkIjoiNTAyMDgxM2QtOTgzMC00NDk0LWE4MjYtYTU3MDVhMmIxZTRhIiwiYXBwaWRhY3IiOiIxIiwiZmFtaWx5X25hbWUiOiJHbmFuZXN3YXJhbiIsImdpdmVuX25hbWUiOiJCaXJ1bnRoYSIsImlwYWRkciI6IjE3NS4xNTcuMjQ0LjIiLCJuYW1lIjoiQmlydW50aGEgR25hbmVzd2FyYW4iLCJvaWQiOiIzZWM1MDc0ZC1jOTVhLTRmZWQtOWEzZS1hNTM0YzE1ZjE5YzQiLCJwbGF0ZiI6IjE0IiwicHVpZCI6IjEwMDNCRkZEOUJGM0ZGQ0EiLCJzY3AiOiJEYXNoYm9hcmQuUmVhZC5BbGwgRGF0YXNldC5SZWFkV3JpdGUuQWxsIEdyb3VwLlJlYWQgUmVwb3J0LlJlYWQuQWxsIiwic3ViIjoidG9ZaTAteFNDT3hYSTV4eTB2QkZuWmdzTjc5N2hXV3l6YWxBQnJISVF0USIsInRpZCI6IjQ4NTVkYzQxLTZlODEtNGE3ZC1iYThmLWRjOTRjYjBiNzUxNyIsInVuaXF1ZV9uYW1lIjoiYmlydW50aGFAZ25hbmVzLm9ubWljcm9zb2Z0LmNvbSIsInVwbiI6ImJpcnVudGhhQGduYW5lcy5vbm1pY3Jvc29mdC5jb20iLCJ2ZXIiOiIxLjAiLCJ3aWRzIjpbIjYyZTkwMzk0LTY5ZjUtNDIzNy05MTkwLTAxMjE3NzE0NWUxMCJdfQ.f5HoxDyvi3EcjmKzUCzKobq1jjGECm68bfbGAn72SXOOwqYG9IkvzOuhR_4UL0BSp-E7wex9MqkrGUK0b0rJ1awg8kF7Y5ICjnIiuEHK7jLJf5DEEMb91tBRo3mMgBrri_UR7V0MIBG5IRMtbBiAIZCn-dZw9izCc3pOb9J3rx7ifMdda5frKqF3gQXUGl_814PXQia5EGxcTAfVcBbvcgTZ7FQjzidgI0qzoirNtZshrFzAqj7N1_2WpOlVC-XugA4Oi5vOcm2A3LHZYhYrk1GoqJga8liyUALWDyrKsvyPHGO9dEoYFVCgBK-48envJWlzOO987rI6MACWz8QmIg",  
      "powerbiRefreshToken": "AQABAAAAAADRNYRQ3dhRSrm-4K-adpCJ0Bc0NMKTefb1M1UhZxzmA3v3afmAGpsz_3ISKe49U594Luh4vS53BoCWlAG0vlAv3y5gwhtln1smhbBM6-XZSjYvhgYrGMExiCnX92VPbqI61kYOnOrLtQ8MypdDMdoEotp0VIw3wMV-Pa9qU2J7DhPG0_r7V1b-ZqhQy0PZRRH7RTHelDLpCGsKHYNTqdgFH10GO8JOCHDwImXO5uMBgrxkI9hsAgYw-kc4HvSX8Ah8HXjfHGD3i90Rc79J0mA0eeL4knNkEKyBuXE7CVrEyFUKk6ijybCneHRUOC2_ejY2C04W3S4Us7TlC8rLOAo3Tz6JTF5gpTlmJ7QSF5k_7yiIT0ZmnloVfzCorkqxpcVX0rheQ3b83zX7I4VnEjsdUlIsvcV4QXPbQTcuNRsmEKZHErRph_8F-eG-gxUOBh4DWMss8FPylD8_tioscFIcMhC7aOXglOVnUNESFgJhcp8L0duu64Twn_9b1mCSlMXw8bM8ASm7QabHTnxXGmQHCGmehtd3Df9dIaAbXjwtwkxOSJjAlvGdjGoThO1IJ9gO5fMhaCRicfC8rkVQVsWaP_-sgeZtMFKyItT43C3CiWhPLQbKYwuOeJvWrHtw6z4A4oKPLJ-ALwMBDj8ffkiKjtdAHvpT5K3NQeVcMCkJnvkinLfSUo_--GSoxeWmJpktAhVIv8f8MB-TLUXc5DhufPUrZs1ofPTTZegzild9e-aob_K95zE_tzbvJa_cDF8gAA",  
      "powerbiClientId": "5020813d-9830-4494-a826-a5705a2b1e4a",  
      "powerbiClientSecret": "I+mhnYnSKqnsZmORLtPO5vbJCSnDRdP9J3xUyTPez24=",  
      "powerbiApiUrl": "https://api.powerbi.com",  
      "datasetId": "dd2defac-d062-4262-a9a9-00c1071723b8",  
      "tableName":"Records",  
      "salesforceRESTHostName": "https://login.salesforce.com",  
      "salesforceRESTRefreshToken": "5Aep861TSESvWeug_xCxj8yFaTjeV0kXa8X.gg5d1ipArZn7qABXj_BUgpsSVDvRfMNJtYwqnie1JejvB_GrLnJ",  
      "salesforceRESTClientSecret": "3543063387981089204",  
      "salesforceRESTClientId": "3MVG9ZL0ppGP5UrDt0n2ptTJ_fWBXDlYYXTic9.ApotX3azPQhMX2dw_gXGQ1JyPwTLWjrnCB.0K3vpUJV3Jv",  
      "salesforceRESTAccessToken": "00D28000000avoo!ARoAQGVqGhimwqewU5TNG1Uf4geWWRx9gV13sDffT1zXFHY_mAl158PI1wqfiAsH6uMOJfp5kzps0ERHXxTXpY8GWfNIltID",  
      "salesforceRESTQueryString": "select id, name from Account limit 4",  
      "salesforceRESTApiVersion": "v32.0",  
      "salesforceRESTApiUrl": "https://ap2.salesforce.com",  
      "salesforceRESTIntervalTime": "2400000",  
      "salesforceRESTRegistryPath": "connectors/salesforcerest"  
     }