Mapping with Flow Guide
Inbound mapping is the term to mean the inbound data flow into Salesforce from an external system. The inbound mapping process usually is performed using Batch Apex because the number of records to process can exceed the Salesforce Governor limits. This guide will show you how to configure a Data Synchronization Integration Scenario to run a Salesforce Flow instead of using the Batch Apex.
Advantages
Using a Flow for inbound mapping processing has the following advantages.
- Business logic can be added without Apex code.
- Records can be conditionally queried from the database and processed.
- Mapping configurations can be conditionally run.
- Avoids tying up one of 5 Salesforce Platform Batch Apex workers.
- Flow processing is ideal for smaller batches with custom logic.
Considerations
- Flow processing is limited to the Salesforce Governor limits so care should be used in ensuring not too many records are returned from the backend system, or manually queried from the Integration Objects.
- If a Governor limit would be hit during processing, the process is terminated early as an error and only records that can be processed will be. The mapping operation can be rerun to continue where it left off.
- Apex code in the mapping configuration's Enhancement Point is still executed.
- An activated Data Synchronization Integration Scenario.
- An inbound object mapping configuration saved on the Scenario.
We need to create a Flow to be run as the replacement for Batch Apex processing.
Go to Salesforce Setup -> Process Automation -> Flows -> New Flow -> Autolaunched Flow.
- Create a resource for the input variable. This is set by the Overcast Object Mapper when the Flow starts.
- Resource Type: Variable
- Name: inputs (Must match case exactly)
- Data Type: Apex-Defined. Allow multiple values (collection) is unchecked
- Apex Class: overcast__ObjectMappingInboundFlowInputs
- Availability Outside the Flow: Available for input is checked
- Create a resource for the output variable. This is read by the Overcast Object Mapper when the Flow ends. It is optional. It is used to report back to the mapping process.
- Resource Type: Variable
- Name: outputs (Must match case exactly)
- Data Type: Apex-Defined. Allow multiple values (collection) is unchecked
- Apex Class: overcast__ObjectMappingInboundFlowOutputs
- Availability Outside the Flow: Available for output is checked
- Save the Flow. Give it a name related to the Scenario that will use it, like "MyScenario_MappingOrchestration".
When the Scenario mapping operation is run, the Flow will be loaded with the run context.
Some standard actions performed in the Flow would be
- Run the inbound mapping action for all records and all mapping configurations.
- Read a subset of the records from the Integration Object for mapping.
- Run the mappings with a subset of the mapping configurations.
- Handle errors.
The following sections explain how to complete each action. Each action is independent but complimentary to each other.
Run the inbound mapping action for all records and all mapping configurations
- Add an Action to the Flow.
- Select the Overcast category then select Run Overcast Inbound Mapping action.
- Give it a label and name.
- For Object for "Records", Select an Integration Object for the Scenario. The Inputs will appear.
- Inputs field should be set to Inputs [Apex-defined] ({!inputs}).
- Click the toggle for Records to disable.
- Specific mappings to run should be disabled.
- Advanced / Manually assign variables can be left unchecked.
.png?Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cHM6Ly9kemY4dnF2MjRlcWhnLmNsb3VkZnJvbnQubmV0L3VzZXJmaWxlcy83NDg4LzMyMTM5L2NrZmluZGVyL2ltYWdlcy9xdS9pbWFnZSg5OSkucG5nIiwiQ29uZGl0aW9uIjp7IkRhdGVMZXNzVGhhbiI6eyJBV1M6RXBvY2hUaW1lIjoxNzY2Mzk3ODQyfX19XX0_&Signature=cpgexPVPIClxY9fahJB9q9W3nyd-kmUl6NGF8dL6aSlKUgiEsxVWMBH4o4b3X5-e44kFoZY~wlproor765ph7BBUXsJ4iHFHONzCKH9SMokeQXC7xK1q049Wn28DLlTNrA7q0WakrxRwVyr8K82oNvpdaB7~I2EFnIgrUQ7pH4CLrt-cMWfEm22rVdlt19QmQfnCTMbPXD9ejWt68oaxOz-~9f3NNL~WUnQdUKkD4r~pavn0T8NiwaLeFSlKL56iKLuz37xf9-cvjPL6H5pkvhWbM-EF6~Vv8IAqA8rQnyWGrII1cIGtqiid-w5ZV0GvhxFGBBVckHVqrx2NJUoq7Q__&Key-Pair-Id=K2TK3EG287XSFC)
Read a subset of the records from the Integration Object for mapping
- Add Get Records to the Flow.
- Specify a Label and Name.
- Select the Integration Object to read from.
- Set the first filter condition. This will ensure that only the current Scenario run's records are queried.
- Name equals inputs > inboundRecordsName
- Set any additional filters, if required.
- Set All records stored.
- Set Automatically store all fields.
- Save.
- Pre-process the records in a loop, if required.
- Add Run Overcast Inbound Mapping action and set the Get Records value to the action's Records field.
.png?Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cHM6Ly9kemY4dnF2MjRlcWhnLmNsb3VkZnJvbnQubmV0L3VzZXJmaWxlcy83NDg4LzMyMTM5L2NrZmluZGVyL2ltYWdlcy9xdS9pbWFnZSgxMDQpLnBuZyIsIkNvbmRpdGlvbiI6eyJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTc2NjM5Nzg0Mn19fV19&Signature=njUKeWof3WVntTJ86cnCP5Q5r0oNKidMaiPUKPY~GHhG7~luPSsOLSLQDmeMNvTT7u2qC3G-LKoMeg5s0mnYe02ZolLQA~08BvH6TWY0hUGq9cQIQQPMeaiZ8eU7bDRYdMbBtRogWCDFZ7ZhFQcgw5gHm8wWufu0y67m8Pu7Hh5hduFEtxKD5t5JbjDgsgN1QnsqX4vP7d6em6odem0TyeNiIfhFuqCmCvRem0h517W8UGCdgXlLmrt5ao4OYyFVJDjy5Bjb-AlxEU7QaZDtqrfmV3WNUd9-gmECLJM~kxm6XkLZbPZONYWH7mebVeVTsqg9V1ZbOfxDt6077IYdcw__&Key-Pair-Id=K2TK3EG287XSFC)
Run the mappings with a subset of the mapping configurations
Specify in the Run Overcast Inbound Mapping the names of the mapping configurations. Separate them with a comma; a space is not required.
Exit Flow and Return to Batch Processing
Flow processing is limited to the Salesforce Governor limits so care should be used in ensuring not too many records are returned from the backend system, or manually queried from the Integration Objects.
We have a pattern that can be utilized to address one of the considerations stated at the top of this page. The advantage of orchestration through Flow is that it gives you greater control over mapping. In the case when the response data is small, Flow orchestration can significantly reduce the time taken from starting a Data Sync Scenario to when the data is saved/mapped to the target records because it is not run on the Salesforce Batch Apex queue. In this case, the response data must never be large to avoid hitting the governor limit of 10,000 records.
To work around this hard requirement, when response data is larger than the governor limit we can use the following pattern.
- Query for the count of records in the response integration object.
- Use a Decision and create two branches
- Default (when record count is under the limit)
- Over limit (when record count is over the limit)
- The default branch performs the current behavior.
- In the Over limit branch path, add an Apex Action
- Start Mapping Batch Process
- Input parameters
- Mapping Run Record ID: {!inputs.mappingRunRecordId}
- End the process after Start Mapping Batch Process.
Now, the flow will handle when too much data is returned by running the Batch Apex mapping processor.
Real-time Scenarios (or HTTP Requests) in Mappings
When needing to make HTTP requests in an object mapping enhancement point, like running real-time scenarios to gather extra data to complete a mapping, you may need to carefully construct your flow to avoid the all-too-common "You have uncommitted work pending" error.
You will be able to perform one mapping operation with HTTP requests (below) without special handling. The first mapping Apex action makes the HTTP requests and performs the mappings (copying records). But subsequent HTTP requests will fail without special handling.
.png?Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cHM6Ly9kemY4dnF2MjRlcWhnLmNsb3VkZnJvbnQubmV0L3VzZXJmaWxlcy83NDg4LzMyMTM5L2NrZmluZGVyL2ltYWdlcy9xdS8yMDI1L2ltYWdlKDEpLnBuZyIsIkNvbmRpdGlvbiI6eyJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTc2NjM5Nzg0Mn19fV19&Signature=nyVNzeRk8uKmRLKXPglULPtykjDS8s1tpVl2n8ftagJqpB82aEePZ9NLk~EQGap73wViuBtbJINjxZ37EPuvJmxtL-gTYpvmeDrgaiMq5QmjB16I4mRY8GszkRy8~x~OVD6l4UIBFucbuHqzUzDVJmhcW2Gtvsj5Iagwv-Tn8iFIEyTq2zJlz7YiQtsuKOw-SfI63b6fTshsz3bpwVEfrwvNyOeW7ScDVKI~pKRA2SgMK6uxjc5Ox2sS23cQRvNhEWBijvPUdjQwWGe5jQ7jD2kaMVMY9d0dUKg246nMSSz-4KzOGbUb~cr32p14HaVH1EjHhGLyayM4B7U83DbhxQ__&Key-Pair-Id=K2TK3EG287XSFC)
This section will show you how to run multiple mappings that each run real-time scenarios in the enhancement point Apex code.
.png?Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cHM6Ly9kemY4dnF2MjRlcWhnLmNsb3VkZnJvbnQubmV0L3VzZXJmaWxlcy83NDg4LzMyMTM5L2NrZmluZGVyL2ltYWdlcy9xdS8yMDI1L2ltYWdlKDMpLnBuZyIsIkNvbmRpdGlvbiI6eyJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTc2NjM5Nzg0Mn19fV19&Signature=X0CHRs2PSMhcciL0oheAgdnfvCfaO~Hun1YdSN0uGLMyT0hoCH~OtU5QasZMVpaqmM2eyb0wR6UKwqD~PS52n3tpegMKZEIpb~cYezwpHpq-9a5vt2VDAZZgLInqM-g7nL4y7J~l3~zK0fe906IGnPFl0JM~J3O8eBR0EtQJgsF9~wBWMVby9~AHFjbS--j-cg0heHXl7yg2KQ59JufwwqBbS~OKXABDN5sjPTX2TS-IIu0IFZUdzTxRzFzYVx7fS0WXDbr~7YseNqDi~9xwSF-g3fSgj5qw7OGeeAX~dxzY5G56C7yWp~5Ig279FDfRlnCzIF0W3lL9QmRtJWREcg__&Key-Pair-Id=K2TK3EG287XSFC)
Follow these steps to create the flow above.
- Create a resource for updating the mapping run record.
- Resource Type: Variable
- Name: mappingRunRecord
- Data Type: Record
- Object: overcast__Run__c
- Add Apex Action element to run the mappings for the first source object.
- Type: Run Overcast Inbound Mapping
- Name: Run mapping 1
- Object: The mapping's source object
- Inputs: {!inputs}
- Add a Decision based on the mapping success results.
- On the Failed path, add an Assignment to set the mapping run record as complete.
- Variable: {!Mapping_Run_Record.Id}
Operator: Equals
Value: {!inputs.mappingRunRecordId}
- Variable: {!Mapping_Run_Record.overcast__StatusCode__c}
Operator: Equals
Value: {!Run_mapping_1.statusCode} (This is the output from the last mapping)
- On the Default path, add an Assignment to add a log about the following wait.
- Variable: {!outputs.intoMessages}
Operator: Add
Value: Waiting for Run mapping 2.
- Let's also set the status code so the mapping run record is not set as complete before the second mapping is completed.
Variable: outputs.statusCode
Operator: Equals
Value: 110 (This means mapping is still in process)
- Add a Wait for Amount of Time element
- Label: Transaction Separator
- Amount of Time: 1 Minute
- Add an Apex Action like 2. to run the second mapping operation.
- Add an Assignment to set the mapping run record as complete.
- Variable: {!Mapping_Run_Record.Id}
Operator: Equals
Value: {!inputs.mappingRunRecordId}
- Variable: {!Mapping_Run_Record.overcast__StatusCode__c}
Operator: Equals
Value: {!Run_mapping_2.statusCode} (This is the output from the last mapping)
- Add an Update Records element to save the mapping run record changes.
- Label: Set as finished
- How to Find Records to Update and Set Their Values: Use the IDs...
- Record: {!Mapping_Run_Record}
- End
Handle errors
It is a Salesforce Flow best practice to add a Fault Path to Actions so that users (and admins) do not get ugly error emails. Additionally, when a Fault occurs, the transaction is rolled back and saves are lost. You can create a Fault Path by connecting an action to a second target.
Overcast actions will throw exceptions when there is something that is cannot recover from, like the configuration is bad.
Records failing to be mapped by the object mapping operation do not cause a Fault. The error is logged on the mapping run, the mapping run ends with an appropriate error status code, and the Flow action completes normally with the output values Success and Status Code reflecting the status code.
.png?Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cHM6Ly9kemY4dnF2MjRlcWhnLmNsb3VkZnJvbnQubmV0L3VzZXJmaWxlcy83NDg4LzMyMTM5L2NrZmluZGVyL2ltYWdlcy9xdS9pbWFnZSgxMDIpLnBuZyIsIkNvbmRpdGlvbiI6eyJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTc2NjM5Nzg0Mn19fV19&Signature=aZpIcrfNmfIW5OJiHxeTvD1pzw~18lpcAgmAL3DgRZgOEogCukkd-Yt-k0qmcdDsVIEd1eFPQWneqBwpwCGGcsA1Q8SuczCDJkgsr9QThN6ZxGw145IILDnf-8SbpdlZtKFiIbGxdAncTpTzAUgW1G~rSZw67czxeBe6Tsgm5cPKEWhdozDdLp3TjfBnDRtG5yjzoJmry4Pqi56DvR00mVVruZSfvruBjSSNun6v14F0zXyI-Z6JlH89LwWpXwIM00YiQiaEExKRfJzCD6AUM0yqCFTlA8HANMAfzCGpo-dhCauRHtCroJ5Mza2tupDz1Y12Qf~MvGnv3hosY4W4lQ__&Key-Pair-Id=K2TK3EG287XSFC)
This Flow shows when the mapping operation Map products completes successfully a record is updated with the result.
The Decision element checks the output value Map products > Success equals true.
.png?Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cHM6Ly9kemY4dnF2MjRlcWhnLmNsb3VkZnJvbnQubmV0L3VzZXJmaWxlcy83NDg4LzMyMTM5L2NrZmluZGVyL2ltYWdlcy9xdS9pbWFnZSgxMDMpLnBuZyIsIkNvbmRpdGlvbiI6eyJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTc2NjM5Nzg0Mn19fV19&Signature=nGvYpvVW6I0FnUrRiIkrEqjAUAbl9YR50TMhKHFyiC-bi4vx3ofVoksMoT9PEt~RnzZ0dRdH23BVJYJXpUjvLqlmkt1fqSuooe4ErVchuaeoxLI7AbNlVUcEM18lRak2w5l7WAvUrQO1CYEKqwYHgMEf2SrrtsrCpIwiFsGjdpjGmuoP0n9rphkAAVFlpYz9MYlpny2hj4Gwk330w5o0mNV1aEzSDSKbkaCXfYah2Qocee~bAfFOtbN930TxCJ1OfhvAOsOJVP0Ak4RhQJN-JqOWPx6CGhj3X2D2vyQKi5PFPv3UgDNVVUdFZzci04QGO58X5TlNyvzWagznWz1Jsw__&Key-Pair-Id=K2TK3EG287XSFC)
- Open the Scenario and edit it.
- In the Inbound Mapping Orchestration field, select the Flow you created in Basic Flow Setup.
- Set IO Records Deletion to After mapping each batch.
This is set so records can be deleted in the same transaction. In the case of too many records for a transaction, setting this allows the Scenario mapping operation to be rerun to process the remaining records. If After mapping each batch is not set and too many records are required to be mapped, then the mapping operation is terminated without performing any mapping.
- Save. There is no need to Activate.
Configuration complete. Now you can run the Scenario and your flow will run to process the records.