Hi
I'm having some difficulty with the full sync between UNS and a target system built from a SQL database which uses an autonumber column for its ID column.
If records are created in the target system first, I build the DistinguishedName to include the ID, like this: UID=92,CN=xxx.yyy,system=SampleOrderSystem. By default, Identity Manager uses a distinguishedname convention CN=xxx yyy,system=systemname, but after a fullsync we can update the distinguishedname to contain the ID. In addition to this, I've started storing the UID number in a custom attribute called CCC_UNSAccountB_UID.
But if an object is created in Identity Manager first, we have to wait for a callback from the target system to know what its UID in the target system has been assigned to - it won't be in the distinguishedname or CCC_UNSAccountB_UID until then.
I have a script property called DistinguishedNameContainsUID which consistently gives us the UID from the distinguishedname in UNS if one already exists, else it returns an empty string:
dim Result as String = ""
Dim dn as String = $DistinguishedName$
Dim UIDPattern As String = "^UID=(?<uid>.+?)(?<!\\),"
Dim re As Regex = New Regex(UIDPattern)
Dim m As Match = re.Match(dn)
If m.Success Then
' Item with index 1 returns the first group match.
Result = m.Groups(1).Value
End If
return Result
Another script property, CNWithoutSpacesIfNoUID, gives us the ConcatNames from UNS if DistinguishedNameContainsUID is empty:
Dim CNWithoutSpaces as String = ""
if $CCC_UNSAccountB_UID$= "" AND $DistinguishedNameContainsUID$="" then
CNWithoutSpaces = $LastName$ & $FirstName$
end if
The object mapping rules are such that if the UID is the same on both sides then we have a one-to-one match between UNS and the target system, but if there is no ID on the UNS account then we have to match using lastname and firstname. Although this could be problematic if we simply used the name fields, you would never see more than one UNSAccountB row with the same CNWithoutSpaces response at the same time for the simple reason that the value is only valid during the interval between two steps within a single synchronization workflow.
So this workflow runs perfectly as long as an account is created in the target system first, but I keep having problems if someone creates an account in Manager first.
For example, on the last unit test I created a UNS account for a test user, ran the sync, and the result was one UNSAccountB row created without the UIDs (as I'd expect), which triggered the account creation in the target system, swiftly followed by another one when the target system returned the UID...
If I then simulate another sync, I can see this in the simulation report:
Processed objects
Schema type Method Count
UNSAccountB Delete 1
UNSAccountB Update 1
Executed methods on system objects
Schema type System object Method
UNSAccountB SampleOrderSystem/Test 001 (SampleOrderSystem) Delete
UNSAccountB SampleOrderSystem/001.Test/98 (SampleOrderSystem) Update
So this actually means the provisioning workflow is going to delete the record that we explicitly requested from Manager and which already matches a legitimate person object in use, in order to maintain the record that matches a totally different Person object unrelated to the employee we were managing.
Can anyone think of a way to configure this sync so that the target system --> UNS sync workflow updates the existing record instead of ignoring it completely? After all, that UNS account already has everything in it EXCEPT the UID...
Cheers
Tim