using EgwCoreLib.Razor.Data; using Microsoft.AspNetCore.Identity.UI.Services; using Microsoft.EntityFrameworkCore; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using NLog; using Org.BouncyCastle.Asn1.X509; using StackExchange.Redis; using System.Diagnostics; using System.Reflection.Emit; using System.Security.AccessControl; 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 = ""; string edgeType = ""; string sizeVal = ""; string swingType = ""; int numHier = 1; List listGraphicParams = new List(); List listValues = new List(); ListValuesTempModel Values = new ListValuesTempModel(); 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(); string[] DefaultFile = Directory.GetFiles(rootPath, "Default.ini"); IniFile fIniDef = new IniFile(DefaultFile[0]); // parto con obj base sizeVal = fIniDef.ReadString("Size", "Width", "0.0"); ListValuesTempModel listValObj = new ListValuesTempModel() { TableName = "DoorDef", FieldName = "Sizing", Value = "Width", Label = "Width", Ordinal = 1, DefaultVal = sizeVal, InputType = "TextBox", isSerializable = true }; listValues.Add(listValObj); sizeVal = fIniDef.ReadString("Size", "Height", "0.0"); listValObj = new ListValuesTempModel() { TableName = "DoorDef", FieldName = "Sizing", Value = "Height", Label = "Height", Ordinal = 2, DefaultVal = sizeVal, InputType = "TextBox", isSerializable = true }; listValues.Add(listValObj); sizeVal = fIniDef.ReadString("Size", "Thickness", "0.0"); listValObj = new ListValuesTempModel() { TableName = "DoorDef", FieldName = "Sizing", Value = "Thickness", Label = "Thickness", Ordinal = 3, DefaultVal = sizeVal, InputType = "TextBox", isSerializable = true }; listValues.Add(listValObj); sizeVal = fIniDef.ReadString("Size", "Swing", "UNDEF"); listValObj = new ListValuesTempModel() { TableName = "DoorDef", FieldName = "Sizing", Value = "Swing", Label = "Swing", Ordinal = 1, DefaultVal = sizeVal, InputType = "TextBox", isSerializable = true }; listValues.Add(listValObj); sizeVal = fIniDef.ReadString("Edge", "HingeEdge", "UNDEF"); listValObj = new ListValuesTempModel() { TableName = "DoorDef", FieldName = "Edge", Value = "HingeEdge", Label = "Hinge Edge", Ordinal = 1, DefaultVal = sizeVal, InputType = "ComboBox", isSerializable = true }; listValues.Add(listValObj); sizeVal = fIniDef.ReadString("Edge", "TopEdge", "UNDEF"); listValObj = new ListValuesTempModel() { TableName = "DoorDef", FieldName = "Edge", Value = "TopEdge", Label = "Top Edge", Ordinal = 2, DefaultVal = sizeVal, InputType = "ComboBox", isSerializable = true }; listValues.Add(listValObj); sizeVal = fIniDef.ReadString("Edge", "BottomEdge", "UNDEF"); listValObj = new ListValuesTempModel() { TableName = "DoorDef", FieldName = "Edge", Value = "BottomEdge", Label = "Bottom Edge", Ordinal = 3, DefaultVal = sizeVal, InputType = "ComboBox", isSerializable = true }; listValues.Add(listValObj); sizeVal = fIniDef.ReadString("Edge", "LockEdge", "UNDEF"); listValObj = new ListValuesTempModel() { TableName = "DoorDef", FieldName = "Edge", Value = "LockEdge", Label = "Lock Edge", Ordinal = 4, DefaultVal = sizeVal, InputType = "ComboBox", isSerializable = true }; listValues.Add(listValObj); 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) listValObj = new ListValuesTempModel() { TableName = $"{compoNameSplit[1]}", FieldName = "Hardware", Value = $"{compoNameSplit[0]}", Label = $"{compoNameSplit[1]}", Ordinal = 0, DefaultVal = " ", InputType = " " }; //HardwareModel compoConfig = new HardwareModel() { compoName = $"{compoNameSplit[0]}", compoAlias = compoNameSplit[1].ToString(), compoLayerName = layerName, compoTemplateIsActive = compoTemplateIsActive }; //await dbController.CompoAdd(compoConfig); //listCompoS.Add(compoConfig); listValues.Add(listValObj); //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) { var listV = await GraphicParamsGetAll(file, match, numHead, numPar, $"{compoNameSplit[1]}"); foreach (var item in listV) { listValues.Add(item); } numHead++; } numPar++; } } } fatto = await dbController.ListValuesAdd(listValues); 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; } public async Task ListValuesLuaNgeInsert(string rootPath) { List values = new List(); string[] dirs = Directory.GetDirectories(rootPath); foreach (string dir in dirs) { string compoCode = ""; string[] templateDirectories = Directory.GetDirectories(dir); string[] iniFiles = Directory.GetFiles(dir, "Config.ini"); int ordin = 1; foreach (string templateDirectory in templateDirectories) { var tName = templateDirectory.Split("\\"); var fName = templateDirectory.Split("\\"); foreach (var file in iniFiles) { List lines = File.ReadAllLines(file).ToList(); IniFile fIni = new IniFile(file); var compoName = fIni.ReadString("Compo", "Name", "COMPONAME"); compoCode = compoName.Split("/")[1]; } ListValuesTempModel folderNames = new ListValuesTempModel() { TableName = $"{compoCode}".Replace(" ", "_"), FieldName = "Folder", Value = @$"{tName[tName.Length - 1]}".Replace(" ", "_"), Label = @$"{tName[tName.Length - 1]}", Ordinal = 0, DefaultVal = " ", InputType = " ", }; values.Add(folderNames); string[] templateFiles = Directory.GetFiles(templateDirectory); foreach (string templateFile in templateFiles) { ListValuesTempModel temp = new ListValuesTempModel() { TableName = $"{compoCode}".Replace(" ", "_"), FieldName = "Template", Value = @$"{tName[tName.Length - 1]}\{Path.GetFileName(templateFile)}".Replace(" ", "_"), Label = Path.GetFileName(templateFile).Split(".")[0], Ordinal = ordin, DefaultVal = " ", InputType = " ", }; values.Add(temp); ordin++; } } } bool fatto = await dbController.ListValuesAdd(values); return fatto; } /// /// 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 DoorOpList 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; } /// /// Aggiornamento DoorOP /// /// /// public async Task DoorOpUpdate(DoorOpModel currDoorOp) { var dbResult = await dbController.DoorOpUpdate(currDoorOp); // elimino cache redis dati porta... bool answ = await DoorOpFlushCache(currDoorOp.DoorId); answ = answ && await DoorFlushCache(currDoorOp.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; } public async Task> GraphicParamsGetAll(string file, string match, int n, int i, string HwCode) { await Task.Delay(1); List listValuesTemp = new List(); ListValuesTempModel listValObj = new ListValuesTempModel(); IniFile fIni = new IniFile(file); //cerco il contenuto delle sezioni var graphicParamsName = fIni.ReadSection(match.Substring(1, match.Length - 2)); //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 if (int.Parse(match.Substring(match.Length - 2, 1)) == n) { int ordinal = 1; 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]; } else if (compoParamsSplit[1].Contains(" ")) { CompoParamName = compoParamsSplit[1].Split(" ")[1]; //CompoParamAlias = compoParamsSplit[1].Split(" ")[1]; } //creo nuovo oggetto parametro che conterrà anche il nome del componente per creare relazione listValObj = new ListValuesTempModel() { TableName = $"{HwCode}", FieldName = match.Substring(1, match.Length - 2), Value = CompoParamName, Label = CompoParamAlias, Ordinal = ordinal, DefaultVal = param.Split("=")[1].Split(";")[2], InputType = param.Split("=")[1].Split(";")[0], isSerializable = true }; if (listValuesTemp.Where(x => x.TableName == listValObj.TableName && x.FieldName == listValObj.FieldName && x.Value == listValObj.Value).Count() == 0 && listValObj.TableName != null && listValObj.FieldName != null && listValObj.Value != null) { listValuesTemp.Add(listValObj); ordinal++; } else { Log.Error($"GraphicParamsGetAll | Duplicated key: {listValObj.TableName} {listValObj.FieldName} {listValObj.Value} "); } } else { } } } return listValuesTemp; } /// /// List values /// public async Task?> ListValuesGetAll(string tableName, string fieldName) { string source = "DB"; List? dbResult = new List(); string currKey = ""; // cerco da cache 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; } /// /// 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 } }