ICF 1.5.20.26

Synchronization script

A synchronization script synchronizes objects between two resources. The script should retrieve all objects in the external resource that have been updated since some defined token.

A sample synchronization script for an SQL database is provided in openidm/samples/scripted-sql-with-mysql/tools/SyncScript.groovy.

Input variables

The following variables are available to a sync script:

configuration

A handler to the connector’s configuration object.

options

A handler to the Operation Options.

operation

An OperationType that corresponds to the action (GET_LATEST_SYNC_TOKEN or SYNC).

objectClass

The object class that is synchronized, such as __ACCOUNT__ or __GROUP__.

token

The value of the sync token.

handler

A Closure handler for processing the sync results.

log

A logger instance for the connector.

Returns

If the operation type is GET_LATEST_SYNC_TOKEN, the script must return an object that represents the last known SyncToken for the corresponding ObjectClass. For example:

def operation = operation as OperationType
def configuration = configuration as ScriptedConfiguration
def log = log as Log
def objectClass = objectClass as ObjectClass
def options = options as OperationOptions
def token = token as Object

case OperationType.GET_LATEST_SYNC_TOKEN:
        switch (objectClass) {
            case ObjectClass.ACCOUNT:
                return new SyncToken(17);
            case ObjectClass.GROUP:
                return new SyncToken(16);
            case ObjectClass.ALL:
                return new SyncToken(17);
// ....

If the operation type is SYNC, the script must return a new SyncToken for the corresponding ObjectClass. A Sync result handler (callback) is passed to the script to return the Sync results one by one. The handler must be called for each result.

The handler variable that is passed to the script is a Groovy Closure. It can be called in the following ways:

  • With an ICF SyncDelta object.

    You can use a SyncDeltaBuilder to build this object. For example:

    def builder = new SyncDeltaBuilder()
    builder.setUid(uidValue)
    builder.setToken(new SyncToken(5))
    builder.setDeltaType(SyncDeltaType.CREATE)
    builder.setObject(connectorObject)  // Use the ConnectorObjectBuilder class to build the ConnectorObject object.
    
    // Call the handler with the SyncDelta object
    handler builder.build()
  • Using a Groovy Closure.

    In this case, the Closure delegates calls to a specific Object that implements these calls. For example:

    handler {                       // The handler parameter here
                                                                              is a Closure
        syncToken tokenValue        // (mandatory), the method resolution for 'syncToken' is delegated to
                                       the Object handling the Closure
        <DELTA_TYPE>()              // (mandatory), DELTA_TYPE should be one of: CREATE, UPDATE, DELETE,
                                       CREATE_OR_UPDATE
        object connectorObject      // (optional if DELTA_TYPE is a DELETE), the method resolution for
                                       'object' is delegated to the Object handling the Closure
        previousUid prevUidValue    // (optional), use only if UID has changed
    }

    In the following example, the handler is called twice - first for a CREATE and then for a DELETE:

    // CREATE
    handler({
        syncToken 15
        CREATE()
        object {
            id nameValue
            uid uidValue as String
            objectClass ObjectClass.GROUP
            attribute 'gid', gidValue
            attribute 'description', descriptionValue
        }
    })
    
    // DELETE
    handler({
        syncToken 16
        DELETE(uidValue)
    }

    Optionally, when the action is SYNC, you might want to return a SyncToken at the end of the script. This is a convenient way to update the sync token if no relevant sync events are found.