private static async Task ProcessReplication(int RegionId) { //Get the itesm from the Cosmos table which are not from this region (Replicating other region updates) List <CommonProcessQueue> replicationMetaDatas = await ManageSqlReplicationCMDB.GetAvailableItems(RegionId); foreach (CommonProcessQueue replication in replicationMetaDatas) { // Need to check the Failed queue //Stale Check in the Current Processing Queue bool isRecordExists = await ManageSqlReplicationCMDB.GetAvailableItemsBySqlGuid(replication, RegionId); bool isRecordExistsInfailed = await ManageSqlReplication.GetFailedItemsBySqlGuid(replication); if (!isRecordExists && !isRecordExistsInfailed) { SqlCommand sqlCmd; SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(); DataSet secondaryDataSet = new DataSet(); FailedReplication failedReplication = null; try { //ReplicationMetaData replication = JsonConvert.DeserializeObject<ReplicationMetaData>(data); ReplicationRegion primaryRegion = GetPrimaryRegion(replication.ReplicationConfigKey); List <ReplicationRegion> secondaryRegions = GetSecondaryActiveRegions(replication.ReplicationConfigKey); //Passing source regionID DataTable updatedTable = GetPrimaryRegionDataForReplication(replication, primaryRegion); var guids = updatedTable.AsEnumerable() // .Where(r => r.Field<Guid>("Guid").Equals(new Guid(replication.Guid))) .Select(r => r.Field <Guid>("Guid")) .ToArray(); if (guids.Length > 0) { foreach (ReplicationRegion secondaryRegion in secondaryRegions) { using (SqlConnection sqlCon = new SqlConnection(secondaryRegion.ConnectionString)) { foreach (var primaryGuid in guids) { string filter = "Guid = '" + primaryGuid.ToString() + "'"; DataRow[] updatedRow = updatedTable.Select(filter); sqlCmd = new SqlCommand("select * from " + replication.TableName + " where " + filter, sqlCon); sqlDataAdapter.SelectCommand = sqlCmd; SqlCommandBuilder cb = new SqlCommandBuilder(sqlDataAdapter); sqlDataAdapter.InsertCommand = cb.GetInsertCommand(); sqlDataAdapter.UpdateCommand = cb.GetUpdateCommand(); sqlDataAdapter.DeleteCommand = cb.GetDeleteCommand(); sqlDataAdapter.Fill(secondaryDataSet, replication.TableName); int primaryRecord = updatedRow.Length; int secondaryRecord = secondaryDataSet.Tables[replication.TableName].Select(filter).Length; string operation = ""; if (secondaryRecord > 0 && primaryRecord == 1) // UPDATE (or) SOFT DELETE { foreach (DataRow dr in updatedRow) { dr["isreplicated"] = true; secondaryDataSet.Tables[replication.TableName].Select(filter).SingleOrDefault().ItemArray = dr.ItemArray; } operation = "U"; } if (secondaryRecord == 0 && primaryRecord == 1) // INSERT { foreach (DataRow dr in updatedRow) { dr["isreplicated"] = true; secondaryDataSet.Tables[replication.TableName].Rows.Add(dr.ItemArray); } operation = "I"; } //if (secondaryRecord == 1 && primaryRecord == 0) // HARD DELETE //{ // // secondaryDataSet.Tables[replication.TableName].Rows[0].Delete(); //} try { failedReplication = new FailedReplication() { Action = operation, FromRegionId = primaryRegion.RegionId, ToRegionId = secondaryRegion.RegionId, TableName = replication.TableName, RegionConfigKey = replication.ReplicationConfigKey, Guid = primaryGuid.ToString() }; ArchivedReplication archivedReplication = new ArchivedReplication() { Action = operation, FromRegionId = primaryRegion.RegionId, ToRegionId = secondaryRegion.RegionId, TableName = replication.TableName, RegionConfigKey = replication.ReplicationConfigKey, Guid = primaryGuid.ToString() }; sqlDataAdapter.AcceptChangesDuringUpdate = true; int recordsAffected = sqlDataAdapter.Update(secondaryDataSet, replication.TableName); if (recordsAffected > 0) { UpdatePrimaryRegion(replication.ReplicationConfigKey, primaryGuid.ToString(), replication.TableName); await LogSqlReplication.LogArchive(archivedReplication); await ManageSqlReplicationCMDB.RemoveProcessQueueItem(replication); } //else //{ // failedReplication.ErrorMessage = "No matched record found (or) No records to update in destination from sources"; // await LogSqlReplication.LogFailed(failedReplication); // NOT REPLICATED & KEEP IN PROCESS ENABLE in PROCESS QUEUE //} } catch (Exception exp) { failedReplication.ErrorMessage = exp.StackTrace.ToString(); await LogSqlReplication.LogFailed(failedReplication); await ManageSqlReplicationCMDB.RemoveProcessQueueItem(replication); // ERROR ON REPLICATION } } } } } else { await ManageSqlReplicationCMDB.RemoveProcessQueueItem(replication); } } catch (Exception exp) { failedReplication.ErrorMessage = exp.StackTrace.ToString(); await LogSqlReplication.LogFailed(failedReplication); await ManageSqlReplicationCMDB.RemoveProcessQueueItem(replication); // ERROR ON REPLICATION } finally { sqlDataAdapter.Dispose(); secondaryDataSet.Dispose(); } } else { ConflictReplication conflictReplication = new ConflictReplication() { Guid = replication.Guid, ReplicationSourceRegionId = replication.ReplicationSourceRegionId, TransactionDateTime = replication.TransactionDateTime, TableName = replication.TableName, PartitionKey = replication.PartitionKey + "_CONFLICT", RowKey = replication.RowKey, Timestamp = replication.Timestamp }; await LogSqlReplication.LogConflict(conflictReplication); await ManageSqlReplicationCMDB.RemoveProcessQueueItem(replication); // Conflict Record } } }
//[FunctionName("processFailedTriggers")] // public static async Task ProcessFailedReplicationItems([TimerTrigger("0 */1 * * * *")]TimerInfo timerInfo) // { // try // { // //await ProcessFailedReplication(); // } // catch (Exception exp) // { // //Log to errorlog // throw exp; // } // } private static async Task ProcessFailedReplication() { List <FailedReplication> failedItems = await ManageSqlReplication.GetFailedItems(); }