using EgwCoreLib.Razor.Data; using Microsoft.AspNetCore.Identity.UI.Services; using Microsoft.EntityFrameworkCore; using Newtonsoft.Json; using NLog; using StackExchange.Redis; using System.Diagnostics; using WebDoorCreator.Core; using WebDoorCreator.Data.Controllers; using WebDoorCreator.Data.DbModels; namespace WebDoorCreator.UI.Data { public class WebDoorCreatorService { #region Public Fields public static WebDoorCreatorController dbController = null!; #endregion Public Fields #region Public Constructors public WebDoorCreatorService(IConfiguration configuration, IConnectionMultiplexer redisConnMult, IEmailSender emailSender) { _configuration = configuration; _emailSender = emailSender; // 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"]; // Conf DB string connStr = _configuration.GetConnectionString("WDC.DB"); if (string.IsNullOrEmpty(connStr)) { Log.Info("ConnString empty!"); } else { dbController = new WebDoorCreatorController(configuration); } Log.Info("Avviata classe WebDoorCreatorService"); } #endregion Public Constructors #region Public Properties public string CodApp { get; set; } = ""; #endregion Public Properties #region Public Methods /// /// Update company /// /// /// public async Task CompanyAddMod(CompanyModel currRec) { var dbResult = await dbController.CompanyAddMod(currRec); // elimino cache redis... RedisValue pattern = new RedisValue($"{rKeyCompany}"); bool answ = await ExecFlushRedisPattern(pattern); await Task.Delay(1); return dbResult; } /// /// Company list filtered by company id /// /// Id to filter (0=ALL) /// public async Task> CompanyGetByKey(int id) { string source = "DB"; List dbResult = new List(); // cerco da cache string currKey = $"{rKeyCompany}:{id}"; 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.CompanyGetByKey(id); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, UltraLongCache); } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"CompanyGetAll | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /*----------------------------------------------------------------------------------------------------------------------*/ /// /// Getting a list of all the active components /// /// Path to start /// public async Task> CompoGetAllActive(string rootPath) { await Task.Delay(1); List listActiveCompo = new List(); //estraggo la lista di componenti che sono attive per il cliente IniFile fIni = new IniFile(rootPath); string compoDDF = fIni.ReadString("CompoOrder", "CompoDDFOrder", "CONFIG"); var compoDDFList = compoDDF.Split(","); foreach (string compo in compoDDFList) { listActiveCompo.Add(compo.Trim()); } return listActiveCompo; } /// /// Setting all the component list /// /// Path to start /// public async Task CompoListSetAll(string rootPath) { bool fatto = false; string compoName = ""; int numHier = 1; List listGraphicParams = new List(); dbController.TestTablesTruncate(); List listActiveCompo = await CompoGetAllActive(Path.Combine(rootPath, @"Default.ini")); List listCompoS = new List(); //estraggo tutte le sotto directory della cartella \EgtData\Doors\EgtCompoBase\Compo string[] dirs = Directory.GetDirectories(rootPath, "*", SearchOption.TopDirectoryOnly); // elenco obj da inserire List ListObjDOT = new List(); // parto con obj base List edges = new List(); edges.Add(new Edges()); List sizing = new List(); sizing.Add(new Sizing()); List opening = new List(); opening.Add(new Opening()); Guid opCodeEdges = Guid.NewGuid(); Guid opCodeSizing = Guid.NewGuid(); Guid opCodeOpening = Guid.NewGuid(); DoorOpTypeModel doorOpTypeEdges = new DoorOpTypeModel() { Description = "DOOR OPERATION TYPE FOR Edges", OpCode = opCodeEdges.ToString(), HasHw = false, IsConcrete = true, DoorOpIdPathFromPatriarch = HierarchyId.Parse($"/{numHier}/"), IsDefault = true, JsoncConfig = JsonConvert.SerializeObject(edges), DisplayUrl = $"DoorOpTypeImg/{numHier}.svg", MaxAllowed = 1 }; numHier++; DoorOpTypeModel doorOpTypeSizing = new DoorOpTypeModel() { Description = "DOOR OPERATION TYPE FOR Sizing", OpCode = opCodeSizing.ToString(), HasHw = false, IsConcrete = true, DoorOpIdPathFromPatriarch = HierarchyId.Parse($"/{numHier}/"), IsDefault = true, JsoncConfig = JsonConvert.SerializeObject(sizing), DisplayUrl = $"DoorOpTypeImg/{numHier}.svg", MaxAllowed = 1 }; numHier++; DoorOpTypeModel doorOpTypeOpening = new DoorOpTypeModel() { Description = "DOOR OPERATION TYPE FOR Opening", OpCode = opCodeOpening.ToString(), HasHw = false, IsConcrete = true, DoorOpIdPathFromPatriarch = HierarchyId.Parse($"/{numHier}/"), IsDefault = true, JsoncConfig = JsonConvert.SerializeObject(opening), DisplayUrl = $"DoorOpTypeImg/{numHier}.svg", MaxAllowed = 1 }; numHier++; //await dbController.DoorOpTypeAdd(doorOpTypeEdges); //await dbController.DoorOpTypeAdd(doorOpTypeSizing); //await dbController.DoorOpTypeAdd(doorOpTypeOpening); ListObjDOT.Add(doorOpTypeEdges); ListObjDOT.Add(doorOpTypeSizing); ListObjDOT.Add(doorOpTypeOpening); foreach (string dir in dirs) { int numPar = 1; int numHead = 1; // scansione della directory... string[] files = Directory.GetFiles(dir, "Config.ini"); compoName = ""; //iterazione per cercare tutti numPar file "Config.ini" nelle sotto directory foreach (string file in files) { //leggo tutte le linee del file List lines = File.ReadAllLines(file).ToList(); IniFile fIni = new IniFile(file); Guid opCode = Guid.NewGuid(); //cerco la sezione del file ed estraggo il nome del componente compoName = fIni.ReadString("Compo", "Name", "COMPONAME"); //cerco la sezione del file ed estraggo se numPar template sono attivi per il seguente componente var isActive = fIni.ReadString("Template", "IsActive", "1"); bool compoTemplateIsActive = true; string layerName = fIni.ReadString("Layer", "LayerName", "LAYER"); if (isActive == "0") { compoTemplateIsActive = false; } // lo slash indica l'alias var compoNameSplit = compoName.Split("/"); if (listActiveCompo.Contains(compoNameSplit[0].ToString())) { //creo il componente (padre) HardwareModel compoConfig = new HardwareModel() { compoName = $"{compoNameSplit[0]}", compoAlias = compoNameSplit[1].ToString(), compoLayerName = layerName, compoTemplateIsActive = compoTemplateIsActive }; await dbController.CompoAdd(compoConfig); listCompoS.Add(compoConfig); //cerco all'interno del file tutte le sezioni che contengono "[Graphic" così da poter prendere il nome della sezione ES: [Graphic parameters1] = Graphic parameters1 var lineToSearch = lines.Where(x => x.Contains("[Graphic")).ToList(); numHead = 1; foreach (var match in lineToSearch) { listGraphicParams = await GraphicParamsGetAll(file, match, numHead, numPar); numHead++; } DoorOpTypeModel doorOpType = new DoorOpTypeModel() { Description = $"DOOR OPERATION TYPE FOR {compoNameSplit[0]}", OpCode = opCode.ToString(), HasHw = true, IsConcrete = true, HwCode = $"{compoNameSplit[1]}", DoorOpIdPathFromPatriarch = HierarchyId.Parse($"/{numHier}/"), JsoncConfig = JsonConvert.SerializeObject(listGraphicParams), DisplayUrl = $"DoorOpTypeImg/{numHier}.svg", MaxAllowed = 2 }; numHier++; ListObjDOT.Add(doorOpType); //await dbController.DoorOpTypeAdd(doorOpType); } numPar++; } } fatto = await dbController.DoorOpTypeAddRange(ListObjDOT); return fatto; } public async Task VocLemmaInsert(string rootPath) { bool fatto = false; List VocLemmas = new List(); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string[] files = Directory.GetFiles(rootPath, "*"); string lang = ""; foreach (string file in files) { var fileName = file.Split("."); lang = fileName[0].Substring(fileName[0].Length - 2, 2); //leggo tutte le linee del file List lines = File.ReadAllLines(file).ToList(); foreach (var line in lines) { if (!line.StartsWith("//") && line != "") { string[] lineSplit = line.Split("="); //string trad = ""; if (lineSplit.Length != 1) { VocabularyTempModel newVocLemma = new VocabularyTempModel() { Lingua = lang, Lemma = lineSplit[0], Traduzione = lineSplit[1] }; VocLemmas.Add(newVocLemma); } } } } fatto = await dbController.VocLemmaInsert(VocLemmas); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"VocLemmaInsert in: {ts.TotalMilliseconds} ms"); return fatto; } public string DecriptData(string encData) { return SteamCrypto.DecryptString(encData, passPhrase); } /// /// CElimina record posta /// /// /// public async Task DoorDelete(DoorModel currRec) { int DoorId = currRec.DoorId; int OrderId = currRec.OrderId; // elimino sul DB bool answ = await dbController.DoorDelete(DoorId); // svuoto cache await DoorFlushCache(DoorId); await DoorOpFlushCache(DoorId); await OrderDetailFlushCache(OrderId); await OrdersFlushCache(); return answ; } /// /// Clean redis DOORS cache /// /// 0 = all /// public async Task DoorFlushCache(int DoorId) { RedisValue pattern = new RedisValue($"{rKeyDoor}:*"); if (DoorId > 0) { pattern = new RedisValue($"{rKeyDoor}:{DoorId}:*"); } bool answ = await ExecFlushRedisPattern(pattern); return answ; } /// /// Doors list by orderId /// public async Task?> DoorGetByOrderId(int orderId) { string source = "DB"; List? dbResult = new List(); // cerco da cache string currKey = $"{rKeyOrderDetail}:{orderId}"; 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.DoorsGetByOrderId(orderId); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, UltraLongCache); } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"DoorGetByOrderId | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /// /// Add door /// /// /// public async Task DoorInsert(DoorModel newRec) { var dbResult = await dbController.DoorInsert(newRec); // elimino cache redis dati ordine... await OrderDetailFlushCache(newRec.OrderId); await OrdersFlushCache(); return dbResult; } /// /// Adding or removing a single door /// /// Record id to edit or add /// States if it has to be added or removing a door /// public async Task DoorModQty(int OrderId, int DoorId, bool isAdd) { var dbResult = await dbController.DoorModQty(DoorId, isAdd); // svuoto cache await DoorFlushCache(DoorId); await DoorOpFlushCache(DoorId); await OrderDetailFlushCache(OrderId); await OrdersFlushCache(); return dbResult; } /// /// Clean redis DOORS OP cache /// /// 0 = all /// public async Task DoorOpFlushCache(int DoorId) { RedisValue pattern = new RedisValue($"{rKeyDoorOp}:*"); if (DoorId > 0) { pattern = new RedisValue($"{rKeyDoorOp}:{DoorId}:*"); } bool answ = await ExecFlushRedisPattern(pattern); return answ; } /// /// Doors list by orderId /// public async Task?> DoorOpGetByDoorId(int doorId) { string source = "DB"; List? dbResult = new List(); // cerco da cache string currKey = $"{rKeyDoorOp}:{doorId}"; 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.DoorOpGetByDoorId(doorId); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, UltraLongCache); } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"DoorOpGetByDoorId | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } public async Task>?> VocLemmaGetAll() { string source = "DB"; Dictionary>? dbResult = new Dictionary>(); // cerco da cache Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string currKey = $"{rKeyVocLemma}"; string? rawData = await redisDb.StringGetAsync(currKey); if (!string.IsNullOrEmpty(rawData)) { source = "REDIS"; var tempResult = JsonConvert.DeserializeObject>>(rawData); if (tempResult == null) { dbResult = new Dictionary>(); } else { dbResult = tempResult; } } else { dbResult = dbController.VocLemmaGetAll(); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, UltraLongCache); } if (dbResult == null) { dbResult = new Dictionary>(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"VocLemmaGetAll | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /// /// Doors list by orderId /// public async Task?> DoorOpTypeGetAll() { string source = "DB"; List? dbResult = new List(); // cerco da cache string currKey = $"{rKeyDoorOpType}"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); #if false 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 { rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, UltraLongCache); } #endif dbResult = dbController.DoorOpTypeGetAll(); if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"DoorOpTypeGetAll | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /// /// lista DoorOp necessarie all'init /// /// public async Task> DoorOpGetDefault() { List? dbResult = new List(); string source = "DB"; // cerco da cache string currKey = $"{rKeyDoorOpType}:DEFAULT"; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); #if false 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 { #endif dbResult = await dbController.DoorOpTypeGetDefault(); #if false rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, UltraLongCache); } #endif if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"DoorOpGetDefault | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /// /// Add doorOP list /// /// /// /// public async Task DoorOpInsert(int DoorId, List newOpList) { var dbResult = await dbController.DoorOpInsert(newOpList); // elimino cache redis dati porta... bool answ = await DoorOpFlushCache(DoorId); answ = answ && await DoorFlushCache(DoorId); // elimino cache redis dati ordine... answ = answ && await OrdersFlushCache(); return dbResult; } /// /// Update or add door /// /// /// public async Task DoorUpsert(DoorModel currRec) { var dbResult = await dbController.DoorUpsert(currRec); // elimino cache redis dati porta... bool answ = await DoorFlushCache(currRec.DoorId); // elimino cache redis dati ordine... answ = answ && await OrdersFlushCache(); return dbResult; } public string EncriptData(string rawData) { return SteamCrypto.EncryptString(rawData, passPhrase); } public async Task FlushRedisCache() { await Task.Delay(1); RedisValue pattern = new RedisValue($"{redisBaseAddr}*"); bool answ = await ExecFlushRedisPattern(pattern); return answ; } /// /// Setting the graphic parameters for components /// /// /// /// /// /// public async Task> GraphicParamsGetAll(string file, string match, int n, int i) { await Task.Delay(1); List listGraphicParams = new List(); IniFile fIni = new IniFile(file); //estraggo la lista di componenti che sono attive per il cliente var graphicParamsName = fIni.ReadSection(match.Substring(1, match.Length - 2)); //cerco il contenuto delle sezioni if (int.Parse(match.Substring(match.Length - 2, 1)) == n) //controllo se tra numPar numeri di graphic params vi è un buco ES: Graphic parameters1 Graphic parameters3 se il buco c'è salto tutti numPar parametri che stanno dopo il buco ==> tengo conto solo di Graphic parameters1 { foreach (string param in graphicParamsName) { string compoParams = fIni.ReadString(match.Substring(1, match.Length - 2), $"{param.Split("=")[0]}", "CONFIG"); //cerco il parametro nella sezione var compoParamsSplit = compoParams.Split(";"); string CompoParamName = ""; string CompoParamAlias = ""; if (param.Split("=")[0].StartsWith("Param")) { if (compoParamsSplit[1].Contains("/")) { CompoParamName = compoParamsSplit[1].Split("/")[0]; CompoParamAlias = compoParamsSplit[1].Split("/")[1]; } GraphicParamsModel graphicParams = new GraphicParamsModel() { compoId = i, graphicParamsN = match.Substring(1, match.Length - 2), graphicParamKey = param.Split("=")[0], graphicParamName = CompoParamName, graphicParamAlias = CompoParamAlias, graphicParamType = compoParamsSplit[0], graphicParamDefaultVal = compoParamsSplit[2] }; listGraphicParams.Add(graphicParams); //creo nuovo oggetto parametro che conterrà anche il nome del componente per creare relazione await dbController.ParamAdd(graphicParams); } else { GraphicParamsModel graphicParams = new GraphicParamsModel() { compoId = i, graphicParamsN = match.Substring(1, match.Length - 2), graphicParamKey = param.Split("=")[0], graphicParamName = compoParams }; listGraphicParams.Add(graphicParams); //creo nuovo oggetto parametro che conterrà anche il nome del componente per creare relazione await dbController.ParamAdd(graphicParams); } } } return listGraphicParams; } /// /// Company list /// public async Task?> ListValuesGetAll(string tableName, string fieldName) { string source = "DB"; List? dbResult = new List(); // cerco da cache string currKey = $"{rKeyListValues}:{tableName}:{fieldName}"; 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.ListValuesGetAll(tableName, fieldName); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, UltraLongCache); } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"ListValuesGetAll | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /// /// Estraggo tutte le lingue disponibili per questa applicazione /// /// public async Task?> LanguageGetAll() { string source = "DB"; List? dbResult = new List(); // cerco da cache string currKey = $"{rKeyLanguage}"; 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.LanguageGetAll(); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, UltraLongCache); } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"LanguageGetAll | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /// /// Add new order /// /// /// public async Task OrderAdd(OrderModel currRec) { var dbResult = await dbController.OrderAdd(currRec); // elimino cache redis... RedisValue pattern = new RedisValue($"{rKeyOrderStatus}:*"); bool answ = await ExecFlushRedisPattern(pattern); return dbResult; } /// /// Clean REDIS order detail data in cache /// /// 0 = all /// public async Task OrderDetailFlushCache(int OrderId) { RedisValue pattern = new RedisValue($"{rKeyOrderDetail}:*"); if (OrderId > 0) { pattern = new RedisValue($"{rKeyOrderDetail}:{OrderId}"); } bool answ = await ExecFlushRedisPattern(pattern); return answ; } /// /// Remove order /// /// /// public async Task OrderRem(int OrdId) { var dbResult = await dbController.OrderRem(OrdId); // elimino cache redis... RedisValue pattern = new RedisValue($"{rKeyOrderStatus}:*"); bool answ = await ExecFlushRedisPattern(pattern); return dbResult; } /// /// Clean redis ORDERS cache /// /// /// public async Task OrdersFlushCache() { RedisValue pattern = new RedisValue($"{rKeyOrderStatus}:*"); bool answ = await ExecFlushRedisPattern(pattern); return answ; } public async Task?> OrderStatusGetFilt(int companyId, int orderStatus, DateTime dataFrom, DateTime dataTo) { string source = "DB"; List? dbResult = new List(); // cerco da cache string currKey = $"{rKeyOrderStatus}:{companyId}:{orderStatus}:{dataFrom:yyyyMMdd}:{dataTo:yyyyMMdd}"; 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.OrderStatusGetAll(companyId, orderStatus, dataFrom, dataTo); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, UltraLongCache); } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"OrderStatusGetFilt | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /// /// Graphic parameters list by hw id /// public async Task?> ParamGetByHwId(int hwId) { string source = "DB"; List? dbResult = new List(); // cerco da cache string currKey = $"{rKeyGraphicParameters}:{hwId}"; 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.ParamGetByHwId(hwId); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, UltraLongCache); } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"ParamGetByHwId | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /// /// Graphic parameters list by hw id /// //public async Task?> HardwareGetAll() //{ // string source = "DB"; // List? dbResult = new List(); // // cerco da cache // string currKey = $"{rKeyGraphicParameters}"; // 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.HardwareGetAll(); // rawData = JsonConvert.SerializeObject(dbResult, JSSettings); // await redisDb.StringSetAsync(currKey, rawData, UltraLongCache); // } // if (dbResult == null) // { // dbResult = new List(); // } // stopWatch.Stop(); // TimeSpan ts = stopWatch.Elapsed; // Log.Debug($"HardwareGetAll | {source} in: {ts.TotalMilliseconds} ms"); // return dbResult; //} /// /// roles list /// public async Task?> RolesGetAll() { string source = "DB"; List? dbResult = new List(); // cerco da cache string currKey = rKeyRoles; 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.RolesGetAll(); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, UltraLongCache); } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"RolesGetAll | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /// /// Users roles list /// public async Task?> UsersGetAll() { string source = "DB"; List? dbResult = new List(); // cerco da cache string currKey = rKeyUsers; 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.UsersGetAll(); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, UltraLongCache); } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"UsersGetAll | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /// /// Users roles list /// public async Task UsersGetById(string userId) { string source = "DB"; AspNetUsers dbResult = new AspNetUsers(); // cerco da cache string currKey = $"{rKeyUsers}:{userId}"; 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 AspNetUsers(); } else { dbResult = tempResult; } } else { dbResult = dbController.UsersGetById(userId); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, UltraLongCache); } if (dbResult == null) { dbResult = new AspNetUsers(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"UsersGetById | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } /// /// Users roles list /// public async Task?> UserViewGetAll() { string source = "DB"; List? dbResult = new List(); // cerco da cache string currKey = rKeyUsersView; 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.UserViewGetAll(); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, UltraLongCache); } if (dbResult == null) { dbResult = new List(); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Debug($"UserViewGetAll | {source} in: {ts.TotalMilliseconds} ms"); return dbResult; } #endregion Public Methods #region Protected Fields protected const string passPhrase = "9eb4660f-8753-46bc-b23b-08759ba03fe9"; protected const string redisBaseAddr = "WDC"; protected const string rKeyCompany = $"{redisBaseAddr}:Cache:Company"; protected const string rKeyDoor = $"{redisBaseAddr}:Cache:Door"; protected const string rKeyDoorOp = $"{redisBaseAddr}:Cache:DoorOp"; protected const string rKeyDoorOpType = $"{redisBaseAddr}:Cache:DoorOpType"; protected const string rKeyGraphicParameters = $"{redisBaseAddr}:Cache:GraphicParameters"; protected const string rKeyListValues = $"{redisBaseAddr}:Cache:ListValues"; protected const string rKeyOrderDetail = $"{redisBaseAddr}:Cache:OrderDetail"; protected const string rKeyOrderStatus = $"{redisBaseAddr}:Cache:OrderStatus"; protected const string rKeyRoles = $"{redisBaseAddr}:Cache:Roles"; protected const string rKeyUsers = $"{redisBaseAddr}:Cache:Users"; protected const string rKeyUsersView = $"{redisBaseAddr}:Cache:UsersView"; protected const string rKeyVocLemma = $"{redisBaseAddr}:Cache:VocLemma"; protected const string rKeyLanguage = $"{redisBaseAddr}:Cache:Languages"; protected Random rnd = new Random(); #endregion Protected Fields #region Private Fields private static IConfiguration _configuration = null!; private static JsonSerializerSettings? JSSettings; private static NLog.Logger Log = LogManager.GetCurrentClassLogger(); private readonly IEmailSender _emailSender; /// /// Durata cache lunga IN SECONDI /// private int cacheTtlLong = 60 * 5; /// /// Durata cache breve IN SECONDI /// private int cacheTtlShort = 60 * 1; /// /// Oggetto per connessione a REDIS /// private IConnectionMultiplexer redisConn; /// /// Oggetto DB redis da impiegare x chiamate R/W /// private IDatabase redisDb = null!; #endregion Private Fields #region Private Properties /// /// Durata cache lunga (+ perturbazione percentuale +/-10%) /// private TimeSpan FastCache { get => TimeSpan.FromSeconds(cacheTtlShort * rnd.Next(900, 1100) / 1000); } /// /// Durata cache lunga (+ perturbazione percentuale +/-10%) /// private TimeSpan LongCache { get => TimeSpan.FromSeconds(cacheTtlLong * rnd.Next(900, 1100) / 1000); } /// /// Durata cache lunga (+ perturbazione percentuale +/-10%) /// private TimeSpan UltraLongCache { get => TimeSpan.FromSeconds(cacheTtlLong * 10 * rnd.Next(900, 1100) / 1000); } #endregion Private Properties #region Private Methods /// /// Esegue flush memoria redis dato pattern /// /// /// private async Task ExecFlushRedisPattern(RedisValue pattern) { bool answ = false; var listEndpoints = redisConn.GetEndPoints(); foreach (var endPoint in listEndpoints) { //var server = redisConnAdmin.GetServer(listEndpoints[0]); var server = redisConn.GetServer(endPoint); if (server != null) { var keyList = server.Keys(redisDb.Database, pattern); foreach (var item in keyList) { await redisDb.KeyDeleteAsync(item); } answ = true; } } return answ; } #endregion Private Methods } }