Failover mechanism for Active Directory connector

It would be usefully if there is a failover mechanism for active directory connector.

Currently you can configure in Active Directory Synchronization project only one DC where the synchronizator conencts, but it can be that there is a connection failure for that specific DC and whole synchronization process fails.

It would be usefully if one could configure a pool of DCs for failover cases.

Is there plan for this kind behavior?

Parents
  • Thing is, that you would need to configure the sync to complete sync without any change optimizations as the changed modifier (USN) is different on each DC.

    Or are we talking about the ad-hoc synchronization from OneIM to AD?

  • You could convert the CP_ADServer variable into a scripted variable in the sync project (for a FullSync my comments from above apply. No synchronization optimization allowed then).

    In the script, you could determine a DC of your domain and do some other checks as well (ping, login, whatsoever).

    The sample script is just taking the first domain controller it gets from the collection: Further enhancements would be to check the DC classes, ping time, etc.

    References System.DirectoryServices.dll
    Imports System.DirectoryServices.ActiveDirectory
    
    
    		Dim RootDN as String = VariableSet.Item("CP_ADRootdn")
    
    		Dim DomainName As String = RootDN.Replace(",dc=",".").Replace("dc=","")
    		Dim DomainCon As New DirectoryContext(DirectoryContextType.Domain, DomainName)
    		
    		Dim DCs As DomainControllerCollection = Domain.GetDomain(DomainCon).DomainControllers
    		
    		Return DCs.Item(0).Name
    		
    		'For Each DC As DirectoryServices.ActiveDirectory.DomainController In DCs
             '   Return DC.Name
            'Next

  • Im interested in the further enhancements mentioned above but im not able to fin any suitable method in the DomainController class documentation  https://docs.microsoft.com/en-us/dotnet/api/system.directoryservices.activedirectory.domaincontroller?view=dotnet-plat-ext-6.0 nor in the DirectoryServer class docs.microsoft.com/.../system.directoryservices.activedirectory.directoryserver

  • Does  Domain.GetDomain(DomainCon).FindDomainController(LocatorOptions.WriteableRequired) will ensure the server is available ? 

  • Hi Markus,

    I know this is an old thread, but i managed to progress with this.

    However i need help with how to DELETE the DPRRevisionStore, which is what is storing the Revision counter.

    I want to delete the Revision counter every time the CP_ADServer is recalculated for another server; Typically an ordered list of ADServers will be sequentially traversed. If the PRIMARY ADServer is available, then revision counters should remain, however if a secondary ADServer is required, then revision counters will need to be removed, and then the new secondary ADServer is promoted as the new PRIMARY.

    The issue that i run into is line 38, whereby the compiler is complaining about the Session, 'Reference to a non-shared member requires an object reference'

    References System.DirectoryServices.dll
    References System.DirectoryServices.AccountManagement.dll
    Imports System.DirectoryServices.ActiveDirectory
    Imports System.DirectoryServices.AccountManagement
    
    References VI.DB.dll
    Imports VI.DB
    Imports VI.DB.Entities
    Imports VI.DB.Scripting
    Imports VI.DB.Scripting.ScriptBase
    
    Dim valid As Boolean = False	'Has valid ADServer been found
    Dim UID_DPRSystemVariableSet = VariableSet.Item("CP_UID_DPRSystemVariableSet")
    Dim ServiceName As String = VariableSet.Item("CP_BASEloginaccount")
    Dim ServicePassword As String = VariableSet.Item("CP_BASEpassword")
    Dim ServerList As String = VariableSet.Item("CP_ADServerList")
    Dim TargetADServers() As String = ServerList.Split(New Char() {","c})
    
    'Try to authenticate against PRIMARY ADServer, which is first in the ADServerList
    Try
    	Using context As New PrincipalContext(ContextType.Domain, TargetADServers(0))
    		valid = context.ValidateCredentials(ServiceName, ServicePassword)
    	End Using
    	If valid Then
    		'Return name of AD Server successfully authenticated against
    		Return TargetADServers(0)
    	End If		
    Catch ex As Exception
    	AppData.Instance.RaiseMessage(MsgSeverity.Warning, "Could not authenticate to PRIMARY ADServer " & TargetADServers(0) & " " & ex.ToString())
    End Try
    
    'WARNING: If valid is still false, then revision state needs to be deleted as different ADServers will have differing revision counter values
    'This will cause a full synchronisation!
    'Ensure that a valid Primary ADServer is always configured to be the first ADServer in ADServerList
    If (Not valid) Then
    	AppData.Instance.RaiseMessage(MsgSeverity.Warning, "Removing Revision Counters")
    	
    	Dim f As ISqlFormatter = Session.SqlFormatter
        Dim colDPRRevisionStore As IEntityCollection
    
        Dim qDPRRevisionStore = Query.From("DPRRevisionStore") _
                      .Where(f.Comparison("UID_DPRSystemVariableSet", UID_DPRSystemVariableSet, ValType.String, CompareOperator.Equal)) _
                      .Select("UID_DPRRevisionStore")
    
        ' Create a collection of Revision entries
        colDPRRevisionStore = Session.Source.GetCollection(qDPRRevisionStore)
    
        ' Run through the list of Revision entries
        For Each colElement As IEntity In colDPRRevisionStore
            'Dim dd = colElement.DeepDelete(Session)
        	'dd.Execute(Session)
        Next	
    End If
    
    For i = 1 To ubound(TargetADServers)
    	'Try to authenticate against AD Server
    	Try
    		Using context As New PrincipalContext(ContextType.Domain, TargetADServers(i))
    			valid = context.ValidateCredentials(ServiceName, ServicePassword)
    		End Using
    		If valid Then
    			'Return name of AD Server successfully authenticated against
    			Return TargetADServers(i)
    			Exit For
    		End If		
    	Catch ex As Exception
    		AppData.Instance.RaiseMessage(MsgSeverity.Warning, "Could not authenticate to Non-PRIMARY ADServer " & TargetADServers(i) & " " & ex.ToString())
    	End Try
    Next
    	
    'Otherwise no DC could be contacted, defaulting to first entry in CP_ADServerList
    AppData.Instance.RaiseMessage(MsgSeverity.Warning, "Defaulting to PRIMARY ADServer " & TargetADServers(0))
    Return TargetADServers(0)

    any ideas?

  • I assume this script is the code inside of a scripted variable. Inside this script, you do not have a normal Object Layer connection (or session).

    A rough idea (haven't thought about all details yet) would be:

    1. For a full-sync, you could add a custom process to start the synchronization for your AD sync. In that process, you execute (after some rewrite) your detection script as normal DialogScript in an additional process step before the synchronization process step. That script needs to return a string in the OutParameter then that can be used in the OverrideVariables parameter of the synchronization process step. Or - assuming that the script running in the process step and the variable set would identify the same DC as a new PRIMARY, you could just run the scripted variable without the RevisionStore part, and the script in the process step is mainly for the deletion of the revision store entries in case of a change of PRIMARY happened.
    2. For ad-hoc projections (where close timing might be important) you do not need to remove the revision store entries. But as you should work with a scripted variable here, to avoid too many process changes, you need to figure out a way to make this script work together with the solution from 1.
Reply
  • I assume this script is the code inside of a scripted variable. Inside this script, you do not have a normal Object Layer connection (or session).

    A rough idea (haven't thought about all details yet) would be:

    1. For a full-sync, you could add a custom process to start the synchronization for your AD sync. In that process, you execute (after some rewrite) your detection script as normal DialogScript in an additional process step before the synchronization process step. That script needs to return a string in the OutParameter then that can be used in the OverrideVariables parameter of the synchronization process step. Or - assuming that the script running in the process step and the variable set would identify the same DC as a new PRIMARY, you could just run the scripted variable without the RevisionStore part, and the script in the process step is mainly for the deletion of the revision store entries in case of a change of PRIMARY happened.
    2. For ad-hoc projections (where close timing might be important) you do not need to remove the revision store entries. But as you should work with a scripted variable here, to avoid too many process changes, you need to figure out a way to make this script work together with the solution from 1.
Children