public Response <ServiceBatchModel> AddBatch(ServiceBatchModel batch) { var repository = _unitOfWork.GetRepository <ServiceBatchModel>(SchemaName.Synch); SqlParameter batchStatusIDParam = new SqlParameter("BatchStatusID", batch.BatchStatusID); SqlParameter batchTypeIDParam = new SqlParameter("BatchTypeID", batch.BatchTypeID); SqlParameter batchConfigIDParam = new SqlParameter("ConfigID", batch.ConfigID); SqlParameter batchUSNParam = new SqlParameter("usn", batch.USN); SqlParameter batchIsActiveParam = new SqlParameter("IsActive", batch.IsActive); SqlParameter modifiedOnParam = new SqlParameter("ModifiedOn", batch.ModifiedOn ?? DateTime.Now); List <SqlParameter> procParams = new List <SqlParameter>() { batchStatusIDParam, batchTypeIDParam, batchConfigIDParam, batchUSNParam, batchIsActiveParam, modifiedOnParam }; return(repository.ExecuteNQStoredProc("usp_AddBatch", procParams, idResult: true)); }
//public static void Sync(Object source, ElapsedEventArgs e) public static void Sync(int configID) { _debugMode = ConfigurationManager.AppSettings["Debug"] != null && Convert.ToBoolean(ConfigurationManager.AppSettings["Debug"]); _debugLogFileMode = ConfigurationManager.AppSettings["DebugLogFile"] != null && Convert.ToBoolean(ConfigurationManager.AppSettings["DebugLogFile"]); // first lets get our current config, in case something has been updated var syncServ = new SynchronizationServiceDataProvider(_logger); var config = syncServ.GetServiceConfiguration(configID).DataItems[0]; // we only want to run this service is we have an active config for it // todo: the plan is at some point to have a network monitoring tool to set which configs are active, so services on multiple servers know if they should be running or not // NOTE: by having the services continue to check their configs, the configs can be changed if (_debugMode) { EventLog.WriteEntry("SynchronizationService", "Using the following ConfigXML: " + config.ConfigXML, EventLogEntryType.Information); } if (_debugLogFileMode) { using (StreamWriter sw = File.AppendText("Log.txt")) { sw.WriteLine("Using the following ConfigXML: " + config.ConfigXML); } } if (config != null && config.IsActive != null && (bool)config.IsActive) { /* * config.ConfigXML reads from the DB the configuration database containing * SyncServer * - ProcessingServer * Timer * - Interval * LDAPServer * - LDAPPath * - LDAPUserFilter * - LDAPRoleFilter * - Name * - Port: Defaultvalue="389" */ using (XmlReader reader = XmlReader.Create(new StringReader(config.ConfigXML))) { // create a directory identifier and connection, reader.ReadToFollowing("SyncServer"); reader.ReadToDescendant("ProcessingServer"); reader.MoveToFirstAttribute(); var processingServer = reader.Value; reader.ReadToFollowing("LDAPServer"); reader.ReadToDescendant("LDAPPath"); reader.MoveToFirstAttribute(); var ldapPath = reader.Value; reader.ReadToFollowing("LDAPUserFilter"); reader.MoveToFirstAttribute(); var ldapUserFilterFromConfig = reader.Value; reader.ReadToFollowing("LDAPRoleFilter"); reader.MoveToFirstAttribute(); var ldapRoleFilterFromConfig = reader.Value; if (_debugMode) { EventLog.WriteEntry("SynchronizationService", "Sync Server host name should be " + System.Net.Dns.GetHostName() + ", ldap sync server configured is " + processingServer + ", ldap path configured is " + ldapPath + ", ldap user filter configured is " + ldapUserFilterFromConfig + ", ldap role filter from config is " + ldapRoleFilterFromConfig, EventLogEntryType.Information); } if (_debugLogFileMode) { using (StreamWriter sw = File.AppendText("Log.txt")) { sw.WriteLine("Sync Server host name should be " + System.Net.Dns.GetHostName() + ", ldap sync server configured is " + processingServer + ", ldap path configured is " + ldapPath + ", ldap user filter configured is " + ldapUserFilterFromConfig + ", ldap role filter from config is " + ldapRoleFilterFromConfig); } } //Till here make sure that you have the right configuration on the right machine // we need to look at the previous batch to know which updates to start requesting, as well as to make sure its completed before starting a new batch var lastBatch = syncServ.GetLastBatch(config.ConfigID); // the batches are by config, not config type, as you can have more than 1 config for a given type if ( processingServer == System.Net.Dns.GetHostName() && // we want to make sure we have the ldap info we need to pull what we need from AD ( ldapPath != string.Empty && ldapUserFilterFromConfig != string.Empty && ldapRoleFilterFromConfig != string.Empty ) && // only proceed w/ a new AD request, once the last request has been completed ( lastBatch.DataItems.Count < 1 || (lastBatch.DataItems[0] != null && lastBatch.DataItems[0].BatchStatusID >= (int)BatchStatus.Completed) ) ) { var usnChanged = (lastBatch.DataItems.Count > 0) ? lastBatch.DataItems[0].USN : 0; var ldapUserFilter = ldapUserFilterFromConfig.Replace(_usnChangedToken, usnChanged.ToString()); if (_debugMode) { EventLog.WriteEntry("SynchronizationService", "Searching AD for users using ldap filter string: " + ldapUserFilter, EventLogEntryType.Information); } if (_debugLogFileMode) { using (StreamWriter sw = File.AppendText("Log.txt")) { sw.WriteLine("Searching AD for users using ldap filter string: " + ldapUserFilter); } } var resultsUsers = SearchAD(ldapPath, ldapUserFilter); var ldapRolesFilter = ldapRoleFilterFromConfig.Replace(_usnChangedToken, usnChanged.ToString()); if (_debugMode) { EventLog.WriteEntry("SynchronizationService", "Searching AD for roles using ldap filter string: " + ldapRolesFilter, EventLogEntryType.Information); } if (_debugLogFileMode) { using (StreamWriter sw = File.AppendText("Log.txt")) { sw.WriteLine("Searching AD for roles using ldap filter string: " + ldapRolesFilter); } } var resultsRoles = SearchAD(ldapPath, ldapRolesFilter); // we only want to create a new batch, if there are actually results to be processed if ((resultsUsers != null && resultsRoles != null) && (resultsUsers.Count > 0 || resultsRoles.Count > 0)) { // add this new request to the db var batch = new ServiceBatchModel { BatchStatusID = (int)BatchStatus.Requesting, BatchTypeID = (int)BatchType.ADSynService, ConfigID = config.ConfigID, USN = _lastUSN + 1, IsActive = true }; batch.BatchID = syncServ.AddBatch(batch).ID; if (_debugMode) { EventLog.WriteEntry("SynchronizationService", "Batch created, ID: " + batch.BatchID, EventLogEntryType.Information); } if (_debugLogFileMode) { using (StreamWriter sw = File.AppendText("Log.txt")) { sw.WriteLine("Batch created, ID: " + batch.BatchID); } } var dtUsers = BuildUsersDataTable(resultsUsers, batch.BatchID, ldapPath); if (_debugMode) { EventLog.WriteEntry("SynchronizationService", "Inserting users into UserStage table.", EventLogEntryType.Information); } if (_debugLogFileMode) { using (StreamWriter sw = File.AppendText("Log.txt")) { sw.WriteLine("Inserting users into UserStage table."); } } syncServ.BulkInsert(dtUsers, UserStageTable, _debugMode, _debugLogFileMode); var dtRoles = BuildRolesDataTable(resultsRoles, batch.BatchID); if (_debugMode) { EventLog.WriteEntry("SynchronizationService", "Inserting roles into RoleStage table.", EventLogEntryType.Information); } if (_debugLogFileMode) { using (StreamWriter sw = File.AppendText("Log.txt")) { sw.WriteLine("Inserting roles into RoleStage table."); } } syncServ.BulkInsert(dtRoles, RoleStageTable, _debugMode, _debugLogFileMode); // also, lets populate which groups the users belong to var dtUserRoles = BuildUserRolesDataTable(resultsRoles, batch.BatchID, ldapPath); if (_debugMode) { EventLog.WriteEntry("SynchronizationService", "Inserting user's roles into RoleStage table.", EventLogEntryType.Information); } if (_debugLogFileMode) { using (StreamWriter sw = File.AppendText("Log.txt")) { sw.WriteLine("Inserting user's roles into RoleStage table."); } } syncServ.BulkInsert(dtUserRoles, UserRoleStageTable, _debugMode, _debugLogFileMode); // if we've added any staging data to be processed, update the batch created for this interval for keeping up w/ the data to be processed // NOTE: adding +1 to the last usn, as we are doing a >= to filter by usn, so we don't want to get the last usn again, the next time we look for updates batch.BatchStatusID = (int)BatchStatus.Completed; batch.BatchTypeID = (int)BatchType.ADSynService; batch.USN = _lastUSN + 1; if (_debugMode) { EventLog.WriteEntry("SynchronizationService", "Updating batch to Pending status with USN " + batch.USN + ".", EventLogEntryType.Information); } if (_debugLogFileMode) { using (StreamWriter sw = File.AppendText("Log.txt")) { sw.WriteLine("Updating batch to Pending status with USN " + batch.USN + "."); } } syncServ.UpdateBatch(batch); } } } } }