How to: Create Unique Naming Attributes in the Metaverse

Some attributes in a connector space, such as samAccountName in Active Directory Domain Services (AD DS), must have a unique value in that connector space. When you import objects from a connected system to the FIM Synchronization Service database (metaverse), the imported objects might have attribute values that already exist on other objects in the metaverse. You can use a rules extension to enforce that an object that is projected or joined to the metaverse has unique attribute values. If an attribute value from this object already exists in the metaverse, you can provide conflict resolution logic to create a unique attribute value for it as part of the import process.

Note

You do not have to limit your checks for uniqueness to only FIM Synchronization Service data sources. You can also use external data sources to check for uniqueness. The downside to using any external source is the additional challenges they present, including possible performance problems and debugging issues.

The following examples show how to create a unique attribute value in the metaverse.

Public Sub MapAttributesForImport( _
    ByVal FlowRuleName As String, _
    ByVal csentry As CSEntry, _
    ByVal mventry As MVEntry) _
    Implements IMASynchronization.MapAttributesForImport

    Select Case FlowRuleName
        Case "mailNicknameMapping"

            ' If the mailnickname attribute exists, set to attribute to
            ' a value from the nickname function. If the nickname attribute
            ' does not exist, delete the <tla rid="fim_syncdb_short" /> entry.
            If csentry("mailnickname").IsPresent Then

                ' The value for the mailnickname attribute should be unique on every 
                ' <tla rid="fim_syncdb_short" /> entry. To create a unique value, call a function that
                ' calculates a unique name based upon the connector space entry.
                ' Use this calculated value as the attribute value for the <tla rid="fim_syncdb_short" />
                ' entry.
                Dim newMailNickname As String
                newMailNickname = GetCheckedMailNickName(csentry("mailnickname").Value, mventry)

                ' If a unique nickname could not be created, throw an exception.
                If newMailNickname.Equals("") Then
                    Throw New TerminateRunException("A unique mailNickname could not be found")
                End If

                mventry("mailNickname").Value = newMailNickname
            Else
                mventry("mailNickname").Delete()
            End If
        Case Else
    End Select
End Sub

' This function checks passed value for uniqueness and also creates new values.
Public Function GetCheckedMailNickName( _
      ByVal mailNickname As String, _
      ByVal mventry As MVEntry) As String

    Dim findResultList() As MVEntry
    Dim checkedMailNickname As String = mailNickname
    GetCheckedMailNickName = ""

    Dim nameSuffix As Integer
    Dim mvEntryFound As MVEntry

    ' Create a unique naming attribute by adding a number to
    ' the existing mailNickname value.
    For nameSuffix = 1 To 100
        ' Check if the passed mailNickname value exists in the <tla rid="fim_syncdb_short" /> by
        ' using the Utils.FindMVEntries method.
        findResultList = Utils.FindMVEntries("mailNickname", checkedMailNickname, 1)

        ' If the value does not exist in the <tla rid="fim_syncdb_short" />, use the passed value
        ' as the <tla rid="fim_syncdb_short" /> value.
        If findResultList.Length = 0 Then
            GetCheckedMailNickName = checkedMailNickname
            Exit For
        End If

        ' Check that the connector space entry is connected to the
        ' <tla rid="fim_syncdb_short" /> entry.
        mvEntryFound = findResultList(0)
        If mvEntryFound Is mventry Then
            GetCheckedMailNickName = checkedMailNickname
            Exit For
        End If

        ' If the passed value already exists, concatenate the counter number
        ' to the passed value and verify this new value exists. Repeat
        ' this step until a unique value is created.
        checkedMailNickname = mailNickname & nameSuffix.ToString
    Next
End Function
void IMASynchronization.MapAttributesForImport (string FlowRuleName, CSEntry csentry, MVEntry mventry)
{
    switch(FlowRuleName)
    {  
        case "mailNicknameMapping" :
            //case "mailNicknameMapping":
            // If the mailnickname attribute exists, set attribute to
            // a value from the nickname function. If the nickname attribute
            // does not exist, delete the <tla rid="fim_syncdb_short" /> entry.
            if(csentry["mailNickname"].IsPresent)
            {
                // The value for the mailnickname attribute should be unique on every 
                // <tla rid="fim_syncdb_short" /> entry. To create a unique value, call a function that
                // calculates a unique name based upon the connector space entry.
                // Use this calculated value as the attribute value for the <tla rid="fim_syncdb_short" />
                // entry.
                string newMailNickname = GetCheckedMailNickName(csentry["mailNickname"].Value, mventry);

                // If a unique nickname could not be created, throw an exception.
                if(newMailNickname.Equals(""))
                {
                    throw new TerminateRunException("A unique mailNickname could not be found");
                }

                mventry["mailNickname"].Value = newMailNickname;
            }
            else
            {
                mventry["mailNickname"].Delete();
            }
            break;

        default :
            break;
    }
}

// This function creates a unique mailNickname for use in a <tla rid="fim_syncdb_short" /> entry.
string GetCheckedMailNickName(string mailNickname, MVEntry mventry)
{
    MVEntry[] findResultList = null;
    string checkedMailNickname = mailNickname;

    // Create a unique naming attribute by adding a number to
    // the existing mailNickname value.
    for (int nameSuffix = 1; nameSuffix < 100; nameSuffix++)
    {
        // Check if the mailNickname value exists in the <tla rid="fim_syncdb_short" /> by 
        // using the Utils.FindMVEntries method.
        findResultList = Utils.FindMVEntries("mailNickname", checkedMailNickname, 1);
        if (findResultList.Length == 0)
        {
            // The current mailNickname is not in use.
            return(checkedMailNickname);
        }

        // If a <tla rid="fim_syncdb_short" /> entry was found with the specified mailNickname, 
        // see if this is the entry specified.
        MVEntry mvEntryFound = findResultList[0];
        if (mvEntryFound.Equals(mventry))
        {
            return(checkedMailNickname);
        }

        // If the passed nickname is already in use by another <tla rid="fim_syncdb_short" /> 
        // entry, concatenate the counter number to the passed value and 
        // verify this new value exists. Repeat this step until a unique 
        // value is created.
        checkedMailNickname = mailNickname + nameSuffix.ToString();
    }

    // Return an empty string if no unique nickname could be created.
    return "";
}

See Also

Concepts

Creating and Checking Attribute Values