Contact Us 1-800-596-4880

Salesforce Contact Aggregation Example

This example application uses the Salesforce connector to query contacts from two separate Salesforce instances and determine which contacts are present in both instances. The section immediately below describes the functions of each of the flows in the application. The section further below describes the configuration of the Salesforce Global Connector Configuration through which the Mule application establishes a connection to Salesforce.

Beyond this example, access introductory and reference documentation for the Salesforce Connector.

Prerequisites

This document assumes that you are familiar with Mule, the Anypoint Studio interface, Global Elements, DataSense, and the DataWeave or its predecessor, Datamapper. Further, it is assumed that you are familiar with Salesforce and have a developerforce account. Learn more about flows and subflows to gain more insight into the design of this example.

Understanding the Flows

The sections immediately below describe the functions of each of the flows.

contact_aggr_flows

mainFlow

Invoked by the triggerFlow (configured in a separate mflow file in the application), the mainFlow begins processing the message triggerFlow accepted via HTTP request. The mainFlow consists of four Flow Ref scopes, which successively call the four subflows in the application. The flow also references a catch exception strategy to handle exceptions thrown. At runtime, the mainFlow begins by calling the gatherDataFlow, explained below the example.

<mule xmlns:file="http://www.mulesoft.org/schema/mule/file" xmlns:smtp="http://www.mulesoft.org/schema/mule/smtp"
    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/smtp http://www.mulesoft.org/schema/mule/smtp/current/mule-smtp.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/file http://www.mulesoft.org/schema/mule/file/current/mule-file.xsd">

    <!-- In this file you should declare all your inbound endpoints and from here control the access to your application -->

    <flow name="triggerFlow" processingStrategy="synchronous" doc:name="triggerFlow" doc:description="This is the simplest entry point to start the execution of your Template.
Here you should:
    * Define any inbound endpoints
    * Handle any input parameter and transform it into the expected format by the mainFlow.
Here you should not:
    * Run validations against external systems
    * Choose a flow of your application based on input parameters">
<http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8081" doc:name="HTTP Listener Configuration"/>
      <http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="${http.port}" path="generatereport" doc:name="Start Report Generation"/>
      <flow name="mainFlow>
        <http:listener config-ref="HTTP_Listener_Configuration" path="/" doc:name="call mainFlow"/>
      </flow>
...
</mule>

gatherDataFlow

This flow contains two message enricher scopes with a Salesforce connector in each. Each Salesforce connector connects to a Salesforce instance to retrieve all fields of type Contact. The message enricher for each connector stores this information in two flow variables, one for each Salesforce organization.

At a later stage, the application accesses these two flow variables to determine which contacts are present in both organizations.

Studio Visual Editor

gatherDataFlow

XML Editor

<sub-flow name="gatherDataFlow" doc:name="gatherDataFlow">
        <enricher source="#[payload]" target="#[flowVars['contactsFromOrgA']]" doc:name="Store result in FlowVar 'contactsFromOrgA'">
            <sfdc:query config-ref="SalesforceA" query="dsql:SELECT Name, Email, Id  FROM Contact" doc:name="query all contacts from SalesForce instance A"/>
        </enricher>
        <enricher source="#[payload]" target="#[flowVars['contactsFromOrgB']]" doc:name="Store result in FlowVar 'contactsFromOrgB'">
            <sfdc:query config-ref="SalesforceB" query="dsql:SELECT Name, Email, Id  FROM Contact" doc:name="query all contacts from SalesForce instance B"/>
        </enricher>
</sub-flow>

As you can see, each Salesforce connector is inside an enricher scope. The first Salesforce connector queries "Salesforce instance A" for contact data; Mule uses the enricher scope to record this data as in a flow variable, contactsFromOrgA. At this point, the application has all contacts from "Salesforce instance A" stored in this variable.

Then, the second Salesforce connector and the second enricher repeat the above-described exercise with "Salesforce instance B", storing contact data for the instance in the flow variable contactsFromOrgB.

Each Salesforce connector references a Salesforce global element, which is configured with the connection parameters (user ID, password, etc.) for each Salesforce organization. To see the configuration for each global element, see the Salesforce Global Elements section.

The table below lists the configuration for the Salesforce connector ("instance A"). This configuration is identical to that of the second Salesforce connector ("instance B"), except that each connector references a different global element.

Studio Visual Editor

Properties Editor

sfdcconfiguration1
Parameter Value

Display Name

query all contacts from SalesForce instance A

Connector Configuration

SalesforceA

Operation

Query

Language

DataSense Query Language

Query Text

SELECT Name, Email, Id FROM Contact

Fetch Size

100

XML Editor

<sfdc:query config-ref="SalesforceA" query="dsql:SELECT Name, Email, Id  FROM Contact" doc:name="query all contacts from SalesForce instance A"/>

After the application has created the two variables containing the contact information for both Salesforce organizations, mainFlow calls the aggregationFlow subflow.

aggregationFlow

This subflow contains only one element: a Java component, which invokes custom-built activity. This component takes both lists of contacts – the one contained in flow variable contactsFromOrgA and the one from contactsFromOrgB – and merges them into a single list. The application passes the merged list back to the mainFlow, then onwards to the formatOutputFlow.

formatOutputFlow

In this flow, a custom Java component searches merged contact list produced by aggregationFlow for elements with identical content in the Email field. Any that appear more than once signify contacts that exist in both Salesforce organizations. This Java component outputs these "duplicates" another list.

Next, a DataMapper transformer maps the Java object to a CSV file which the flow then transforms to a string. The flow passes the message, now a string of duplicated email addresses back to the mainFlow. The mainFlow proceeds to send the message to the outboundFlow (configured in a separate mflow file in the application) to email the results to a pre-defined address.

<mule xmlns:file="http://www.mulesoft.org/schema/mule/file" xmlns:smtp="http://www.mulesoft.org/schema/mule/smtp"
    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/smtp http://www.mulesoft.org/schema/mule/smtp/current/mule-smtp.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/file http://www.mulesoft.org/schema/mule/file/current/mule-file.xsd">

    <!-- In this file you should declare all your inbound endpoints, and from here control the access to your application. -->
...
      <flow name="outboundFlow" doc:name="outboundFlow" doc:description="This is the simplest output point to push the result of the data processing.
Here you should:
    * Call external systems through outbound endpoints
Here you should not:
    * Perform generic data transformation

The outboundFlow is in this file in order to maintain the logical abstraction of the Template.">
        <file:outbound-endpoint path="/Users/admin/_marcos/sfdc-templates/sfdc2sfdc-contact-aggregation-main/_output" outputPattern="result.txt" responseTimeout="10000" doc:name="Write output"/>
    </flow>
</mule>

Salesforce Global Elements

The tables below list the configuration for the Salesforce global element which establishes a connection to "Salesforce instance A".

Studio Visual Editor

General Tab

Properties Editor
SFglobalelem
Parameter Value

Name

SalesforceA

Username

Redacted. Use the appropriate user ID for your Salesforce instance.

Password

Redacted. Use the appropriate password for your Salesforce instance.

Security Token

Redacted. Use the appropriate security token for your Salesforce instance.

Url

Redacted. Use the appropriate URL for your Salesforce instance, such as https://salesforce.com/services/Soap/u/30.0

Proxy Host

Proxy Port

Proxy Username

Proxy Password

Session Id

Service Endpoint

Enable DataSense

True

Time Object Store Reference

Assignment Rule Id

Client Id

Batch Sobject Max Depth

5 (default)

Allow Field Truncation Support

Use Default Rule

Pooling Profile Tab

In this tab, all settings reflect their default values.

Properties Editor
SFglobalelem-connpooltab
Parameter Value

Max active

5

Max idle

5

Initialisation policy

INITIALISE_ONE

Exhausted action

WHEN_EXHAUSTED_GROW

Max wait

5

Min eviction (ms)

1800000

Reconnection Tab

In this tab, all settings reflect their default values.

Properties Editor
SFglobalelem-reconntab
Parameter Value

Do not use a Reconnection strategy

Checked

Run the reconnection in a separated thread

Unchecked

See Also