Spread the love

Another trailblazer joins Nerd at Work crew!
His name is Christian Tinghino and his first post is about a brand new addition to the Salesforce platform: MuleSoft.
He’s been helped by another awesome trailblazer, Ivano Guerini.

Christian Tinghino is a Senior Salesforce.com Developer at WebResults, part of Engineering Group.
He started working in 2012, moving his first steps on the Salesforce.com platform in 2014 coding in Apex and Visualforce.
Since 2015 he works in WebResults, fully focused on the development of managed packages and Lightning components.
As all enthusiast developers, he’s fascinated by innovative, challenging and strategic solutions. Owns two Salesforce.com certifications, writes blog posts on bugcoder.it, and saves the world from time to time.

Ivano Guerini is a Salesforce Senior Developer at Webresults, part of Engineering Group since 2015.
He started my career on Salesforce during his university studies and based his final thesis on it.
He’s passionate about technology and development, in his spare time he enjoys developing applications mainly on Node.js.


Few days ago the great news: Salesforce signed an agreement to acquire MuleSoft, a company that provides integration software (link).

SAN FRANCISCO, March 20, 2018 PRNewswire — Salesforce (NYSE: CRM), the global leader in CRM, and MuleSoft (NYSE: MULE), the provider of one of the world’s leading platforms for building application networks, have entered into a definitive agreement under which Salesforce will acquire MuleSoft for an enterprise value of approximately $6.5 billion.

As Salesforce.com developers and nerds we are excited by these news… so me and my colleague Ivano felt we had to take a look at Mule ESB 

Sample use case

For our tests, we want to migrate Salesforce accounts from an organization to another (Sf-to-Sf). Migrated records should dynamically receive the correct Record Type Id once in the destination org, in order to grant a correct mapping.

The flow should manage both existing and new accounts, inserting and updating records based on the presence in the destination org. For this reason, the support for the UPSERT operation is definitely a good thing.

Setup

Since we just want to evaluate the integration capability with Salesforce, we went with the on-premise Enterprise Edition (EE). This has a Salesforce connector that is not available in the Community Edition (CE). For the records, you can also choose a “Anypoint cloud” version.

Mule EE is delivered as Eclipse plugin, so you have to install the Java JDK, download and extract Eclipse. From eclipse, press Help > Install new software to add sites from that contain the runtime:

Some things never change: if you are/were a Java developer, you’ll feel comfortable with this procedure. Just install the EE runtime and Anypoint studio and you’re ready to create your Mule Project via the Eclipse interface.

When installed, a palette contains available components, connectors, transformers and so on. To use them you need to drag-and-drop it on the flow:

 Step 1 – Start flow

Mule works with flows: sets of components, transformers and connectors used to fulfil an “integration need”. Components can communicate passing payloads, reading/writing flow variables accessible by other components in the same flow. You can create custom components and transformers using Java, Javascript etc. A session context is also present, but stores variables and information beyond flows executions.

Always start from the beginning: how the flow starts?
For our test, we want to use the HTTP Listener connector to trigger the flow
http://localhost:8081/start-flow

To to this, drag the HTTP component at the beginning of the flow:

Step 2 – Retrieve origin accounts

Mule automatically connects “blocks” (components) in a flow sequence, so you just need to put a block after another to build your flow.

Drag the Salesforce connector after the HTTP Listener, so that we can query Accounts from the origin org.

To connect with the org, we need to define a configuration. The cool thing is that once a connection is configured, you can reference it just using the Name:

To query accounts from the origin org, set the Salesforce component to execute a query operation, you can be supported by a query builder tool:

Then, we assign the query result (the component payload) to a flow variable called originAccounts, using the Variable component:

Step 3 – Retrieve destination Record Types

Define a different Salesforce configuration to connect to the destination Org (as for the step 2).

Then, drag again the Salesforce component to query Account Record Types, and then store the result in a flow variable. The procedure is similar to the step 2.

Step 4 – Accounts transformation

Now we have to map different fields and apply the correct Record Type ID. We can accomplish this by using custom code and different languages.

Honestly, I had problems with Javascript because of some data type incompatibilities on Iterators. Anyway, everything worked as expected with Java, so I created a class called CustomTransformer:

The class should extend the Mule AbstractMessageTransformer class, and override the transformerMessage method, storing the result into a flow variable. For example, our flow puts the ExternalCode__c field into the ExternalId__c field, reset some fields and apply the new RecordTypeId

@Override
public Object transformMessage(MuleMessage message, String outputEncoding) throws TransformerException {
 
   ConsumerIterator rts = (ConsumerIterator)message.getInvocationProperty("destinationRecordTypes");
   ConsumerIterator accs = (ConsumerIterator)message.getInvocationProperty("originAccounts");
 
   HashMap<Object,Object> rtMap = new HashMap<Object,Object>();
   while (rts != null && rts.hasNext()) {
     HashMap rt = rts.next();
     rtMap.put(rt.get("DeveloperName"), rt.get("Id"));
   }
 
   List newAccs = new ArrayList();
   while (accs != null && accs.hasNext()) {
     HashMap acc = accs.next();
     if(acc.containsKey("RecordType") && acc.get("RecordType") != null) {
       HashMap newAcc = new HashMap(acc);
       String devname = (String) ((HashMap)newAcc.get("RecordType")).get("DeveloperName");
       newAcc.put("Id", null);
       newAcc.put("RecordType", null);
       newAcc.put("ExternalId__c", newAcc.remove("ExternalCode__c"));
       newAcc.put("RecordTypeId", rtMap.get(devname));
       newAccs.add(newAcc);
     }
   }
   message.setInvocationProperty("destinationAccounts", newAccs);
   return newAccs;
}

Step 5 – Upsert accounts

We can now proceed with the upsert operation on the destination org. We can thus use the previously configured credentials to perform the Upsert operation, defining the external id field.

Then with a combination of Foreach and Logger components it is possible to parse and inspect the upsert result in the Mule console log. After that, a transformation into a String allows to print the result to the HTTP listener page. This is not mandatory, but allows us to see how the flow run.

Done!

The full flow should look like this:

You can run a local Mule instance by pressing the “run project” button in Eclipse. To execute the flow, just open the HTTP URL defined in the step 1 and look at the upsert result directly from your page!

This is an example: