Monday, September 08, 2008

Writing to the CSEntry During Export_Entry()

A while back I posted about writing the Anchor attribute to the CSEntry during the Export_Entry() routine in an XMA.

Recently I've done a little more work on it to narrow it down. There are some things to know about the scenario.

1. It only works with an XMA
no other MA has an Export_Entry() method, so that is fair.

2. It only works with the LDIF and DSML file types in an XMA
Those are the only two that support DNs, so that is fair.

3. Sometimes It Isn't Optional
If you set your anchor in MV.Provision, then you are not required to it during Export_Entry(). So if your MV.Provision method has code that resembles the code below, then you do not need to set the Anchor during Export_Entry():

// "GUID" is the anchor attribute on this 'LDIF XMA'
if (mventry.ObjectType == "Person" & mventry.ConnectedMAs["LDIF XMA"].Connectors.Count == 0)
{
CSEntry csentry = mventry.ConnectedMAs["LDIF XMA"].Connectors.StartNewConnector("Person");
csentry["GUID"].StringValue = Guid.NewGuid().ToString();
csentry.DN = mventry.ConnectedMAs["LDIF XMA"].EscapeDNComponent(string.Format("CN={0}", Guid.NewGuid().ToString()));
csentry.CommitNewConnector();
}

If you do NOT set the anchor in MV.Provision, then you need to set it during Export_Entry() otherwise you'll recieve an error at Export time with the error message:
"The anchor attributes were not set in export entry"

4. You Can Also Rename During Export_Entry()
If during Generate_Import() you use the object's Anchor in to construct the DN, then on Import you will see Renames. This is normal, because you've set the DN to one thing in your MV.Provision code, then Imported it as something else. This only works because you have the Anchor to track the objects. If you don't change the DN then you shouldn't see Renames.

NOTE (thanks for this Rob): renames during Export_Entry() are only possible if the anchor was not set in MV.Provision. The CSEntry's anchor is only writable when it has not been set in Provision code.

Finally, this post serves to upgrade the previous post's psuedo-code to sample code:

public void ExportEntry(
ModificationType modificationType,
string[] changedAttributes,
CSEntry csentry
)
{
// I might have code here to insert a row into SQL, then return the Unique ID as a String
// but instead I'm just going to pretend by generating a new GUID
String newAnchor = Guid.NewGuid().ToString();
// During ExportEntry() you wouldn't think that CSEntry is writable, but it is
// In fact, if I don't do this, then ILM will throw an exception on Export, with an error message of:
// "The anchor attributes were not set in export entry."
csentry["GUID"].StringValue = newAnchor;
// Output my entry to a file, which I'll then consume on Import
file.WriteLine("DN: ", csentry.DN.ToString());
file.WriteLine("ObjectClass: Person");
file.WriteLine("GUID: {0}", newAnchor); // --> This is my new anchor getting sent to the file
file.WriteLine();
}

No comments: