Mule ESB 3.6
CRUD operations on Salesforce using
Mule ESB
Objective
– Advantages of using Salesforce connector
– How to perform Create, Read, Update and Delete
operations on Salesforce
Pre-requisites
• Anypoint Studio
• A Salesforce developer account
• A security token for Salesforce
Salesforce Connector
• Salesforce connector allows Mule ESB application to connect
to Salesforce
• It supports data sense which fetches meta data information
about of Salesforce once required connection details are
specified at the connector
• It lists all objects and operations at design time using data
sense and makes development easy and rapid
Steps
• Create a Salesforce developer account
• Create a security token for Salesforce account
• Create a mule application to perform CRUD
operations
How to create Salesforce developer
account
• Sign up for a new account at http://developer.force.com/
How to generate a security token
• Sign into http://developer.force.com/, click your name in the
upper right corner, then click Setup > My Personal
Information > Reset Security Token. Then, click Reset My
Security Token. Salesforce sends your security token via email
to your registered email address
Create a mule application to perform
CRUD operations
• Create a property file
• Configure property file in your project
• Add Salesforce connector and configure the
connector details
• Configure a flow
• Run your application
• Create a property file with following details
and place it in mule_home/conf folder
#SF URL
sf_url=https://<your salesforce url>/services/Soap/u/26.0
#SF Username
sf_username=<Your salesforce account name>
#SF Password
sf_password=<Your salesforce account password>
#SF Security Token
sf_security_token=<Your salesforce security token>
Add the property file in your flow
• Click on global elements tab -> Click on create -> Type in Property
Placeholder in the filter box -> Select Property Placeholder and click on Ok
-> Type in “file:${mule_home}/conf/salesforce-config.properties” in the
location text box and click on Ok
• You should see an XML tag added under your configuration XML as below
<context:property-placeholder location="file:${mule_home}/conf/salesforce-
config.properties"/>
Add Salesforce connector in your flow
• Click on global elements tab -> Click on create -> Select
Salesforce and add property as shown below
You need to create 3 java classes as
show below
• CreateContactRequest.java
public class CreateContactRequest implements Callable {
@Override
public Object onCall(MuleEventContext eventContext) throws Exception {
HashMap<String,Object> contactSObjectFields = new HashMap<String,Object>();
// sObject is defined as a map
contactSObjectFields.put("FirstName", “YourFirstName");
contactSObjectFields.put("LastName", "YourLastName");
contactSObjectFields.put("MobilePhone", "YourMobileNo");
contactSObjectFields.put("Email", “YourEmail");
// list of sobjects to be created
List<HashMap<String,Object>> objects = new ArrayList<HashMap<String,Object>>();
objects.add(contactSObjectFields);
// map that will be placed as payload
HashMap<String,Object> payload = new HashMap<String,Object>();
payload.put("type", "Contact");
payload.put("objects", objects);
return payload;
}
}
• UpdateContactRequest.java
public class UpdateContactRequest implements Callable {
@Override
public Object onCall(MuleEventContext eventContext) throws Exception {
HashMap<String,Object> contactSObjectFields = new HashMap<String,Object>();
MuleMessage muleMessage = eventContext.getMessage();
contactSObjectFields.put("FirstName", “YourModifiedFirstName");
contactSObjectFields.put("LastName", "YourModifiedLastName");
contactSObjectFields.put("MobilePhone", "YourModifiedMobileNo");
contactSObjectFields.put("Email", “YourModifiedEmail");
contactSObjectFields.put("Id", muleMessage.getProperty("sObjectId", PropertyScope.SESSION));
// map that will be placed as payload
HashMap<String,Object> payload = new HashMap<String,Object>();
payload.put("type", "Contact");
payload.put("object", contactSObjectFields);
return payload;
}
}
• CreateContactResponseProcessor.java
public class CreateContactResponseProcessor implements Callable {
@SuppressWarnings("unchecked")
@Override
public Object onCall(MuleEventContext eventContext) throws Exception {
AcknowledgementType ack = new AcknowledgementType();
MuleMessage message = eventContext.getMessage();
System.out.println(message.toString());
// get the message payload
List<SaveResult> saveResults = (List<SaveResult>) message.getPayload();
Iterator<SaveResult> iter = saveResults.iterator();
SaveResult saveResult = iter.next();
ack.setMessageID(saveResult.getId());
if(saveResult.getSuccess())
ack.setStatus("Success");
else
ack.setStatus("Success");
System.out.println(ack);
return ack.getMessageID();
}
}
Create a mule flow with as show
below
The flow configuration will look should look like as
follows
<context:property-placeholder location="file:${mule_home}/conf/salesforce-config.properties"/>
<sfdc:config name="Salesforce" username="${sf_username}" password="${sf_password}" securityToken="${sf_security_token}" url="${sf_url}" doc:name="Salesforce">
<sfdc:connection-pooling-profile initialisationPolicy="INITIALISE_ONE" exhaustedAction="WHEN_EXHAUSTED_GROW"/>
</sfdc:config>
<flow name="CreateContact" doc:name="CreateContact">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="1001" path="SFDC_CRUD" doc:name="HTTP_Inbound"/>
<component class="com.sfdc.requestresponse.processor.CreateContactRequest" doc:name="CreateContactRequest"/>
<logger message="Salesforce Request----&gt; #[payload]" level="INFO" doc:name="LogSalesforceRequest"/>
<sfdc:create config-ref="Salesforce" doc:name="CreateSalesforceContact" type="#[payload.type]">
<sfdc:objects ref="#[payload.objects]"/>
</sfdc:create>
<logger message="SFDC output: ------ #[payload]" level="INFO" doc:name="LogSalesforceResponse"/>
<component class="com.sfdc.requestresponse.processor.CreateContactResponseProcessor" doc:name="CreateContactSFResponseProcessor"/>
<message-properties-transformer overwrite="true" scope="session" doc:name="StoreContactId">
<add-message-property key="sObjectId" value="#[payload]"/>
</message-properties-transformer>
<flow-ref name="QueryContact" doc:name="GoToReadContactFlow"/>
</flow>
<flow name="QueryContact" doc:name="QueryContact">
<logger level="INFO" doc:name="LogSalesforceReadContactRequest"/>
<sfdc:query config-ref="Salesforce" query="SELECT Id,Name,BillingStreet, BillingCity,BillingState,BillingPostalCode,BillingCountry FROM Account WHERE Id = '#[sessionVars.sObjectId]'" doc:name="ReadSalesforceContact"/>
<logger level="INFO" doc:name="LogSalesforceReadContactResponse" message="Query Output: #[payload]"/>
<flow-ref name="UpdateContact" doc:name="GoToUpdateContactFlow"/>
</flow>
<flow name="UpdateContact" doc:name="UpdateContact">
<component class="com.sfdc.requestresponse.processor.UpdateContactRequest" doc:name="UpdateContactRequest"/>
<logger message="Update Request----&gt; #[payload]" level="INFO" doc:name="LogUpdateContactSalesforceRequest"/>
<sfdc:update-single config-ref="Salesforce" type="#[payload.type]" doc:name="UpdateSalesforceContact">
<sfdc:object ref="#[payload.object]"/>
</sfdc:update-single>
<logger message="Update Output----&gt; #[payload]" level="INFO" doc:name="LogContactUpdated"/>
<flow-ref name="ReadContactAgain" doc:name="GoToReadContactFlow"/>
</flow>
<flow name="ReadContactAgain" doc:name="ReadContactAgain">
<logger level="INFO" doc:name="LogSalesforceReadContactRequest"/>
<sfdc:query config-ref="Salesforce" query="SELECT Id,Name,BillingStreet, BillingCity,BillingState,BillingPostalCode,BillingCountry FROM Account WHERE Id = '#[sessionVars.sObjectId]'" doc:name="ReadSalesforceContact"/>
<logger level="INFO" doc:name="LogSalesforceReadContactResponse" message="Query Output: #[payload]"/>
<flow-ref name="DeleteContact" doc:name="GoToDeleteContactFlow"/>
</flow>
<flow name="DeleteContact" doc:name="DeleteContact">
<sfdc:delete config-ref="Salesforce" doc:name="DeleteSalesforceContact">
<sfdc:ids>
<sfdc:id>#[sessionVars.sObjectId]</sfdc:id>
</sfdc:ids>
</sfdc:delete>
<logger level="INFO" doc:name="LogDeleteContactResponse" message="Delete Output-----&gt; #[payload]"/>
<set-payload value="&quot;CRUD Operations executed successfully. Please check the logs for details&quot;" doc:name="Set Payload"/>
</flow>
• Now you can run the application and hit the http URL configured in your
application in browser
• It should create a contact, read the values, update the contact, read the
value and finally delate the contact from Salesforce.
• You can delete the last flow reference for delete contact if you like to see
the contact in Salesforce for your testing
• Details of the contact creation to deletion can be observed in logs
Extract from the logs
INFO 2015-03-21 20:01:39,730 [[sfdc_connector].connector.http.mule.default.receiver.02] org.mule.api.processor.LoggerMessageProcessor: Salesforce Request---->
{type=Contact, objects=[{Email=xyz@abc.com, FirstName=Rupesh, MobilePhone=078000000, LastName=Sinha}]}
INFO 2015-03-21 20:01:41,605 [[sfdc_connector].connector.http.mule.default.receiver.02] org.mule.api.processor.LoggerMessageProcessor: SFDC output: ------
[[SaveResult errors='{[0]}'
id='003L000000YhRS5IAN'
success='true'
]
]
Status: Success, Id: 003L000000YhRS5IAN
INFO 2015-03-21 20:01:42,069 [[sfdc_connector].connector.http.mule.default.receiver.02] org.mule.api.processor.LoggerMessageProcessor: Query Output: []
INFO 2015-03-21 20:01:42,073 [[sfdc_connector].connector.http.mule.default.receiver.02] org.mule.api.processor.LoggerMessageProcessor: Update Request---->
{object={Email=xyz@abc.com, FirstName=Rupesh_Changed, Id=003L000000YhRS5IAN, MobilePhone=078000000, LastName=Sinha_Changed}, type=Contact}
INFO 2015-03-21 20:01:42,883 [[sfdc_connector].connector.http.mule.default.receiver.02] org.mule.api.processor.LoggerMessageProcessor: Update Output---->
[SaveResult errors='{[0]}'
id='003L000000YhRS5IAN'
success='true'
]
INFO 2015-03-21 20:01:43,254 [[sfdc_connector].connector.http.mule.default.receiver.02] org.mule.api.processor.LoggerMessageProcessor: Query Output: []
INFO 2015-03-21 20:01:44,053 [[sfdc_connector].connector.http.mule.default.receiver.02] org.mule.api.processor.LoggerMessageProcessor: Delete Output----->
[[DeleteResult errors='{[0]}'
id='003L000000YhRS5IAN'
success='true'
]
]
Thanks for watching

Mule using Salesforce

  • 1.
    Mule ESB 3.6 CRUDoperations on Salesforce using Mule ESB
  • 2.
    Objective – Advantages ofusing Salesforce connector – How to perform Create, Read, Update and Delete operations on Salesforce
  • 3.
    Pre-requisites • Anypoint Studio •A Salesforce developer account • A security token for Salesforce
  • 4.
    Salesforce Connector • Salesforceconnector allows Mule ESB application to connect to Salesforce • It supports data sense which fetches meta data information about of Salesforce once required connection details are specified at the connector • It lists all objects and operations at design time using data sense and makes development easy and rapid
  • 5.
    Steps • Create aSalesforce developer account • Create a security token for Salesforce account • Create a mule application to perform CRUD operations
  • 6.
    How to createSalesforce developer account • Sign up for a new account at http://developer.force.com/
  • 7.
    How to generatea security token • Sign into http://developer.force.com/, click your name in the upper right corner, then click Setup > My Personal Information > Reset Security Token. Then, click Reset My Security Token. Salesforce sends your security token via email to your registered email address
  • 8.
    Create a muleapplication to perform CRUD operations • Create a property file • Configure property file in your project • Add Salesforce connector and configure the connector details • Configure a flow • Run your application
  • 9.
    • Create aproperty file with following details and place it in mule_home/conf folder #SF URL sf_url=https://<your salesforce url>/services/Soap/u/26.0 #SF Username sf_username=<Your salesforce account name> #SF Password sf_password=<Your salesforce account password> #SF Security Token sf_security_token=<Your salesforce security token>
  • 10.
    Add the propertyfile in your flow • Click on global elements tab -> Click on create -> Type in Property Placeholder in the filter box -> Select Property Placeholder and click on Ok -> Type in “file:${mule_home}/conf/salesforce-config.properties” in the location text box and click on Ok • You should see an XML tag added under your configuration XML as below <context:property-placeholder location="file:${mule_home}/conf/salesforce- config.properties"/>
  • 11.
    Add Salesforce connectorin your flow • Click on global elements tab -> Click on create -> Select Salesforce and add property as shown below
  • 12.
    You need tocreate 3 java classes as show below • CreateContactRequest.java public class CreateContactRequest implements Callable { @Override public Object onCall(MuleEventContext eventContext) throws Exception { HashMap<String,Object> contactSObjectFields = new HashMap<String,Object>(); // sObject is defined as a map contactSObjectFields.put("FirstName", “YourFirstName"); contactSObjectFields.put("LastName", "YourLastName"); contactSObjectFields.put("MobilePhone", "YourMobileNo"); contactSObjectFields.put("Email", “YourEmail"); // list of sobjects to be created List<HashMap<String,Object>> objects = new ArrayList<HashMap<String,Object>>(); objects.add(contactSObjectFields); // map that will be placed as payload HashMap<String,Object> payload = new HashMap<String,Object>(); payload.put("type", "Contact"); payload.put("objects", objects); return payload; } }
  • 13.
    • UpdateContactRequest.java public classUpdateContactRequest implements Callable { @Override public Object onCall(MuleEventContext eventContext) throws Exception { HashMap<String,Object> contactSObjectFields = new HashMap<String,Object>(); MuleMessage muleMessage = eventContext.getMessage(); contactSObjectFields.put("FirstName", “YourModifiedFirstName"); contactSObjectFields.put("LastName", "YourModifiedLastName"); contactSObjectFields.put("MobilePhone", "YourModifiedMobileNo"); contactSObjectFields.put("Email", “YourModifiedEmail"); contactSObjectFields.put("Id", muleMessage.getProperty("sObjectId", PropertyScope.SESSION)); // map that will be placed as payload HashMap<String,Object> payload = new HashMap<String,Object>(); payload.put("type", "Contact"); payload.put("object", contactSObjectFields); return payload; } }
  • 14.
    • CreateContactResponseProcessor.java public classCreateContactResponseProcessor implements Callable { @SuppressWarnings("unchecked") @Override public Object onCall(MuleEventContext eventContext) throws Exception { AcknowledgementType ack = new AcknowledgementType(); MuleMessage message = eventContext.getMessage(); System.out.println(message.toString()); // get the message payload List<SaveResult> saveResults = (List<SaveResult>) message.getPayload(); Iterator<SaveResult> iter = saveResults.iterator(); SaveResult saveResult = iter.next(); ack.setMessageID(saveResult.getId()); if(saveResult.getSuccess()) ack.setStatus("Success"); else ack.setStatus("Success"); System.out.println(ack); return ack.getMessageID(); } }
  • 15.
    Create a muleflow with as show below
  • 16.
    The flow configurationwill look should look like as follows <context:property-placeholder location="file:${mule_home}/conf/salesforce-config.properties"/> <sfdc:config name="Salesforce" username="${sf_username}" password="${sf_password}" securityToken="${sf_security_token}" url="${sf_url}" doc:name="Salesforce"> <sfdc:connection-pooling-profile initialisationPolicy="INITIALISE_ONE" exhaustedAction="WHEN_EXHAUSTED_GROW"/> </sfdc:config> <flow name="CreateContact" doc:name="CreateContact"> <http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="1001" path="SFDC_CRUD" doc:name="HTTP_Inbound"/> <component class="com.sfdc.requestresponse.processor.CreateContactRequest" doc:name="CreateContactRequest"/> <logger message="Salesforce Request----&gt; #[payload]" level="INFO" doc:name="LogSalesforceRequest"/> <sfdc:create config-ref="Salesforce" doc:name="CreateSalesforceContact" type="#[payload.type]"> <sfdc:objects ref="#[payload.objects]"/> </sfdc:create> <logger message="SFDC output: ------ #[payload]" level="INFO" doc:name="LogSalesforceResponse"/> <component class="com.sfdc.requestresponse.processor.CreateContactResponseProcessor" doc:name="CreateContactSFResponseProcessor"/> <message-properties-transformer overwrite="true" scope="session" doc:name="StoreContactId"> <add-message-property key="sObjectId" value="#[payload]"/> </message-properties-transformer> <flow-ref name="QueryContact" doc:name="GoToReadContactFlow"/> </flow> <flow name="QueryContact" doc:name="QueryContact"> <logger level="INFO" doc:name="LogSalesforceReadContactRequest"/> <sfdc:query config-ref="Salesforce" query="SELECT Id,Name,BillingStreet, BillingCity,BillingState,BillingPostalCode,BillingCountry FROM Account WHERE Id = '#[sessionVars.sObjectId]'" doc:name="ReadSalesforceContact"/> <logger level="INFO" doc:name="LogSalesforceReadContactResponse" message="Query Output: #[payload]"/> <flow-ref name="UpdateContact" doc:name="GoToUpdateContactFlow"/> </flow> <flow name="UpdateContact" doc:name="UpdateContact"> <component class="com.sfdc.requestresponse.processor.UpdateContactRequest" doc:name="UpdateContactRequest"/> <logger message="Update Request----&gt; #[payload]" level="INFO" doc:name="LogUpdateContactSalesforceRequest"/> <sfdc:update-single config-ref="Salesforce" type="#[payload.type]" doc:name="UpdateSalesforceContact"> <sfdc:object ref="#[payload.object]"/> </sfdc:update-single> <logger message="Update Output----&gt; #[payload]" level="INFO" doc:name="LogContactUpdated"/> <flow-ref name="ReadContactAgain" doc:name="GoToReadContactFlow"/> </flow> <flow name="ReadContactAgain" doc:name="ReadContactAgain"> <logger level="INFO" doc:name="LogSalesforceReadContactRequest"/> <sfdc:query config-ref="Salesforce" query="SELECT Id,Name,BillingStreet, BillingCity,BillingState,BillingPostalCode,BillingCountry FROM Account WHERE Id = '#[sessionVars.sObjectId]'" doc:name="ReadSalesforceContact"/> <logger level="INFO" doc:name="LogSalesforceReadContactResponse" message="Query Output: #[payload]"/> <flow-ref name="DeleteContact" doc:name="GoToDeleteContactFlow"/> </flow> <flow name="DeleteContact" doc:name="DeleteContact"> <sfdc:delete config-ref="Salesforce" doc:name="DeleteSalesforceContact"> <sfdc:ids> <sfdc:id>#[sessionVars.sObjectId]</sfdc:id> </sfdc:ids> </sfdc:delete> <logger level="INFO" doc:name="LogDeleteContactResponse" message="Delete Output-----&gt; #[payload]"/> <set-payload value="&quot;CRUD Operations executed successfully. Please check the logs for details&quot;" doc:name="Set Payload"/> </flow>
  • 17.
    • Now youcan run the application and hit the http URL configured in your application in browser • It should create a contact, read the values, update the contact, read the value and finally delate the contact from Salesforce. • You can delete the last flow reference for delete contact if you like to see the contact in Salesforce for your testing • Details of the contact creation to deletion can be observed in logs
  • 18.
    Extract from thelogs INFO 2015-03-21 20:01:39,730 [[sfdc_connector].connector.http.mule.default.receiver.02] org.mule.api.processor.LoggerMessageProcessor: Salesforce Request----> {type=Contact, objects=[{Email=xyz@abc.com, FirstName=Rupesh, MobilePhone=078000000, LastName=Sinha}]} INFO 2015-03-21 20:01:41,605 [[sfdc_connector].connector.http.mule.default.receiver.02] org.mule.api.processor.LoggerMessageProcessor: SFDC output: ------ [[SaveResult errors='{[0]}' id='003L000000YhRS5IAN' success='true' ] ] Status: Success, Id: 003L000000YhRS5IAN INFO 2015-03-21 20:01:42,069 [[sfdc_connector].connector.http.mule.default.receiver.02] org.mule.api.processor.LoggerMessageProcessor: Query Output: [] INFO 2015-03-21 20:01:42,073 [[sfdc_connector].connector.http.mule.default.receiver.02] org.mule.api.processor.LoggerMessageProcessor: Update Request----> {object={Email=xyz@abc.com, FirstName=Rupesh_Changed, Id=003L000000YhRS5IAN, MobilePhone=078000000, LastName=Sinha_Changed}, type=Contact} INFO 2015-03-21 20:01:42,883 [[sfdc_connector].connector.http.mule.default.receiver.02] org.mule.api.processor.LoggerMessageProcessor: Update Output----> [SaveResult errors='{[0]}' id='003L000000YhRS5IAN' success='true' ] INFO 2015-03-21 20:01:43,254 [[sfdc_connector].connector.http.mule.default.receiver.02] org.mule.api.processor.LoggerMessageProcessor: Query Output: [] INFO 2015-03-21 20:01:44,053 [[sfdc_connector].connector.http.mule.default.receiver.02] org.mule.api.processor.LoggerMessageProcessor: Delete Output-----> [[DeleteResult errors='{[0]}' id='003L000000YhRS5IAN' success='true' ] ]
  • 19.