using Core; using LiMan.DbSync.Controllers; using LiMan.DbSync.DbModels; using Microsoft.Extensions.Configuration; using Newtonsoft.Json; using StackExchange.Redis; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Runtime; using System.Text; using System.Threading.Tasks; namespace LiMan.DbSync.Services { public class DbSyncService : BaseServ { #region Public Constructors public DbSyncService(IConfiguration configuration, IConnectionMultiplexer redisConnMult) { Log.Info("DbSyncService starting..."); _configuration = configuration; // Conf cache redisConn = redisConnMult; redisDb = this.redisConn.GetDatabase(); // json serializer... FIX errore loop circolare https://www.ryadel.com/en/jsonserializationexception-self-referencing-loop-detected-error-fix-entity-framework-asp-net-core/ JSSettings = new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }; // cod app CodApp = _configuration["CodApp"]; dbController = new DbSyncController(); TplController = new DB.Controllers.DbController(configuration); // chiudo log Log.Info("DbSyncService started!"); } #endregion Public Constructors #region Public Methods /// /// Elenco record AnagKeyVal /// /// nome APP del DB da sincronizzare /// public async Task> AnagKeyValGetAll(string appName) { string source = "DB"; string cString = ConnString(appName); List? dbResult = new List(); try { string currKey = $"{Const.rKeyConfig}:DbSync:AnagKeyVal"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty(rawData)) { source = "REDIS"; var tempResult = JsonConvert.DeserializeObject>(rawData); if (tempResult == null) { dbResult = new List(); } else { dbResult = tempResult; } } else { dbResult = dbController.AnagKeyValGetAll(cString); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, LongCache); // per evitare loopback uso deserialize... var tempResult = JsonConvert.DeserializeObject>(rawData); if (tempResult != null) { dbResult = tempResult; } } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"AnagKeyValGetAll | {source} in: {ts.TotalMilliseconds} ms"); } catch (Exception exc) { Log.Error($"Error during AnagKeyValGetAll:{Environment.NewLine}{exc}"); } return dbResult; } /// /// Elenco record Config /// /// nome APP del DB da sincronizzare /// public async Task> ConfigGetAll(string appName) { string source = "DB"; string cString = ConnString(appName); List? dbResult = new List(); if (!string.IsNullOrEmpty(cString)) { try { string currKey = $"{Const.rKeyConfig}:DbSync:Config"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty(rawData)) { source = "REDIS"; var tempResult = JsonConvert.DeserializeObject>(rawData); if (tempResult == null) { dbResult = new List(); } else { dbResult = tempResult; } } else { dbResult = dbController.ConfigGetAll(cString); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, LongCache); // per evitare loopback uso deserialize... var tempResult = JsonConvert.DeserializeObject>(rawData); if (tempResult != null) { dbResult = tempResult; } } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"ConfigGetAll | {source} in: {ts.TotalMilliseconds} ms"); } catch (Exception exc) { Log.Error($"Error during ConfigGetAll:{Environment.NewLine}{exc}"); } } return dbResult; } /// /// Elenco record Vocabolario /// /// nome APP del DB da sincronizzare /// public async Task> VocabolarioGetAll(string appName) { string source = "DB"; string cString = ConnString(appName); List? dbResult = new List(); try { string currKey = $"{Const.rKeyConfig}:DbSync:Vocabolario"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string? rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty(rawData)) { source = "REDIS"; var tempResult = JsonConvert.DeserializeObject>(rawData); if (tempResult == null) { dbResult = new List(); } else { dbResult = tempResult; } } else { dbResult = dbController.VocabolarioGetAll(cString); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, LongCache); // per evitare loopback uso deserialize... var tempResult = JsonConvert.DeserializeObject>(rawData); if (tempResult != null) { dbResult = tempResult; } } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"VocabolarioGetAll | {source} in: {ts.TotalMilliseconds} ms"); } catch (Exception exc) { Log.Error($"Error during VocabolarioGetAll:{Environment.NewLine}{exc}"); } return dbResult; } #endregion Public Methods #region Protected Fields protected static JsonSerializerSettings? JSSettings; #endregion Protected Fields #region Protected Properties protected DbSyncController dbController { get; set; } = null!; protected LiMan.DB.Controllers.DbController TplController { get; set; } = null!; #endregion Protected Properties #region Private Properties private string CodApp { get; set; } = ""; #endregion Private Properties #region Private Methods /// /// Restituisce la stringa di connessione al DB data app riferimento /// /// /// private string ConnString(string appName) { string answ = ""; try { var currRec = TplController.GetApplicazioniFilt(appName); if (currRec != null) { answ = currRec.TplConnString; } } catch { } return answ; } #endregion Private Methods } }