---
title: Sync operation
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:operations/operation-sync
canonical_url: https://docs.pingidentity.com/pingidm/7.2/connector-dev-guide/operations/operation-sync.html
section_ids:
  SyncApiOp-api-level-rules: Use the OpenICF sync operation
  SyncOp-spi-level-rules: Implement the sync operation
---

# Sync operation

|   |                                                                                                                                                                                   |
| - | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | 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). |

The sync operation polls the target system for synchronization events, that is, native changes to target objects.

The operation has two methods:

* `sync()` - request synchronization events from the target system

  This method calls the specified handler, once, to pass back each matching synchronization event. When the method returns, it will no longer invoke the specified handler.

* `getLatestSyncToken()` - returns the token corresponding to the most recent synchronization event

## Use the OpenICF sync operation

Consumption of the Sync Operation(`getLatestSyncToken()` Method), at the API Level

```java
@Test
public void getLatestSyncTokenTest() {
    logger.info("Running GetLatestSyncToken Test");
    final ConnectorFacade facade = createConnectorFacade(BasicConnector.class, null);
    SyncToken token = facade.getLatestSyncToken(ObjectClass.ACCOUNT);
    Assert.assertEquals(token.getValue(), 10);
}
```

The `getLatestSyncToken` method throws an `IllegalArgumentException` if the `objectClass` is null or invalid.

Consumption of the Sync Operation (`sync()`Method), at the API Level

```java
@Test
public void syncTest() {
    logger.info("Running Sync Test");
    final ConnectorFacade facade = createConnectorFacade(BasicConnector.class, null);
    final OperationOptionsBuilder builder = new OperationOptionsBuilder();
    builder.setPageSize(10);
    final SyncResultsHandler handler = new SyncResultsHandler() {
        public boolean handle(SyncDelta delta) {
            return false;
        }
    };

    SyncToken token =
            facade.sync(ObjectClass.ACCOUNT, new SyncToken(10), handler, builder.build());
    Assert.assertEquals(token.getValue(), 10);
}
```

The `sync` method throws an `IllegalArgumentException` if the `objectClass` or `handler` is null, or if any argument is invalid.

## Implement the sync operation

Implementation of the Sync Operation at the SPI Level

```java
public void sync(ObjectClass objectClass, SyncToken token, SyncResultsHandler handler,
        final OperationOptions options) {
    if (ObjectClass.ALL.equals(objectClass)) {
        //
    } else if (ObjectClass.ACCOUNT.equals(objectClass)) {
        final ConnectorObjectBuilder builder = new ConnectorObjectBuilder();
        builder.setUid("3f50eca0-f5e9-11e3-a3ac-0800200c9a66");
        builder.setName("Foo");
        builder.addAttribute(AttributeBuilder.buildEnabled(true));

        final SyncDeltaBuilder deltaBuilder = new SyncDeltaBuilder();
        deltaBuilder.setObject(builder.build());
        deltaBuilder.setDeltaType(SyncDeltaType.CREATE);
        deltaBuilder.setToken(new SyncToken(10));

        for (SyncDelta connectorObject : CollectionUtil.newSet(deltaBuilder.build())) {
            if (!handler.handle(connectorObject)) {
                // Stop iterating because the handler stopped processing
                break;
            }
        }
    } else {
        logger.warn("Sync of type {0} is not supported", configuration.getConnectorMessages()
                .format(objectClass.getDisplayNameKey(), objectClass.getObjectClassValue()));
        throw new UnsupportedOperationException("Sync of type"
                + objectClass.getObjectClassValue() + " is not supported");
    }
    ((SyncTokenResultsHandler) handler).handleResult(new SyncToken(10));
}

public SyncToken getLatestSyncToken(ObjectClass objectClass) {
    if (ObjectClass.ACCOUNT.equals(objectClass)) {
        return new SyncToken(10);
    } else {
        logger.warn("Sync of type {0} is not supported", configuration.getConnectorMessages()
                .format(objectClass.getDisplayNameKey(), objectClass.getObjectClassValue()));
        throw new UnsupportedOperationException("Sync of type"
                + objectClass.getObjectClassValue() + " is not supported");
    }
}
```
