123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652 |
- using Dfs.WayneChina.SpsDataCourier.SpsData;
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Linq;
- using Microsoft.EntityFrameworkCore;
- using System.Threading.Tasks;
- using System.Timers;
- using Microsoft.Extensions.Logging;
- using System.Collections.Concurrent;
- namespace Dfs.WayneChina.SpsDataCourier
- {
- public class DbMonitor
- {
- #region Fields
- private Timer timer;
- private int interval;
- private bool smartFuel05Compatible;
- private Queue<long> sendQueue = new Queue<long>();
- private object syncObj = new object();
- private ConcurrentQueue<long> processedTransQueue = new ConcurrentQueue<long>();
- private string connectionString;
- #endregion
- #region Events
- public event EventHandler<CardTrxEventArgs> OnCardTrxCreated;
- public event EventHandler<EntryFoundEventArgs> OnAccountCreated;
- public event EventHandler<EntryFoundEventArgs> OnAccountUpdated;
- public event EventHandler<EntryFoundEventArgs> OnCardInfoCreated;
- public event EventHandler<EntryFoundEventArgs> OnCardInfoUpdated;
- public event EventHandler<CardChangedEventArgs> OnCardInfoDeleted;
-
- public event EventHandler<EntryFoundEventArgs> OnRechargeCreated;
-
- public event EventHandler<EntryFoundEventArgs> OnLostCardCreated;
-
-
- public event EventHandler<EntryFoundEventArgs> OnClosedCardCreated;
-
- public event EventHandler<EntryFoundEventArgs> OnBaseBlackCardCreated;
- public event EventHandler<CardChangedEventArgs> OnBaseBlackCardDeleted;
-
- public event EventHandler<EntryFoundEventArgs> OnBlacklistedCardCreated;
- public event EventHandler<EntryFoundEventArgs> OnBlacklistedCardUpdated;
- public event EventHandler<CardChangedEventArgs> OnBlacklistedCardDeleted;
-
- public event EventHandler<EntryFoundEventArgs> OnReleasedCardCreated;
-
- public event EventHandler<CardChangedEventArgs> OnReleasedCardDeleted;
- public event EventHandler<EntryFoundEventArgs> OnGrayInfoCreated;
- public event EventHandler<EntryFoundEventArgs> OnGrayInfoDeleted;
- public event EventHandler<MultipleAccountRecordsEventArgs> OnMultipleAccountsCreated;
- public event EventHandler<MultipleAccountRecordsEventArgs> OnMultipleAccountsUpdated;
- public event EventHandler<MultipleCardRecordsEventArgs> OnMultipleCardsCreated;
- public event EventHandler<MultipleCardRecordsEventArgs> OnMultipleCardsUpdated;
- #endregion
- #region Logger
- NLog.Logger logger = NLog.LogManager.LoadConfiguration("NLog.config").GetLogger("SpsDataCourier");
- #endregion
- #region Constructor
- public DbMonitor(int scanInterval, string connectionString, bool sf05Compatible)
- {
- interval = scanInterval;
- this.connectionString = connectionString;
- smartFuel05Compatible = sf05Compatible;
- timer = new Timer();
- timer.Interval = interval * 1000;
- timer.Elapsed += Timer_Elapsed;
- }
- #endregion
- public void Start()
- {
- logger.Info("Starting database monitor");
- timer.Start();
- }
- public void Stop()
- {
- logger.Info("Stopping database monitor");
- timer.Stop();
- }
- private async void Timer_Elapsed(object sender, ElapsedEventArgs e)
- {
- logger.Debug("Start to scan database");
- await CheckDbAsync();
- }
- public bool AddToQueue(long gid)
- {
- lock (syncObj)
- {
- foreach (var item in sendQueue)
- {
- logger.Info($"Item in the send queue: {item}");
- }
- if (sendQueue.Contains(gid))
- {
- logger.Info($"Trying to enqueue gid {gid}, but it's being processed already");
- return false;
- }
- sendQueue.Enqueue(gid);
- logger.Info($"After check, Gid: {gid} added to queue");
- return true;
- }
- }
- public void ClearFromQueue(TTableaudit tableaudit)
- {
- if(tableaudit.TransCreated != null && tableaudit.TransCreated.Value != 0)
- {
- lock (syncObj)
- {
- logger.Info($"Removing {tableaudit.TransCreated.Value} from send queue");
- sendQueue = new Queue<long>(sendQueue.Where(i => i != tableaudit.TransCreated.Value));
- }
- }
- }
- public void ClearFromQueue(long gid)
- {
- lock (syncObj)
- {
- logger.Info($"Removing {gid} from send queue");
- sendQueue = new Queue<long>(sendQueue.Where(i => i != gid));
- }
- }
- public void AddToProcessedQueue(long gid)
- {
- logger.Info($"Adding {gid} to ProcessedQueue");
- if (processedTransQueue.Count > 10)
- {
- long toBeRemoved = 0;
- processedTransQueue.TryDequeue(out toBeRemoved);
- logger.Info($"To be removed from ProcessedQueue: {toBeRemoved}");
- }
- processedTransQueue.Enqueue(gid);
- }
- public bool IsTransAlreadyUploaded(long gid)
- {
- return processedTransQueue.Contains(gid);
- }
- private async Task CheckDbAsync()
- {
- timer.Stop();
-
- try
- {
- using (var context = new SpsDbContext(connectionString))
- {
- var allRecords = await context.TTableaudit.ToListAsync();
-
- var deletedCards = allRecords.Where(t => t.CardInfoDeleted != "0");
- if (deletedCards.Count() > 0)
- logger.Info($"Deleted cards count: {deletedCards.Count()}");
-
- try
- {
- context.TTableaudit.RemoveRange(allRecords.Where(t => t.CardInfoDeleted != "0"));
- await context.SaveChangesAsync();
- }
- catch (Exception ex)
- {
- logger.Error($"Exception in removing the DELETED CARD records, {ex.ToString()}");
- }
-
-
-
- var createdAccounts = allRecords.Where(t => t.AccountCreated != 0);
- if (createdAccounts.Count() > 0)
- logger.Info($"Multiple created accounts, count: {createdAccounts.Count()}");
- if (createdAccounts.Count() > 5)
- {
- List<TAcctinfo> createdAccountInfo = new List<TAcctinfo>();
- foreach (var r in createdAccounts)
- {
- var expectedAccountInfo = context.TAcctinfo
- .AsNoTracking()
- .FirstOrDefault(a => a.Gid == Convert.ToUInt64(r.AccountCreated.Value));
- if (expectedAccountInfo != null)
- createdAccountInfo.Add(expectedAccountInfo);
- }
- if (createdAccountInfo.Count > 0)
- {
- ProcessMultipleCreatedAccounts(createdAccountInfo, createdAccounts);
- }
- }
-
-
- var updatedAccounts = allRecords.Where(t => t.AccountUpdated != 0);
- if (updatedAccounts.Count() > 0)
- logger.Info($"Multiple updated accounts, count: {updatedAccounts.Count()}");
- if (updatedAccounts.Count() > 5)
- {
- List<TAcctinfo> updatedAccountInfo = new List<TAcctinfo>();
- foreach (var r in updatedAccounts)
- {
- var expectedAccountInfo = context.TAcctinfo
- .AsNoTracking()
- .FirstOrDefault(a => a.Gid == Convert.ToUInt64(r.AccountUpdated.Value));
- if (expectedAccountInfo != null)
- updatedAccountInfo.Add(expectedAccountInfo);
- }
- if (updatedAccountInfo.Count > 0)
- {
- ProcessMultipleUpdatedAccounts(updatedAccountInfo, updatedAccounts);
- }
- }
-
-
- var createdCards = allRecords.Where(t => t.CardInfoCreated != 0);
- if (createdCards.Count() > 0)
- logger.Info($"Multiple created cards count: {createdCards.Count()}");
- if (createdCards.Count() > 5)
- {
- List<TCardinfo> createdCardInfo = new List<TCardinfo>();
- foreach (var r in createdCards)
- {
- var expectedCardInfo = context.TCardinfo
- .AsNoTracking()
- .FirstOrDefault(c => c.Gid == Convert.ToUInt64(r.CardInfoCreated.Value));
- if (expectedCardInfo != null)
- createdCardInfo.Add(expectedCardInfo);
- }
- if (createdCardInfo.Count > 0)
- {
- logger.Info($"Found multiple created card info records, count: {createdCardInfo.Count}");
- ProcessMultipleCreatedCards(createdCardInfo, createdCards);
- }
- }
-
-
- var updatedCards = allRecords
- .Where(t => t.CardInfoUpdated != 0)
- .Distinct(new GenericComparer<TTableaudit, long>(a => a.CardInfoUpdated.Value));
- if (updatedCards.Count() > 0)
- {
- logger.Info($"Multiple updated cards, count: {updatedCards.Count()}");
- }
- if (updatedCards.Count() > 5)
- {
- List<TCardinfo> updatedCardInfo = new List<TCardinfo>();
- foreach (var r in updatedCards)
- {
- var expectedCardInfo = context.TCardinfo
- .AsNoTracking()
- .FirstOrDefault(c => c.Gid == Convert.ToUInt64(r.CardInfoUpdated.Value));
- if (expectedCardInfo != null)
- updatedCardInfo.Add(expectedCardInfo);
- }
- if (updatedCardInfo.Count > 0)
- {
- ProcessMultipleUpdatedCards(updatedCardInfo, updatedCards);
- }
- }
-
-
-
- allRecords = await context.TTableaudit.ToListAsync();
- var deletedCardsCount1 = allRecords.Where(t => t.CardInfoDeleted != "0").Count();
- if (deletedCardsCount1 > 0)
- logger.Info($"After refresh, delete cards count: {deletedCardsCount1}");
- var recordCount = allRecords.Count;
- if (recordCount > 0)
- {
- var record = await context.TTableaudit.FirstAsync();
- if (record.RechargeCreated.HasValue && record.RechargeCreated.Value != 0)
- {
- logger.Info($"New recharge or reduction record, Gid: {record.RechargeCreated.Value}");
- ProcessRecharge(record);
- }
- else if (record.CardInfoCreated.HasValue && record.CardInfoCreated.Value != 0)
- {
- logger.Info($"New CardInfo record, Gid: {record.CardInfoCreated.Value}");
- ProcessCardInfoCreated(record);
- }
- else if (record.CardInfoUpdated.HasValue && record.CardInfoUpdated.Value != 0)
- {
- logger.Info($"CardInfo updated, Gid: {record.CardInfoUpdated.Value}");
- ProcessCardInfoUpdated(record);
- }
- else if (record.CardInfoDeleted != "0")
- {
- logger.Info($"CardInfo deleted, CardNo: {record.CardInfoDeleted}");
- ProcessCardInfoDeleted(record);
- }
- else if (record.AccountCreated.HasValue && record.AccountCreated.Value != 0)
- {
- logger.Info($"New account created, Gid: {record.AccountCreated.Value}");
- ProcessAccountCreated(record);
- }
- else if (record.AccountUpdated.HasValue && record.AccountUpdated.Value != 0)
- {
- logger.Info($"Account updated on GID: {record.AccountUpdated.Value}");
- ProcessAccountUpdated(record);
- }
- else if (record.ClosedCardCreated.HasValue && record.ClosedCardCreated.Value != 0)
- {
- logger.Info($"Card closed/deactivated, Gid: {record.ClosedCardCreated.Value}");
- ProcessClosedCard(record);
- }
- else if (record.LostCardCreated.HasValue && record.LostCardCreated.Value != 0)
- {
- logger.Info($"Card lost or found registerred, Gid: {record.LostCardCreated.Value}");
- ProcessLostCardCreated(record);
- }
- else if (record.BlacklistedCardCreated.HasValue && record.BlacklistedCardCreated.Value != 0)
- {
- logger.Info($"A blacklisted card is registerred, Gid: {record.BlacklistedCardCreated.Value}");
- ProcessBlacklistedCardCreated(record);
- }
- else if (record.BlacklistedCardUpdated.HasValue && record.BlacklistedCardUpdated.Value != 0)
- {
- logger.Info($"A card which was registered as LOST CARD is released, Gid: {record.BlacklistedCardUpdated.Value}");
- ProcessBlacklistedCardUpdated(record);
- }
- else if (record.BlacklistedCardDeleted != "0")
- {
- logger.Info($"A blacklisted card was deleted, CardNo: {record.BlacklistedCardDeleted}");
- ProcessBlacklistedCardDeleted(record);
- }
- else if (record.ReleasedCardCreated.HasValue && record.ReleasedCardCreated.Value != 0)
- {
- logger.Info($"A lost card was found and released, Gid: {record.ReleasedCardCreated.Value}");
- ProcessReleasedCardCreated(record);
- }
- else if (record.ReleasedCardDeleted != "0")
- {
- logger.Info($"A released card is deleted, card no: {record.ReleasedCardDeleted}");
- ProcessReleasedCardDeleted(record);
- }
- else if (record.BaseBlackCardCreated.HasValue && record.BaseBlackCardCreated.Value != 0)
- {
- logger.Info($"A base black card is created, gid: {record.BaseBlackCardCreated.Value}");
- ProcessBaseBlackCardCreated(record);
- }
- else if (record.BaseBlackCardDeleted != "0")
- {
- logger.Info($"A base black card is deleted, card no: {record.BaseBlackCardDeleted}");
- ProcessBaseBlackCardDeleted(record);
- }
- else if (record.TransCreated.HasValue && record.TransCreated.Value != 0)
- {
- logger.Info($"Db monitor, found a newly created card transaction, Gid: {record.TransCreated.Value}");
- lock (syncObj)
- {
- var gid = record.TransCreated.Value;
- if (sendQueue.Contains(gid))
- {
- if ((DateTime.Now - record.OperationTime).TotalSeconds < 30)
- {
- logger.Info($"Gid: {gid} being processed now");
- timer.Start();
- return;
- }
- else
- {
- logger.Info($"Trans of GID: {gid} was created more than 30 seconds ago!");
- }
- }
- else
- {
- sendQueue.Enqueue(gid);
- logger.Info($"Enqueued: {gid}");
- }
- }
- ProcessCardTransaction(record);
- lock (syncObj)
- {
- if (sendQueue.Count >= 5)
- {
- var dequeuedGid = sendQueue.Dequeue();
- logger.Info($"Dequeued: {dequeuedGid}");
- }
- }
- }
- else if (record.GrayInfoCreated.HasValue && record.GrayInfoCreated.Value != 0)
- {
- logger.Info($"A new Gray info created, gid: {record.GrayInfoCreated.Value}");
- ProcessGrayInfoCreated(record);
- }
- else if (record.GrayInfoDeleted != "0")
- {
- logger.Info($"A existing Gray info deleted, Card No: {record.GrayInfoDeleted}");
- ProcessGrayInfoDeleted(record);
- }
- }
- else
- {
- logger.Debug("No record found");
- }
- }
- }
- catch (Exception ex)
- {
- logger.Error(ex);
- }
- timer.Start();
- }
- #region Multiple records handling
- private void ProcessMultipleCreatedAccounts(IEnumerable<TAcctinfo> createdAccountRecords, IEnumerable<TTableaudit> createdAccoutsAudit)
- {
- OnMultipleAccountsCreated?.Invoke(this, new MultipleAccountRecordsEventArgs(createdAccountRecords, createdAccoutsAudit));
- }
- private void ProcessMultipleUpdatedAccounts(IEnumerable<TAcctinfo> updatedAccountRecords, IEnumerable<TTableaudit> updatedAccountsAudit)
- {
- OnMultipleAccountsUpdated?.Invoke(this, new MultipleAccountRecordsEventArgs(updatedAccountRecords, updatedAccountsAudit));
- }
- private void ProcessMultipleCreatedCards(IEnumerable<TCardinfo> cardInfoRecords, IEnumerable<TTableaudit> createdCardsAudit)
- {
- OnMultipleCardsCreated?.Invoke(this, new MultipleCardRecordsEventArgs(cardInfoRecords, createdCardsAudit));
- }
- private void ProcessMultipleUpdatedCards(IEnumerable<TCardinfo> cardInfoRecords, IEnumerable<TTableaudit> updatedCardsAudit)
- {
- OnMultipleCardsUpdated?.Invoke(this, new MultipleCardRecordsEventArgs(cardInfoRecords, updatedCardsAudit));
- }
- #endregion
- #region Single record handling
-
- private void ProcessCardTransaction(TTableaudit tableAudit)
- {
- OnCardTrxCreated?.Invoke(this, new CardTrxEventArgs(null, tableAudit));
- }
-
- private void ProcessAccountCreated(TTableaudit tableAudit)
- {
- OnAccountCreated?.Invoke(this, new EntryFoundEventArgs(tableAudit, tableAudit.OperationTime));
- }
- private void ProcessAccountUpdated(TTableaudit tableAudit)
- {
- OnAccountUpdated?.Invoke(this, new EntryFoundEventArgs(tableAudit, tableAudit.OperationTime));
- }
-
- private void ProcessCardInfoCreated(TTableaudit tableAudit)
- {
- OnCardInfoCreated?.Invoke(this, new EntryFoundEventArgs(tableAudit, tableAudit.OperationTime));
- }
- private void ProcessCardInfoUpdated(TTableaudit tableAudit)
- {
- OnCardInfoUpdated?.Invoke(this, new EntryFoundEventArgs(tableAudit, tableAudit.OperationTime));
- }
- private void ProcessCardInfoDeleted(TTableaudit tableAudit)
- {
- OnCardInfoDeleted?.Invoke(this, new CardChangedEventArgs(tableAudit.CardInfoDeleted, tableAudit));
- }
-
- private void ProcessRecharge(TTableaudit tableAudit)
- {
- OnRechargeCreated?.Invoke(this, new EntryFoundEventArgs(tableAudit, tableAudit.OperationTime));
- }
-
- private void ProcessClosedCard(TTableaudit tableAudit)
- {
- OnClosedCardCreated?.Invoke(this, new EntryFoundEventArgs(tableAudit, tableAudit.OperationTime));
- }
-
- private void ProcessLostCardCreated(TTableaudit tableAudit)
- {
- OnLostCardCreated?.Invoke(this, new EntryFoundEventArgs(tableAudit, tableAudit.OperationTime));
- }
-
-
- private void ProcessBaseBlackCardCreated(TTableaudit tableAudit)
- {
- OnBaseBlackCardCreated?.Invoke(this, new EntryFoundEventArgs(tableAudit, tableAudit.OperationTime));
- }
- private void ProcessBaseBlackCardDeleted(TTableaudit tableAudit)
- {
- OnBaseBlackCardDeleted?.Invoke(this, new CardChangedEventArgs(tableAudit.BaseBlackCardDeleted, tableAudit));
- }
-
- private void ProcessBlacklistedCardCreated(TTableaudit tableAudit)
- {
- OnBlacklistedCardCreated?.Invoke(this, new EntryFoundEventArgs(tableAudit, tableAudit.OperationTime));
- }
- private void ProcessBlacklistedCardUpdated(TTableaudit tableAudit)
- {
- OnBlacklistedCardUpdated?.Invoke(this, new EntryFoundEventArgs(tableAudit, tableAudit.OperationTime));
- }
- private void ProcessBlacklistedCardDeleted(TTableaudit tableAudit)
- {
- OnBlacklistedCardDeleted?.Invoke(this, new CardChangedEventArgs(tableAudit.BlacklistedCardDeleted, tableAudit));
- }
-
- private void ProcessReleasedCardCreated(TTableaudit tableAudit)
- {
- OnReleasedCardCreated?.Invoke(this, new EntryFoundEventArgs(tableAudit, tableAudit.OperationTime));
- }
- private void ProcessReleasedCardDeleted(TTableaudit tableAudit)
- {
- OnReleasedCardDeleted?.Invoke(this, new CardChangedEventArgs(tableAudit.ReleasedCardDeleted, tableAudit));
- }
-
- private void ProcessGrayInfoCreated(TTableaudit tableAudit)
- {
- OnGrayInfoCreated?.Invoke(this, new EntryFoundEventArgs(tableAudit, tableAudit.OperationTime));
- }
- private void ProcessGrayInfoDeleted(TTableaudit tableAudit)
- {
- OnGrayInfoDeleted?.Invoke(this, new EntryFoundEventArgs(tableAudit, tableAudit.OperationTime));
- }
- #endregion
- #region Data versions
- private async Task CheckDataVersionsAsync()
- {
- using (var context = new SpsDbContext(connectionString))
- {
- var versionData = await context.TVersioninfo.ToListAsync();
- foreach (var versionInfo in versionData)
- {
- logger.Debug($"{versionInfo.Gid}, {versionInfo.VerNo}, {versionInfo.EffTime}, {versionInfo.LoseEffTime}");
- }
- }
- }
- #endregion
- }
- }
|