Salesforce and Mule ESB Integration
Learn the steps to set up an integration between Mule ESB and the customer success platform Salesforce in this tutorial.
Join the DZone community and get the full member experience.
Join For FreeThe Salesforce connector establishes a connection to the Salesforce system using a SOAP web service (provided by Salesforce). Almost every operation that can be done via the Salesforce API can be done through this connector. This connector will also work if your Salesforce objects are customized with additional fields, or even if you are working with custom objects. The connector supports the option to configure Salesforce connection details, connection pooling, and max limit of active connections.
Configuration: This element must be placed outside of your flows and at the root of your Mule application. You can create as many configurations as you deem necessary as long as each carries its own name.
Connection Pool: The Salesforce connector offers automatic connection management via the use of a connection pool. The pool will act as a storage mechanism for all the connections that are in use by the user of this connector.
Reconnection Strategies: Reconnection strategies specify how a connector behaves when its connection fails. You can control how Mule attempts to reconnect by specifying a number of criteria.
Prerequisites
Create a Salesforce account if you don't have one.
Reset the Security Token. Go to My Settings > personal > reset my security token. Click "Reset Security Token" and it will send a security token to your registered email.
Create an Accounts View with Postal Code in Salesforce.
Create a new object as per the requirement, or use an existing one.
Create a Mule Flow to perform business logic and integration.
Mule Flow:
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:batch="http://www.mulesoft.org/schema/mule/batch" xmlns:schedulers="http://www.mulesoft.org/schema/mule/schedulers" xmlns:metadata="http://www.mulesoft.org/schema/mule/metadata" xmlns:dw="http://www.mulesoft.org/schema/mule/ee/dw" xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking" xmlns:vm="http://www.mulesoft.org/schema/mule/vm"
xmlns:file="http://www.mulesoft.org/schema/mule/file"
xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.mulesoft.org/schema/mule/vm http://www.mulesoft.org/schema/mule/vm/current/mule-vm.xsd
http://www.mulesoft.org/schema/mule/file http://www.mulesoft.org/schema/mule/file/current/mule-file.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd
http://www.mulesoft.org/schema/mule/ee/dw http://www.mulesoft.org/schema/mule/ee/dw/current/dw.xsd
http://www.mulesoft.org/schema/mule/batch http://www.mulesoft.org/schema/mule/batch/current/mule-batch.xsd
http://www.mulesoft.org/schema/mule/schedulers http://www.mulesoft.org/schema/mule/schedulers/current/mule-schedulers.xsd">
<http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8091" doc:name="HTTP Listener Configuration"/>
<queued-asynchronous-processing-strategy name="Queued_Asynchronous_Processing_Strategy" maxThreads="100" minThreads="20" threadTTL="10000" doc:name="Queued Asynchronous Processing Strategy"/>
<flow name="KelltontechSolution-SalseForce" processingStrategy="synchronous">
<composite-source doc:name="Composite Source">
<http:listener config-ref="HTTP_Listener_Configuration" path="/SalseForceData" allowedMethods="POST" doc:name="HTTP"/>
<file:inbound-endpoint path="src/main/resources/readFile/" responseTimeout="10000" doc:name="File prrocess" moveToDirectory="src/main/resources/uploadedFile/"/>
<vm:inbound-endpoint exchange-pattern="one-way" path="dataque" doc:name="dataque VM"/>
</composite-source>
<byte-array-to-string-transformer doc:name="Byte Array to String"/>
<choice doc:name="Choice">
<when expression="#[message.inboundProperties['MULE_ENDPOINT']]">
<dw:transform-message doc:name="Action Valriable" metadata:id="f64ef5c2-5bbd-43d7-bced-faa307b52d79">
<dw:input-payload doc:sample="insert-json\InsertJson.json" mimeType="application/json"/>
<dw:set-session-variable variableName="actionValidatonValue"><![CDATA[%dw 1.0
%output application/java
%var actionCheck = payload.action
---
actionCheck
]]></dw:set-session-variable>
</dw:transform-message>
<logger message="VM #[payload]" level="INFO" doc:name="Vm Logger"/>
<flow-ref name="VM-Process-Subflow" doc:name="VM-Process-Subflow"/>
<vm:outbound-endpoint exchange-pattern="one-way" path="resposneQueue" doc:name="VM"/>
</when>
<when expression="#[message.inboundProperties['http.scheme']]">
<dw:transform-message doc:name="Action Valriable">
<dw:set-session-variable variableName="actionValidatonValue"><![CDATA[%dw 1.0
%output application/java
%var actionCheck = payload.action
---
actionCheck]]></dw:set-session-variable>
</dw:transform-message>
<logger message="Http : #[payload]" level="INFO" doc:name="http Logger"/>
<flow-ref name="Http-Process-Subflow" doc:name="Http-Process-Subflow"/>
</when>
<when expression="#[message.inboundProperties['originalDirectory']]">
<logger message="File: #[payload]" level="INFO" doc:name="file Logger"/>
<flow-ref name="File-Process-Subflow" doc:name="File-Process-Subflow"/>
<set-payload value="#[payload]" doc:name="Set Payload"/>
</when>
<otherwise>
<logger message="This data is not valid!!" level="INFO" doc:name="Else Logger"/>
</otherwise>
</choice>
<exception-strategy ref="utilflowChoice_Exception_Strategy" doc:name="Reference Exception Strategy"/>
</flow>
<sub-flow name="File-Process-Subflow">
<async processingStrategy="Queued_Asynchronous_Processing_Strategy" doc:name="Async">
<logger message="File-Process Payload #[payload]" level="INFO" doc:name="Logger"/>
<splitter expression="#[payload.split("\n")]" doc:name="Splitter"/>
<dw:transform-message doc:name="Transform Message" metadata:id="88cbea7f-fa8a-4069-8714-d15d05db603c">
<dw:input-payload doc:sample="sample_data\string.dwl" mimeType="application/java"/>
<dw:set-payload><![CDATA[%dw 1.0
%output application/json
%var groupedData = (payload splitBy "-") map using (fruit = $ splitBy ",") {
"msisdn" : fruit[0],
"Email" : fruit[1],
"fName" : fruit[2],
"name" : fruit[3],
"lName" : fruit[4],
"action" :fruit[5] replace "\r" with ""
}
---
groupedData[0]]]></dw:set-payload>
</dw:transform-message>
<object-to-string-transformer doc:name="Object to String"/>
<logger message="File values : #[payload]" level="INFO" doc:name="Logger"/>
<dw:transform-message doc:name="Action Valriable">
<dw:set-session-variable variableName="actionValidatonValue"><![CDATA[%dw 1.0
%output application/java
%var actionCheck = payload.action
---
actionCheck]]></dw:set-session-variable>
</dw:transform-message>
<flow-ref name="Data-Operation-SalseForce" doc:name="Data-Operation-SalseForce"/>
</async>
</sub-flow>
<sub-flow name="Http-Process-Subflow">
<logger message="http-Process Payload #[payload]" level="INFO" doc:name="Logger"/>
<flow-ref name="Data-Operation-SalseForce" doc:name="Data-Operation-SalseForce"/>
</sub-flow>
<sub-flow name="VM-Process-Subflow">
<logger message="VM-Process-Subflow : #[payload]" level="INFO" doc:name="Logger"/>
<object-to-string-transformer doc:name="Object to String"/>
<flow-ref name="Data-Operation-SalseForce" doc:name="Data-Operation-SalseForce"/>
</sub-flow>
<flow name="kelltontechsalseforceFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/VMInsert" doc:name="HTTP" allowedMethods="POST"/>
<byte-array-to-string-transformer doc:name="Byte Array to String"/>
<request-reply doc:name="Request-Reply">
<vm:outbound-endpoint exchange-pattern="one-way" path="dataque" doc:name="VM-Data-process-request"/>
<vm:inbound-endpoint exchange-pattern="one-way" path="resposneQueue" doc:name="VM-resposne-queue"/>
</request-reply>
</flow>
</mule>
Suppoting flow :
global.xml :
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking" xmlns:metadata="http://www.mulesoft.org/schema/mule/metadata" xmlns:dw="http://www.mulesoft.org/schema/mule/ee/dw"
xmlns:sfdc="http://www.mulesoft.org/schema/mule/sfdc" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.mulesoft.org/schema/mule/ee/dw http://www.mulesoft.org/schema/mule/ee/dw/current/dw.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/sfdc http://www.mulesoft.org/schema/mule/sfdc/current/mule-sfdc.xsd
http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd">
<sfdc:config name="Salesforce__Basic_Authentication" username="XXXXXX" password="XXXXXX" securityToken="XXXXXX" doc:name="Salesforce: Basic Authentication"/>
<sub-flow name="Insert_Data">
<sfdc:create config-ref="Salesforce__Basic_Authentication" doc:name="Insert kelltonData" type="KelltonDataSource__c">
<sfdc:objects ref="#[payload]"/>
</sfdc:create>
<set-payload value="#[payload[0]]" doc:name="Set Payload"/>
</sub-flow>
<sub-flow name="DataQuery">
<enricher source="#[payload]" target="#[variable:queryDataExist]" doc:name="Query Data Enricher">
<processor-chain doc:name="Processor Chain">
<sfdc:query config-ref="Salesforce__Basic_Authentication" query="dsql:SELECT Id FROM KelltonDataSource__c where Contact_Number__c='#[payload[0].Contact_Number__c]'" doc:name="Data Query"/>
<set-payload value="#[org.apache.commons.collections.IteratorUtils.toList(payload)]" doc:name="Set Salseforce Response as Payload"/>
<logger message="#[payload]" level="INFO" doc:name="Logger"/>
</processor-chain>
</enricher>
</sub-flow>
<sub-flow name="update_data">
<flow-ref name="payload_enrich_id" doc:name="payload_enrich_id"/>
<sfdc:update config-ref="Salesforce__Basic_Authentication" type="KelltonDataSource__c" doc:name="Update record Salesforce">
<sfdc:objects ref="#[payload]"/>
</sfdc:update>
<set-payload value="#[payload[0]]" doc:name="Set Payload"/>
<logger message="#[payload]" level="INFO" doc:name="Logger"/>
</sub-flow>
<sub-flow name="delete_data">
<flow-ref name="DataQuery" doc:name="DataQuery"/>
<flow-ref name="payload_enrich_id" doc:name="payload_enrich_id"/>
<sfdc:delete config-ref="Salesforce__Basic_Authentication" doc:name="Update record Salesforce">
</sfdc:delete>
<logger message="#[payload]" level="INFO" doc:name="Logger"/>
</sub-flow>
<sub-flow name="Data-Operation-SalseForce">
<dw:transform-message doc:name="Transform Message" >
<dw:input-payload doc:sample="insert-json\InsertJson.json" mimeType="application/json"/>
<dw:set-payload><![CDATA[%dw 1.0
%output application/java
---
[{
First_Name__c: payload.fName,
Last_Name__c: payload.lName,
Contact_Number__c: payload.msisdn,
Email__c: payload.Email
}]]]></dw:set-payload>
</dw:transform-message>
<flow-ref name="DataQuery" doc:name="DataQuery"/>
<choice doc:name="Choice">
<when expression="#[sessionVars.actionValidatonValue=='insert']">
<choice doc:name="Choice">
<when expression="#[queryDataExist.size()==0]">
<flow-ref name="Insert_Data" doc:name="Insert_Data"/>
<set-payload value="Your data has been processed successfully ! please find data unique refrence Id in system: #[payload.id]" doc:name="Set Payload"/>
</when>
<otherwise>
<set-payload value="Data is already existing in system !!" doc:name="Set Payload"/>
</otherwise>
</choice>
<!-- <async doc:name="Async-Insert"> -->
<!-- </async> -->
</when>
<when expression="#[sessionVars.actionValidatonValue=='update']">
<choice doc:name="Choice">
<when expression="#[queryDataExist.size()==0]">
<set-payload value="Data requested for update is not available in system !" doc:name="Set Payload"/>
</when>
<otherwise>
<flow-ref name="update_data" doc:name="update_data"/>
<set-payload value="Your data has been processed successfully ! please find data unique refrence Id in system: #[payload.id]" doc:name="Set Payload"/>
</otherwise>
</choice>
</when>
<when expression="#[sessionVars.actionValidatonValue=='delete']">
<choice doc:name="Choice">
<when expression="#[queryDataExist.size()==0]">
<set-payload value="Requested data is not available in system !!" doc:name="Set Payload"/>
</when>
<otherwise>
<flow-ref name="delete_data" doc:name="delete_data"/>
</otherwise>
</choice>
</when>
</choice>
</sub-flow>
</mule>
utilflow.xml :
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd">
<sub-flow name="payload_enrich_id">
<expression-component doc:name="Payload_add_Id_Flow"><![CDATA[payload[0].Id=queryDataExist[0].Id;
return payload;]]></expression-component>
</sub-flow>
<choice-exception-strategy name="utilflowChoice_Exception_Strategy">
<catch-exception-strategy doc:name="Catch Exception Strategy" when="#[exception.causeMatches('*')]" >
<set-payload value="This action failed due to #[exception.getMessage()] ! Applogies for inconvenience and thanks for your support!" doc:name="Set Payload"/>
</catch-exception-strategy>
</choice-exception-strategy>
</mule>
Opinions expressed by DZone contributors are their own.
Comments