using Blazored.LocalStorage; using Blazored.SessionStorage; using Microsoft.AspNetCore.Components; using Microsoft.VisualBasic; using NLog; using StackExchange.Redis; using System.Diagnostics; namespace MagMan.Core.Services { public class MessageService { #region Public Constructors public MessageService(ILocalStorageService genLocalStorage, ISessionStorageService sessStore, IConnectionMultiplexer RedConn) { // gestione sessioni in browser localStore = genLocalStorage; sessionStore = sessStore; // setup componenti REDIS redisConn = RedConn; redisDb = redisConn.GetDatabase(); // setup canali pub/sub QueUpdGen = new MessagePipe(redisConn, Const.Q_MMAN_GEN); QueUpdAliasMat = new MessagePipe(redisConn, Const.Q_MMAN_ALIAS_MAT); QueUpdInve= new MessagePipe(redisConn, Const.Q_MMAN_LOG); QueUpdLog = new MessagePipe(redisConn, Const.Q_MMAN_LOG); QueUpdProj = new MessagePipe(redisConn, Const.Q_MMAN_PROJ); QueUpdRes = new MessagePipe(redisConn, Const.Q_MMAN_RES); } #endregion Public Constructors #region Public Events public event Action EA_CustomerSel = null!; public event Action EA_FilterUpdated = null!; public event Action EA_HideSearch = null!; public event Action EA_KeySel = null!; public event Action EA_PageUpdated = null!; public event Action EA_SearchUpdated = null!; public event Action EA_ShowCustomers = null!; public event Action EA_ShowSearch = null!; #endregion Public Events #region Public Properties public int CustomerID { get => _customerID; set { if (_customerID != value) { _customerID = value; if (EA_CustomerSel != null) { EA_CustomerSel?.Invoke(); } } } } public int KeyNum { get => _keyNum; set { if (_keyNum != value) { _keyNum = value; if (EA_KeySel != null) { EA_KeySel?.Invoke(); } } } } public string PageIcon { get => _pageIcon; set { if (_pageIcon != value) { _pageIcon = value; ReportPageUpd(); } } } public string PageName { get => _pageName; set { if (_pageName != value) { _pageName = value; ReportPageUpd(); } } } public string SearchVal { get => _searchVal; set { if (_searchVal != value) { _searchVal = value; if (EA_SearchUpdated != null) { EA_SearchUpdated?.Invoke(); } } } } public string SelOrderCode { get; set; } = ""; public string SelPlantId { get; set; } = "0"; public bool ShowCustomers { get => _showCustomers; set { _showCustomers = value; if (EA_ShowCustomers != null) { EA_ShowCustomers?.Invoke(value); } } } public bool ShowSearch { get => _showSearch; set { if (_showSearch != value) { _showSearch = value; if (_showSearch) { if (EA_ShowSearch != null) { EA_ShowSearch?.Invoke(); } } else { if (EA_HideSearch != null) { EA_HideSearch?.Invoke(); } } } } } /// /// Message pipe ricezione dati da EgtBW relativi a info Alias/Materials /// public MessagePipe QueUpdAliasMat { get; set; } = null!; /// /// Message pipe ricezione dati da EgtBW (General/Generics) /// public MessagePipe QueUpdGen { get; set; } = null!; /// /// Message pipe ricezione dati da EgtBW relativi a info LogMachine /// public MessagePipe QueUpdLog { get; set; } = null!; /// /// Message pipe ricezione dati da EgtBW relativi a info Projects /// public MessagePipe QueUpdProj { get; set; } = null!; /// /// Message pipe ricezione dati da EgtBW relativi a info Resources /// public MessagePipe QueUpdRes { get; set; } = null!; /// /// Message pipe ricezione dati da EgtBW relativi a info Inventario (aggiunta/consumi) /// public MessagePipe QueUpdInve { get; set; } = null!; public string UserName { get; set; } = "NA"; #endregion Public Properties #region Public Methods /// /// Cliente selezionato (da browser data cache) /// public async Task ClientIdGet() { var answ = await localStore.GetItemAsync("ClientID"); return answ; } /// /// Imposta Cliente selezionato (browser data cache) /// public async Task ClientIdSet(int newVal) { await localStore.SetItemAsync("ClientID", newVal); } /// /// Num record x la pagina corrente /// public async Task NumRowGridGet(string gridName) { var answ = await localStore.GetItemAsync($"{gridName}_nRow"); answ = answ > 0 ? answ : 10; return answ; } /// /// Imposta num record x la pagina corrente /// public async Task NumRowGridSet(string gridName, int newVal) { await localStore.SetItemAsync($"{gridName}_nRow", newVal); } /// /// Recupera CustomerID dal dizionario dei token noti o cercando sul DB /// /// /// public async Task CustomerIdByToken(string RestToken) { string currKey = $"{Const.rKeyConfig}:Mserv:Dict:Token2CustID"; int answ = await RedisHashGetInt(currKey, RestToken); return answ; } /// /// salvataggio in dizionario Redis associativo Token / Customer /// /// /// /// public bool CustomerIdByTokenSet(string RestToken, int CustId) { string currKey = $"{Const.rKeyConfig}:Mserv:Dict:Token2CustID"; bool fatto = RedisHashSet(currKey, RestToken, $"{CustId}"); return fatto; } /// /// KeyNum da cliente selezionato (da browser data cache) /// public async Task KeyNumGet() { var answ = await localStore.GetItemAsync("KeyNum"); return answ; } /// /// Imposta KeyNum da cliente selezionato (browser data cache) /// public async Task KeyNumSet(int newVal) { await localStore.SetItemAsync("KeyNum", newVal); } /// /// Recupera CustomerID dal dizionario dei token noti o cercando sul DB /// /// /// public async Task MainKeyByCustomer(int CustID) { string currKey = $"{Const.rKeyConfig}:Mserv:Dict:Cust2MKey"; int answ = await RedisHashGetInt(currKey, $"{CustID}"); return answ; } /// /// salvataggio in dizionario Redis associativo Token / Customer /// /// /// /// public bool MainKeyByCustomerSet(int CustId, int MainKey) { string currKey = $"{Const.rKeyConfig}:Mserv:Dict:Cust2MKey"; bool fatto = RedisHashSet(currKey, $"{CustId}", $"{MainKey}"); return fatto; } /// /// Recupera MainKey dal dizionario dei token noti o cercando sul DB /// /// /// public async Task MainKeyByToken(string RestToken) { string currKey = $"{Const.rKeyConfig}:Mserv:Dict:Token2MKey"; int answ = await RedisHashGetInt(currKey, RestToken); return answ; } /// /// salvataggio in dizionario Redis associativo Token / Customer /// /// /// /// public bool MainKeyByTokenSet(string RestToken, int CustId) { string currKey = $"{Const.rKeyConfig}:Mserv:Dict:Token2MKey"; bool fatto = RedisHashSet(currKey, RestToken, $"{CustId}"); return fatto; } /// /// Get single hash record /// /// Redis Key for Hashlist /// Requested key on list /// Value as Int public async Task RedisHashGetInt(RedisKey currKey, string chiave) { int result = 0; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); var hasVal = await redisDb.HashExistsAsync(currKey, chiave); if (hasVal) { var rawRes = await redisDb.HashGetAsync(currKey, chiave); if (rawRes.HasValue) { int.TryParse($"{rawRes}", out result); } } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"RedisHashGetInt | {currKey} | in: {ts.TotalMilliseconds} ms"); return result; } /// /// Get single hash record /// /// Redis Key for Hashlist /// Requested key on list /// Value as string public async Task RedisHashGetString(RedisKey currKey, string chiave) { string result = ""; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); var hasVal = await redisDb.HashExistsAsync(currKey, chiave); if (hasVal) { var rawRes = await redisDb.HashGetAsync(currKey, chiave); if (rawRes.HasValue) { result = $"{rawRes}"; } } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"RedisHashGetString | {currKey} | in: {ts.TotalMilliseconds} ms"); return result; } /// /// Remove for single hash record /// /// Chiave redis della Hashlist /// Chiave nella HashList /// Esito rimozione public async Task RedisHashRemove(RedisKey currKey, string chiave) { bool fatto = false; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); fatto = await redisDb.HashDeleteAsync(currKey, chiave); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"RedisHashRemove | {currKey} | in: {ts.TotalMilliseconds} ms"); return fatto; } /// /// Resetta 1:1 i dizionari Hash in Redis /// /// public bool ResetHashDict() { bool fatto = false; string baseKey = $"{Const.rKeyConfig}:Mserv:Dict"; try { // salvo! RedisHashDictSet($"{baseKey}:Token2CustID", new Dictionary()); RedisHashDictSet($"{baseKey}:Token2MKey", new Dictionary()); RedisHashDictSet($"{baseKey}:Cust2MKey", new Dictionary()); fatto = true; } catch (Exception exc) { Log.Error($"Eccezione in ResetHashDict{Environment.NewLine}{exc}"); } return fatto; } /// /// Svuota localstorage (clear) /// /// public async Task StoreLocalClear() { bool answ = false; try { await localStore.ClearAsync(); answ = true; } catch (Exception ex) { Log.Error($"Eccezione in StoreLocalClear{Environment.NewLine}{ex}"); } return answ; } /// /// Restituisce il valore richiesto da localstorage /// /// Chiave /// public async Task StoreLocalGet(string sKey) { string answ = ""; var result = await localStore.GetItemAsync(sKey); if (result != null) { answ = result; } return answ; } /// /// Scrive il valore nel localstorage /// /// Chiave /// Valore associato /// public async Task StoreLocalSet(string sKey, string sVal) { bool answ = false; try { await localStore.SetItemAsStringAsync(sKey, sVal); answ = true; } catch (Exception ex) { Log.Error($"Eccezione in StoreLocalSet{Environment.NewLine}{ex}"); } return answ; } /// /// Svuota sessionstorage (clear) /// /// public async Task StoreSessClear() { bool answ = false; try { await sessionStore.ClearAsync(); answ = true; } catch (Exception ex) { Log.Error($"Eccezione in StoreLocalClear{Environment.NewLine}{ex}"); } return answ; } /// /// Restituisce il valore richiesto da sessionstorage /// /// Chiave /// public async Task StoreSessGet(string sKey) { string answ = ""; var result = await sessionStore.GetItemAsync(sKey); if (result != null) { answ = result; } return answ; } /// /// Scrive il valore nel sessionstorage (tab) /// /// Chiave /// Valore associato /// public async Task StoreSessSet(string sKey, string sVal) { bool answ = false; try { await sessionStore.SetItemAsStringAsync(sKey, sVal); answ = true; } catch (Exception ex) { Log.Error($"Eccezione in StoreSessSet{Environment.NewLine}{ex}"); } return answ; } #endregion Public Methods #region Protected Fields /// /// Oggetto per connessione a REDIS /// protected IConnectionMultiplexer redisConn = null!; /// /// Oggetto DB redis da impiegare x chiamate R/W /// protected IDatabase redisDb = null!; #endregion Protected Fields #region Protected Properties protected ILocalStorageService localStore { get; set; } = null!; protected ISessionStorageService sessionStore { get; set; } = null!; #endregion Protected Properties #region Protected Methods /// /// Effettua upsert in HasList redis /// /// Chiave redis della Hashlist /// Chiave nella HashList /// Valore da salvare /// Num record nella HashList protected async Task RedisHashUpsert(RedisKey currKey, string chiave, string valore) { long numReq = 0; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); await redisDb.HashSetAsync(currKey, chiave, valore); numReq = await redisDb.HashLengthAsync(currKey); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"RedisHashUpsert | {currKey} | in: {ts.TotalMilliseconds} ms"); return numReq; } #endregion Protected Methods #if false private SelectData _detailFilter = SelectData.Init(5, 15); #endif #region Private Fields private int _customerID = -1; private int _keyNum = -1; private string _pageIcon = ""; private string _pageName = ""; private string _searchVal = ""; private bool _showCustomers = true; private bool _showSearch = false; private Logger Log = LogManager.GetCurrentClassLogger(); #endregion Private Fields #region Private Methods /// /// Recupero HashSet redis come Dictionary /// /// /// private Dictionary RedisHashDictGet(RedisKey currKey) { Dictionary answ = new Dictionary(); try { answ = redisDb .HashGetAll(currKey) .ToDictionary(x => $"{x.Name}", x => $"{x.Value}"); } catch (Exception exc) { Log.Info($"Errore RedisHashDictGet | currKey: {currKey}{Environment.NewLine}{exc}"); } return answ; } /// /// Salvataggio Dictionary come HashSet Redis /// /// /// private bool RedisHashDictSet(RedisKey currKey, Dictionary dict) { bool fatto = false; try { HashEntry[] data2ins = new HashEntry[dict.Count]; int i = 0; foreach (KeyValuePair kvp in dict) { data2ins[i] = new HashEntry(kvp.Key, kvp.Value); i++; } // salvo! redisDb.HashSet(currKey, data2ins); fatto = true; } catch (Exception exc) { Log.Error($"Eccezione in RedisHashDictSet | currKey: {currKey}{Environment.NewLine}{exc}"); } return fatto; } /// /// Salvataggio Dictionary come HashSet Redis /// /// /// /// private bool RedisHashDictSet(RedisKey currKey, Dictionary dict, TimeSpan ttl) { bool fatto = false; try { HashEntry[] data2ins = new HashEntry[dict.Count]; int i = 0; foreach (KeyValuePair kvp in dict) { data2ins[i] = new HashEntry(kvp.Key, kvp.Value); i++; } // salvo! redisDb.HashSet(currKey, data2ins); redisDb.KeyExpire(currKey, ttl); fatto = true; } catch (Exception exc) { Log.Error($"Eccezione in RedisHashDictSet(+TTL) | currKey: {currKey} | ttl: {ttl}{Environment.NewLine}{exc}"); } return fatto; } /// /// Aggiunta KVP in HashSet Redis /// /// /// private bool RedisHashSet(RedisKey currKey, string hashField, string value) { bool fatto = false; try { // salvo! redisDb.HashSet(currKey, hashField, value); fatto = true; } catch (Exception exc) { Log.Error($"Eccezione in RedisHashSet | currKey: {currKey}{Environment.NewLine}{exc}"); } return fatto; } private void ReportPageUpd() { if (EA_PageUpdated != null) { EA_PageUpdated?.Invoke(); } } private void ReportSearch() { if (EA_SearchUpdated != null) { EA_SearchUpdated?.Invoke(); } } #endregion Private Methods #if false /// /// Dizionario totale preferenze utente /// public Dictionary UsersPrefDict { get => RedisHashDictGet((RedisKey)$"{redisBaseKey}:{MatrOpr}"); set => RedisHashDictSet((RedisKey)$"{redisBaseKey}:{MatrOpr}", value); } #endif } }