---
title: Synchronization script
description: Connectors continue to be released outside the IDM release. For the latest documentation, refer to the OpenICF documentation.
component: pingidm
version: 7.2
page_id: pingidm:connector-dev-guide:scripts/script-sync
canonical_url: https://docs.pingidentity.com/pingidm/7.2/connector-dev-guide/scripts/script-sync.html
---

# Synchronization script

|   |                                                                                                                                                                                   |
| - | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | Connectors continue to be released outside the IDM release. For the latest documentation, refer to the [OpenICF documentation](https://docs.pingidentity.com/openicf/index.html). |

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:

```groovy
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 OpenICF `SyncDelta` object.

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

  ```groovy
  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:

  ```groovy
  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:

  ```groovy
  // 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.
