The Custom SFDMU Add-On Api.

The Custom SFDMU Add-On Api allows you to build your own SFDMU Add-On extensions allowing you to extend the SFDMU with unlimited new custom features which may be required by your business.

Together with the Core SFDMU Add-On Module Api it forms the SFDMU Add-On API Engine.


==> VIEW ALSO THE CUSTOM ADD-ON API OBJECT REFERENCE <==

The example of the Custom SFDMU Add-On module.

For the example purposes, we are providing the test custom Add-On module. You can use this module as a basic code snipped for building your modules.

This Add-On makes a simple modification in the source records just before they will be uploaded to the target SF environment.

These instructions are for the Windows OS, but you can transfer it to other OS making appropriate modifications.

How to try this example ?

Working with the SFDMU Add-On Api requires the source code of the SFDMU Plugin installed in your machine.

Step 1. You should create the local clone of the SFDMU repository or use the already existed local clone.

cd C:\
git clone https://github.com/forcedotcom/SFDX-Data-Move-Utility
cd C:\SFDX-Data-Move-Utility
npm install

Step 2. Since we need to compile the module before use, let's compile the SFDMU source code. All the Add-Ons will be also compiled with the same command as they are the part of the SFDMU.

npm run build

Step 3. Now create the directory C:\MySfdmuAddOns which will contain all custom modules.

Copy into this directory the compiled sources listed below:

  • The module compiled component folder (take it from C:\SFDX-Data-Move-Utility\lib\addons\modules\sfdmu-run\custom-addons\CustomSfdmuRunAddonTemplate).
  • The compiled version of the Add-On Library package folder ( located at C:\SFDX-Data-Move-Utility\lib\addons\modules\sfdmu-run\custom-addons\package).

The target directory structure should be looked like this:


|-- C:\MySfdmuAddOns                    <= The root directory for all Add-On modules

      |-- CustomSfdmuRunAddonTemplate        <= The sample module component

      |      |-- index.d.ts

      |      |-- index.js

    |      |-- index.js.map

      |-- TestModule                        <= Another custom module component

      |      |--  index.d.ts

      |      |--  other module files ...

      |--    other modules ...

      |-- package                            <= The mandatory Add-On Library package.

    |--        |-- common.js

    |--        |-- index.js

    |--        |-- other package files ...

You don't need to update the package folder each time your are creating or compiling your modules. Upgrade it once we are pushing a new release of the SFDMU.

Basically, the module component must contain only one file: index.js (the source code is index.ts) It's the main entry point of each module and will be executed by the SFDMU Plugin during the migration job.

Step 4. Create export.json file with the following content:

{
    "objects": [
        {
            "operation": "Upsert",
            "externalId": "Name",
            "deleteOldData" : true,
            "query": "SELECT Id, Name, LongText__c, TEST__c, TEST1__c  FROM Account WHERE Name = 'ACC_10000'",            
            "beforeUpdateAddons" : [
                {
                        "description": "This example of the Sustom SFDMU AddOn module manipulates with the source Account records right before the target SF object going to be updated. It extracts the value from the JSON stored in the LongText__c, then puts the extracted string into the TEST1__c.",
                        "path" : "C:\\MySfdmuAddOns\\CustomSfdmuRunAddonTemplate",                
                        "args" : {
                            "TEST__c": "Another small manipulation with the source data: we want to populate the TEST__c field of each record with this constant text."
                        }
                }
            ] 
        }
    ]
}

Put this export.json into C:\SFDMU\CustomSfdmuRunAddonTemplate

Take a quick look on the export.json structure.

The array beforeUpdateAddons is the beforeUpdate Add-On Event Declaration. It defines the lists the Add-On modules which should be launched right BEFORE the Account object is going to be updated on the Target environment. Here you can make a modifications in the source records, then your modifications will be uploaded to the Target.

In our case we want to run only the module CustomSfdmuRunAddonTemplate, but unlimited number of modules can be attached to the same event.

Step 5. In the Source and the Target SF orgs add to the Account sObject three new custom fields:

  • LongText__c (Long Text Area(32768))

  • TEST__c (Text(255))

  • TEST1__c (Text(255))

Step 6. Create new Account record, initialized with the following values:

  • Name: ACC_10000

  • LongText__c: {

    "TEST1__c" : "Test Value"

    }

Step 7. Launch the SFDMU migration job, using the export.json created in the Step 4.

sfdx sfdmu:run --sourceusername source@name.com --targetusername target@name.com --path C:\\SFDMU\CustomSfdmuRunAddonTemplate

Step 8. Verify that the migration job done correctly and the Add-On has worked as expected:

  • Open the target salesforce Org, locate the Account record having the Name ACC_1000, which was created by the latest migration job.

  • Click the Account "Details" tab. You should have these fields populated:

    • LongText {

        "TEST1\_\_c" : "Test Value"

      }

      • TEST1

        Test Value

      • TEST

        Another small manipulation with the source data: we want to populate the TEST__c field of each record with this constant text.

That's done :)

The full specification of the Add-On Event declaration.

Property Name Is Mandatory ? Data type Description
description No string The description of the module.

Passed to the Add-On instance using the module run-time context object.
path Yes string The local absolute or relative path to the directory where the compiled module and the Api library package are located. We recommend using absolute paths for better chance that the Plugin will locate the module properly.
args No Object The optional object passed as is to the module onExecute method using the args method parameter (see below). Use this parameter for the customized initialization of the Add-On instance via the script definition.

The supported events:

Event Name Type When Fired ? Description
OnDataRetrieved One-time global event. Runs only once for the migration job after all records of all sobjects in the script were already retrieved from the Source and from the Target, but before starting to update the Target. The source records of all sobjects can be accessed and modified.

The target records of all sobjects can be accessed and modified only if this is not the Insert operation, since the records do not exist in the Target yet.
The modified records will be uploaded to the Target during the next update stage.
Object.OnBefore One-time per-sobject event. Runs only once for the current sobject after its records were already retrieved from the Source and from the Target, but before the Target is updated. The source records of the current sobject can be accessed and modified.

The target records can be accessed and modified only if this is not the Insert operation, since the records do not exist in the Target yet.
The modified records will be uploaded to the Target during the next update stage.
Object.OnAfter One-time per-object event. Runs only once for the current sobject after the entire migration job is fully finished. Both the source and the target records can be accessed and modified.
The modifications done with the records will not be uploaded to Target since the job is already completed at this stage.
Object.OnBeforeUpdate Per-stage & per-object event. Runs for the current sobject on each update stage before the Target is updated. Here you have the additional option to directly assess and modify the final version of the source records which are now about to be transferred to the Target.
Moreover for the easiest access, the records are separated to 2 different groups: RecordsToBeUpdated and RecordsToBeInserted
Object.OnTargetDataFiltering Per-stage & per-object event. Runs for the current sobject when the source records are prepared to be uploaded to the Target. Here you can access and modify the source records using the tempRecords property defined in the SfdmuRunAddonTask object.
Object.OnAfterUpdate Per-stage & per-object event. Runs for the current sobject on each update stage after the Target is updated. Both the source and the target records can be accessed and modified.
The modified records will be uploaded to the Target during the next update stage.

How to create and run your own Custom SFDMU Add-On Module ?

It's pretty simple and can be done at the same way as we run the sample module above.

Let's create another module TestModule.

Step 1. Create new subdirectory TestModule under C:\SFDX-Data-Move-Utility\src\addons\modules\sfdmu-run\custom-addons, then create new index.ts file inside it.

The content of the index.ts is:

import { ISfdmuRunCustomAddonContext, ISfdmuRunCustomAddonModule, ISfdmuRunCustomAddonResult, ISfdmuRunCustomAddonRuntime } from "../package";

export default class SfdmuCustomAddOnModule implements ISfdmuRunCustomAddonModule {

    constructor(runtime: ISfdmuRunCustomAddonRuntime) {
        this.runtime = runtime;
    }

    runtime: ISfdmuRunCustomAddonRuntime;

    async onExecute(context: ISfdmuRunCustomAddonContext, args: any): Promise<ISfdmuRunCustomAddonResult> {

        // Just for the example... The line below will prints to the Console the following: "The running Plugin is: sfdmu".
        // TODO: Put your own code instead this line.
        this.runtime.service.log(this, 'The running Plugin is: ' +  this.runtime.service.getPluginRunInfo().pinfo.pluginName);

        // Return null to continue the migration job
        return null;
    }
}

Step 2. Compile the SFDMU and ensure that the complilator does not throw any errors.

cd C:\SFDX-Data-Move-Utility
npm run build

Step 3. Copy the compiled module component files from C:\SFDX-Data-Move-Utility\lib\addons\modules\sfdmu-run\custom-addons\TestModule to C:\MySfdmuAddOns\TestModule

Step 4. Create export.json.

{
    "objects": [
        {
            "operation": "Insert",
            "query": "SELECT Name FROM Account WHERE Name = 'ACC_10000'",            
            "beforeUpdateAddons" : [
                {                        
                    "path" : "C:\\MySfdmuAddOns\\TestModule"
                }
            ] 
        }
    ]
}

Put this file into C:\SFDMU\TestModule

Step 5. Run the job.

sfdx sfdmu:run --sourceusername source@name.com --targetusername target@name.com --path C:\SFDMU\TestModule

Step 6. Verify the results.

As the result of the job, the new Account record should be created in the Target org and the Add-On should print in the Console window like that:

[2021-10-18 08:48:20.619] {Account} Executing of the event:onBeforeUpdate Add-On handlers has started

[2021-10-18 08:48:20.620] [custom:TestModule] {Account} The running Plugin is: sfdmu

[2021-10-18 08:48:20.622] {Account} Executing of the event:onBeforeUpdate Add-On handlers has finished

How to debug the Custom Add-On module ?

As the custom Add-On component is a part of the SFDMU, it can be debugged together with the entire SFDMU Plugin.

When developing the module, simply put the break point in the module code and run the Plugin in debug mode.

See also Debugging


See also:

Introduction to the SFDMU Add-On Api Engine

The Export Files Core Add-On Module

The Custom Add-On Api object reference

Full export.json format

Last updated on Th Nov 2022