IMAExtensible2CallExport.PutExportEntries Method

Persists a batch of entries in the connected system. Called for multiple entries that are exported. It can be assumed OpenExportConnection has been called successfully.

Namespace: Microsoft.MetadirectoryServices
Assembly: Microsoft.MetadirectoryServicesEx (in Microsoft.MetadirectoryServicesEx.dll)

Usage

'Usage
Dim instance As IMAExtensible2CallExport
Dim csentries As IList(Of CSEntryChange)
Dim returnValue As PutExportEntriesResults

returnValue = instance.PutExportEntries(csentries)

Syntax

'Declaration
Function PutExportEntries ( _
    csentries As IList(Of CSEntryChange) _
) As PutExportEntriesResults
PutExportEntriesResults PutExportEntries (
    IList<CSEntryChange> csentries
)
PutExportEntriesResults^ PutExportEntries (
    IList<CSEntryChange^>^ csentries
)
PutExportEntriesResults PutExportEntries (
    IList<CSEntryChange> csentries
)
function PutExportEntries (
    csentries : IList<CSEntryChange>
) : PutExportEntriesResults

Parameters

  • csentries
    Contains a CSEntryChange object specifying the object that is to be exported. If the anchor attributes do not exist they must be set, otherwise the object is read-only.

Return Value

Returns PutExportEntriesResults object that contains the entry identifier, the added anchor attributes, and the returned error code for each entry in the connected system..

Remarks

PutExportEntries is the workhorse for export. It will be called until there are no more objects to be exported to the connected directory. Objects are provided in batches as specified on the Run Step profile. There are two different export types “Export” and “Full Export”. If this method is implemented then “Export” is expected to be implemented and is always offered as a possible run step. If Full Export is supported then the associated setting in the MACapabilities method should be set. For “Export” the engine will provide delta changes since last run. For “Full Export” the engine will provide all objects and all attributes in the connector space regardless if they have changed or not. “Full Export” is used in cases where the target directory does not store state or suffers from “amnesia” for which a full import cannot successfully detect a change.

Objects can be provided in three different variants: “Object Replace”, “Attribute Replace”, and “Attribute Update”. Which variant to be used is defined in the GetCapabilities method.

With “Object Replace” all attributes for an object is always provided regardless if a particular attribute has changed or not. This is useful for connected directories where the existing object is effectively dropped before a new is created. For “Attribute Replace” only attributes which has changed will be provided. For multi-valued attributes a full representation of all values will be provided. If using “Attribute Update” the difference from Attribute Replace is that multi-valued attributes are provided as a list of values to be added and values to be removed from the list.

For each object the ExportError should be set to indicate the result of the operation where success is the default. For object level errors there are two basic sets: actions and errors. An error is a condition where the object should not be retried again in this export run and an error is reported to the administrator. It is expected the administrator must take a corrective action for this object to be successfully exported. An action is a condition where the object couldn’t be exported but where the engine should take an action to correct the situation.

  • ConvertUpdateToAdd – The engine supplied an Update operation for an Object for which there is no representation in the target directory. The engine should convert the operation to an add and supply all attributes in a future batch.

  • RetryReferenceAttributes – There was an issue with at least one reference attribute, most likely because a referenced object couldn’t be resolved, but all other attributes where accepted. The engine should retry the reference attributes later.

  • ProvisioningParent – The hierarchy for this object’s distinguishedName does not exist. The engine should re-provision the LDAP hierarchy and retry this object.

An object can appear several times in one export run. The engine divides an export into several passes. During an export the engine will sort all objects in the order which will be most efficient for reference attributes. As a rule of thumb all objects with no references will appear first in export and objects with many references, e.g. groups with many members, will appear last. If an object has references to objects which have not yet been exported then reference attributes will be suppressed by the engine and the object will be marked for a retry. The other way to mark an object for retry is by returning RetryRefenceAttributes as described above. When all objects have been exported once, all objects marked for retry will see an update to the object with only reference attributes. In the UI this move from one pass to the next can be seen by the completion moving from 100% back to 0% and the process start over again. The engine will determine how many passes should be tried for an export. If reference attributes should not be provided in the first pass, then set the NoReferenceValuesInFirstExport to false. Reference attributes will only be provided in the second pass when this setting is set.

It is assumed that an exported change can be confirmed by an import. If a particular attribute cannot be confirmed, make sure it is marked as ExportOnly in the schema. If object delete operations cannot be confirmed in a delta import then set the ObjectConfirmation to NoDeleteConfirmation. If the object is reported as successfully deleted during export then the engine will automatically confirm the delete.

If the password attribute export_password has been set during provisioning then the default behavior is that the password will not be provided to this method and that SetPassword is instead called to set the password after the object has been created. If the password should be provided to this method then set the ExportPasswordInFirstPass to true. Note: It is the responsibility of the developer to verify that the connection is secure in this case so the password isn’t exported over a clear text channel.

The following is an example of PutExportEntries:

  public PutExportEntriesResults PutExportEntries(IList<CSEntryChange> csentries)
        {
            string modType = null;
 
            //
            // The csentries parameter contains a collection of CSEntryChange
            // objects that need to be exported.  The number of CSEntryChange
            // objects is determined by the bacth size set on the Run Profile Step,
            // which contain be obtained from exportRunStep.BatchSize in OpenExportConnection().
            //
            foreach (CSEntryChange entryChange in csentries)
            {
                m_xmlWriterExport.WriteStartElement(Nodes.Object);
 
                m_xmlWriterExport.WriteElementString(Nodes.ObjectType, entryChange.ObjectType);
 
                switch (entryChange.ObjectModificationType)
                {
                    case ObjectModificationType.Add:
                        modType = "Add";
                        break;
 
                    case ObjectModificationType.Delete:
                        modType = "Delete";
                        break;
 
                    case ObjectModificationType.Replace:
                        modType = "Replace";
                        break;
 
                    case ObjectModificationType.Update:
                        modType = "Update";
                        break;
 
                    default:
                        throw new UnexpectedDataException();
                }
 
                m_xmlWriterExport.WriteElementString(Nodes.ObjectChange, modType);
 
                //
                // One can use the CSEntryChange.ChangedAttributes array and iterate
                // through that to push out changes only to those attributes that
                // have changed.
                //
                foreach (string changeAttributeName in entryChange.ChangedAttributeNames)
                {
                    m_xmlWriterExport.WriteStartElement(changeAttributeName);
 
                    AttributeChange attributeChange = entryChange.AttributeChanges[changeAttributeName];
 
                    // Add attribute modification type to the xml
                    string attributeChangeType = null;
                    switch (attributeChange.ModificationType)
                    {
                        case AttributeModificationType.Add:
                            attributeChangeType = "Add";
                            break;
 
                        case AttributeModificationType.Delete:
                            attributeChangeType = "Delete";
                            break;
 
                        case AttributeModificationType.Replace:
                            attributeChangeType = "Replace";
                            break;
 
                        case AttributeModificationType.Update:
                            attributeChangeType = "Update";
                            break;
 
                        default:
                            throw new UnexpectedDataException();
                    }
 
                    m_xmlWriterExport.WriteElementString(Nodes.AttributeChange, attributeChangeType);
 
 
                    // Add the values to the XML
                    IList<ValueChange> valueChanges = attributeChange.ValueChanges;
                    if (null != valueChanges)
                    {
                        m_xmlWriterExport.WriteStartElement(Nodes.Values);
 
                        //Add each value and its modification type to the xml.
                        foreach (ValueChange valueChange in valueChanges)
                        {
                            m_xmlWriterExport.WriteStartElement(Nodes.Value);
 
                            string valueChangeType = null;
                            switch (valueChange.ModificationType)
                            {
                                case ValueModificationType.Add:
                                    valueChangeType = "Add";
                                    break;
 
                                case ValueModificationType.Delete:
                                    valueChangeType = "Delete";
                                    break;
 
                                default:
                                    throw new UnexpectedDataException();
                            }
                            m_xmlWriterExport.WriteAttributeString(Nodes.ValueChange, valueChangeType);
 
                            m_xmlWriterExport.WriteValue(valueChange.Value.ToString());
 
                            // end Nodes.Value
                            m_xmlWriterExport.WriteEndElement();
                        }
 
                        // end Nodes.Values
                        m_xmlWriterExport.WriteEndElement();
                    }
 
                    // end changeAttributeName
                    m_xmlWriterExport.WriteEndElement();
                }
 
                // end Nodes.Object
                m_xmlWriterExport.WriteEndElement();
            }
 
            PutExportEntriesResults exportEntriesResults = new PutExportEntriesResults();
 
            return exportEntriesResults;
        }

Thread Safety

Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

Platforms

Target Platforms

Change History

See Also

Reference

IMAExtensible2CallExport Interface
IMAExtensible2CallExport Members
Microsoft.MetadirectoryServices Namespace