Entity view (Content)

Salesforce, SAP, Twitter and Activiti BPM integration

By bfattouh
Sep. 11, 2014

In this post, I will illustrate a case to integrate Salesforce with SAP, Activiti BPM, a business process management platform, as well as Twitter. Mule ESB has wealth of cloud connectors that facilitate these kind of integration, and as such, we will show Salesforce, SAP, and Twitter cloud connectors can be used to simplify the integration, and achieve data synchronization between these systems seamlessly.

The benefits of this typical integration are outstanding; you can read more about these here [Ref. 1] .

The integration use cases are:
1. Sending a message to welcome a new customer via Twitter when an opportunity is closed as won in Salesforce.
2. A BPM process is created in Activiti that needs a human action to review, approve or reject the customer account creation.
3. Once the customer is approved in Activiti, other information may be added such as customer address etc ...
4. Once the account creation is approved in Activiti, the account is created in SAP.

Implementation details:
The connection to Salesforce can be achieved using the required credentials created by the Salesforce site. For more details, read here [Ref. 2] :

<mule>
<sfdc:config name="Salesforce" username="${salesforce.username}" password="${salesforce.password}" 
securityToken="${salesforce.securityToken}" doc:name="Salesforce"/>
</mule

The properties placeholders are declared in mule-app.properties file: 

#Salesforce
salesforce.username=
salesforce.password=
salesforce.securityToken=

The following shows the global connections to JMS Connector, Twitter [Ref. 3] and SAP [Ref. 4] :

<twitter:config name="Twitter" consumerKey="${twitter.consumerKey}"
consumerSecret="${twitter.consumerSecret}" 
doc:name="Twitter" accessKey="${twitter.accessKey}" accessSecret="${twitter.accessSecret}"/>

<sap:connector name="sap-connector" jcoAsHost="${sap.jcoAsHost}" jcoUser="${sap.jcoUser}"
validateConnections="true" <doc:name="sap" jcoclient="${sap.jcoClient}" jcopasswd="${sap.jcoPasswd}"
jcopeaklimit="${sap.jcoPeakLimit}" <br=""> jcoPoolCapacity="${sap.jcoPoolCapacity}"
jcoSysnr="${sap.jcoSysnr}" jcoLang="${sap.jcoLang}"/>

<jms:activemq-connector name="jms-connector" specification="1.1" brokerURL="${brokerURL}"
validateConnections="true" doc:name="Active MQ"/>

To capture in Mule the event of a closed and won Salesforce opportunity, we need to subscribe to the configured notification topic as shown within the following flow using the streaming API [Ref. 5] .  

Salesforce cloud connector facilitates the implementation of real time notifications of the Opportunity object updates as follow:

<flow name="businessLogic-flow" doc:name="businessLogic-flow"> 
 <sfdc:subscribe-topic config-ref="Salesforce" topic="/OpportunityUpdates" />
 <sfdc:query-single config-ref="Salesforce" query="select Id, Amount, StageName, Account.Name,
Account.BillingStreet, Account.BillingCity, Account.BillingState, Account.BillingPostalCode
from Opportunity where Id = '#[payload.Id]'" doc:name="Get oppt and account details"/>

 <logger level="INFO" message="Received an update from Opportunity with Payload: #[payload]"/>
 <jms:outbound-endpoint exchange-pattern="request-response" queue="sfdc2canonical.queue"
connector-ref="jms-connector" doc:name="sfdc2canonical.queue"/>

 <logger level="INFO" message="Payload json: #[payload]" doc:name="Logger"/>
 <jms:outbound-endpoint queue="closedOpportunity.queue" connector-ref="jms-connector"/>
</flow>

The following is the flow that captures the received message in the JMS queue and send it simultaneously to Twitter JMS queue as well as to Activiti JMS queue using the scatter gather router:

<flow name="opptClosedWon-flow" doc:name="opptClosedWon-flow">
<jms:inbound-endpoint queue="closedOpportunity.queue" connector-ref="jms-connector"/>
<filter doc:name="Closed Won opportunities Filter" ref="closedWonOppt-filter"/>
<scatter-gather doc:name="Scatter-Gather">
<jms:outbound-endpoint queue="tweetNewCustomer.queue" connector-ref="jms-connector" />
<jms:outbound-endpoint queue="accountCreation.queue" connector-ref="jms-connector" /> 
</scatter-gather>
</flow>

The following if the flow that sends the data as json payload to Activiti and creates a Task for the user to either approve the customer account creation or reject it. Here Activiti is used as a business process management system because we need to pause the process flow in Mule and involve a human intervention [Ref. 6] .

<flow name="activiti-bpm-flow" doc:name="activiti-bpm-flow">
<jms:inbound-endpoint connector-ref="jms-connector" queue="accountCreation.queue" />
<scripting:component doc:name="Prepare process start request">
     <scripting:script engine="Groovy">
           <![CDATA[
             import groovy.json.JsonSlurper; 
             import groovy.json.JsonBuilder; 
             def slurper = new JsonSlurper();
             def request = slurper.parseText(payload);
             request["processDefinitionKey"] = "bpm.accountCreationReviewProcess";
             return (new JsonBuilder(request)).toString();
          ]]></scripting:script>
</scripting:component>
<logger level="INFO" message="Payload before post to activiti-rest: #[payload]" doc:name="Logger"/>
<http:outbound-endpoint exchange-pattern="request-response" host="localhost" port="8080"
path="activiti-rest/service/process-instance" method="POST" doc:name="HTTP"
contentType="application/json" password="admin" user="admin"/>

</flow>

The attribute with the name: processDefinitionKey = bpm.accountCreationReviewProcess is refering to the created process using a separate java application. This application must contain the process of the customer account creation within a file customerCreationApprovalProcess.bpmn and deployed in Activiti.

Twitter connector allows connecting to twitter and post a welcome message to the new customer as illustrated with the following flow: 

<flow name="twitter-flow" doc:name="twitter-flow">
 <jms:inbound-endpoint connector-ref="jms-connector" queue="tweetNewCustomer.queue"
   doc:name="tweetNewCustomer.queue" />

 <set-payload value="Please welcome new Customer #[json:name]" doc:name="Set tweet"/>
 <twitter:update-status config-ref="twitter-conn" status="#[payload]" doc:name="Twitter"/>
</flow>

The following is the flow that processes the message that is received in the SAP JMS queue to create the customer Account as soon as it is approved by the user in Activiti.

<flow name="jms-queue-to-sap" doc:name="flow-frontend-out-toSAP">
 <jms:inbound-endpoint doc:name="sap-queue" queue="sap-queue" connector-ref="jms-connector"/>
 <sap:outbound-endpoint type="function" responseTimeout="10000" doc:name="SAP"
functionName="BAPI_CUSTOMER_CREATEFROMDATA" definitionFile="sap/customer-data.xml"    
connector-ref="sap-connector" exchange-pattern="request-response"/>
 <sap:object-to-xml xmlVersion="2" doc:name="SAP Object to XML"/>
 <object-to-string-transformer doc:name="Object to String"/>
 <logger message="Customer creation result: #[xpath:/jco/export/CUSTOMERNO]
#[xpath:/jco/export/RETURN/MESSAGE]" level="INFO" doc:name="Logger"/>
</flow>

References:

[Ref 1.] http://www.appnovation.com/technologies/mulesoft/salesforce-sap-integration
[Ref. 2] http://www.mulesoft.org/documentation/display/current/Connect+with+Salesforce+Example
[Ref. 3] http://www.mulesoft.org/documentation/display/current/Configure+Twitter+for+API+Access
[Ref. 4]
http://www.mulesoft.org/documentation/display/current/MuleSoft+Enterprise+Java+Connector+for+SAP+Reference
[Ref .5] http://blogs.mulesoft.org/get-real-time-with-the-new-salesforce-api/
[Ref. 6] http://www.activiti.org

Post Tags: