To signal to the sync engine that you support import, you implement the IMAExtensible2CallImport interface. If you do not implement the interface, it indicates that you have an export-only connector.

You must support full import. Support for delta import is optional.


The open connection method is used to establish a connection and prepare any configuration. It receives more information about the configuration than the other methods. Its signature is as follows:

Function OpenImportConnection(configParameters, types, importRunStep) As OpenImportConnectionResults

ConfigParameters is a collection of all parameters configured on the Connector. These can be Global, Partition, or defined on a run step.

Types contains the schema, including the attributes that are selected as included by the administrator. In some cases, the target directory does not have many attributes so there is no performance problem in always asking for all of them. But in other cases that could be problematic and the connector should then only query for the attributes selected by the administrator.

ImportRunStep contains several important concepts a connector might need to worry about.

The ImportRunStep contains information about the hierarchy nodes selected. A connector can select to use this information or ignore it. When data during import is passed to the sync engine and it represents an object in an out-of-scope OU, the sync engine ignores it and does not stage it. If it makes sense to look at the hierarchy information depends on the target directory. As an example, the built-in ADMA does not look at this information and during a full import, it reads all information from AD. The technical reason is because it can quickly be a performance problem in AD to pass in too many OU filters to the AD APIs. The solution in avoiding performance issues is to read everything from AD and let the sync engine figure out what to keep and what to throw away.

The ImportRunStep also contains OperationType. The OperationType is defined so it can have the following values:

  • Delta
  • Full
  • FullObject

Delta and Full are representing a delta or full import. The FullObject option requires a longer explanation.

OperationType FullObject

In OpenImportConnection this property can only have the values Delta or Full. This information was also supposed to be in GetImportEntriesRunStep but is unfortunately missing and requires a workaround.

First, we must understand the scenario. This can only happen when you use the LDAP DN-style and you have implemented hierarchies. In this case, during a full import, it is possible that some entries are thrown away by the sync engine since these represent objects in out-of-scope OUs. Then during delta import, a rename of an object from an out-of-scope to an in-scope OU is seen and passed to the sync engine. When this happens, the sync engine does not have any other attribute for the object than the DN. The object is put in the sync engines FullObject-needed list.

In the next call to GetImportEntries the FullObjectEntries structure is populated with objects where the sync engine needs all attributes.

Here comes the issue. Since the OperationType isn't present in the GetImportEntries structure, the connector must instead look at FullObjectEntries and if it is populated, then it must provide a full import (that is, all attributes) of these objects. The intention of the interface is that if FullObjects should be returned, then only the objects asked for should be returned and nothing else.

In GetImportEntries, you should think of your code working like this:

if (this.importType == OperationType.Full)
{code here}
else if (this.importType == OperationType.Delta)
{code here}
else if (this.importType == OperationType.FullObject)
{code here}
{throw new NotSupportedException("Unexpected import type: " + this.importType);}

But rather than looking at OperationType.FullObject, because it doesn't occur in real life, you need to look at the presence of FullObjectEntries instead.


The workhorse for import is the function GetImportEntries. Its signature is as follows:

Function GetImportEntries(GetImportEntriesRunStep) As GetImportEntriesResults

The page size property is indicating the maximum number of objects you can return. You can return fewer objects. You do not have to fill up the pages to the size of a page. This can be convenient when you have to read objects by querying for all objects starting with A, then with all starting with B, and so on.

The entries are returned as a collection of CSEntryChange objects.

In this structure, you should return the ObjectModification type. In full import, this should always be "Add" indicating a full object. In delta import this can be "Add", "Delete", or "Update". But you don't have to use all of these in delta import. In some cases, you can only tell that the object has changed, but not which attributes. In that case, return all objects as "Add" with all attributes and the sync engine calculates the changed attributes.

On each object, you can also return an object-level error. If you do not set anything, it is assumed that the object was successfully read from the connected directory.

With each page, you should return moreToImport to indicate if there is more data in the connected directory to read. When set to true, the sync engine calls the method again to get more data.

If you support delta import, at the end of both full import and delta import you should also set customData with information about the watermark. You might store other information in this property, but the intended use is only to store the watermark and make sure you understand how errors affects it.


This method is called after GetImportEntries has indicated that there is nothing more to import. It is also called when the run is stopped from the UI or an exception is thrown from the other methods. In this method, you should close the connection to the connected directory.

Function CloseImportConnection(importRunStep) As CloseImportConnectionResults