using MongoDB.Driver; using Newtonsoft.Json; using NLog.Fluent; using NLog; using StackExchange.Redis; using SteamWare.Logger; using System; using System.Collections.Generic; using System.Configuration; using System.Data; using System.Text; using System.Threading; using System.Web; namespace SteamWare.IO { /// /// layer gestione vari tipi di memoria: cache, session... /// public class memLayer { #region Public Fields /// /// oggetto singleton x accesso al layer di memoria /// public static memLayer ML = new memLayer(); /// /// oggetto dizionario con chiave / valore x configurazioni applicazione /// public Dictionary AppConf; /// /// Definisce il TTL x appConf (secondi) /// public int maxAgeAppConf = 5; /// /// Table adapter accesso conf parameters /// public DS_UtilityTableAdapters.ConfigTableAdapter taConfig; /// /// Table adapter accesso conf parameters TMP (x import/check) /// public DS_UtilityTableAdapters.ConfigTmpTableAdapter taConfigTmp; #endregion Public Fields #region Public Constructors /// /// classe gestione accessi a Session, cache, viewstate, configuration... /// public memLayer() { if (Log == null) { Log = LogManager.GetCurrentClassLogger(); } // istanzia il conf setting reader... configAppSetReader = new AppSettingsReader(); // avvio e configuro TA initTA(); setupConnectionStringBase(); setupMongo(); setupParams(); } #endregion Public Constructors #region Public Enums /// /// Tipologia di ordinamento x liste KVP /// public enum kvpOrderBy { /// /// Ordinamento ASCending per KEY /// KeyAsc, /// /// Ordinamento DESCending per KEY /// KeyDesc, /// /// Ordinamento ASCending per VAL /// ValAsc, /// /// Ordinamento DESCending per VAL /// ValDesc } #endregion Public Enums #region Public Properties /// /// Nome della variabile AppConf da utilizzare... /// public string ACBH { get { string answ = "AppConf"; try { answ = string.Format("{0}:{1}:{2}:AppConf", confReadString("CodModulo"), taConfig.Connection.DataSource, taConfig.Connection.Database).Replace("\\", "_"); } catch { } return answ; } } /// /// Oggetto DB REDIS corrente /// public IDatabase cache //currDB { get { IDatabase answ; // se già valorizzato uso oggetto private... if (_currDB != null) { answ = _currDB; } else { // init DB (sullo 0) answ = connRedis.GetDatabase(); // gestione override... if (confReadInt("redisDb") >= 0) { // in questo caso uso il DB configurato in app.config... answ = connRedis.GetDatabase(confReadInt("redisDb")); } _currDB = answ; } // restituisco oggetto DB return answ; } } /// /// Indica se usare la cache su REDIS (true) oppure cache applicativo IIS (false) /// public bool cacheOnRedis { get { bool answ = confReadBool("cacheOnRedis"); return answ; } } /// /// Nome della variabile x indicare che si sta facendo refresh della appConf... /// public string CleaningKey { get { string answ = "RunningACCleaning"; try { answ = string.Format("{0}:{1}:{2}:RunningACCleaning", confReadString("CodModulo"), taConfig.Connection.DataSource, taConfig.Connection.Database).Replace("\\", "_"); } catch { } return answ; } } /// /// Oggetto statico connessione redis /// public ConnectionMultiplexer connRedis { get { return lazyConnection.Value; } } /// /// Oggetto statico connessione redis /// public ConnectionMultiplexer connRedisAdmin { get { return lazyConnectionAdmin.Value; } } /// /// Numero record salvati in AppConf /// public int numRecAppConf { get { int answ = 0; try { answ = AppConf.Count; } catch { } return answ; } } /// /// Restituisce numero record in Redis DB /// public long numRecRedis { get { long answ = 0; try { foreach (var ep in connRedis.GetEndPoints()) { var server = connRedis.GetServer(ep); answ += server.DatabaseSize(); } } catch { } return answ; } } /// /// Verifica se si debba serializzare ogni valore complesso (tabelle/righe) in sessione (per /// impiego di sessioni avanzate come Redis) /// public bool serializeSession { get { return CRB("serializeSession"); } } /// /// elenco dictionary delle tab in cache da aggiornare con update svuotando da cache... /// public Dictionary tabelleInCache { get { Dictionary answ = new Dictionary(); try { var cacheVal = objCacheObj("tabelleInCache"); if (cacheVal != null) { answ = JsonConvert.DeserializeObject>(cacheVal.ToString()); } } catch (Exception exc) { answ = new Dictionary(); Log.Error(string.Format("Eccezzione in tabelleInCache{0}{1}", Environment.NewLine, exc)); } return answ; } set { string serVal = JsonConvert.SerializeObject(value); setCacheVal("tabelleInCache", serVal); } } /// /// elenco dictionary dei valori in session da NON aggiornare con update... /// public Dictionary valSess2SurvUpd { get { Dictionary answ = new Dictionary(); if (isInSessionObject("valoriInSession2Survive")) { try { answ = (Dictionary)objSessionObj("valoriInSession2Survive"); } catch { answ = new Dictionary(); } } return answ; } set { setSessionVal("valoriInSession2Survive", value); } } #endregion Public Properties #region Public Methods /// /// Formattazione stringa URL immagini con gestione "base url" /// /// /// public static string imgUrl(string urlRelPath) { return string.Format("{0}/{1}", memLayer.ML.CRS("baseUrl"), urlRelPath); } /// /// aggiunge la stringa corrente nel dictionary delle tabelle messe in cache e da aggiornare /// su comando update /// /// public void addTabInCache(string nuovaTab) { // provo ad aggiungere nuova tab in elenco... Dictionary _tabelleInCache = tabelleInCache; try { _tabelleInCache.Add(nuovaTab, nuovaTab); tabelleInCache = _tabelleInCache; } catch { } } /// /// aggiunge la stringa corrente nel dictionary delle tabelle messe in session che vanno /// preservate da comando update (es: oggetto selezionato...) /// /// /// public void addValInSession(string nomePar, string valore) { // provo ad aggiungere nuova tab in elenco... Dictionary _valoriInSession2Survive = valSess2SurvUpd; // verifico se fare update o insert... if (_valoriInSession2Survive.ContainsKey(nomePar)) { // update, rimuovo vecchio valore... try { _valoriInSession2Survive.Remove(nomePar); } catch { } } // insert try { _valoriInSession2Survive.Add(nomePar, valore); valSess2SurvUpd = _valoriInSession2Survive; } catch { } } /// /// carica dalla Cachee un dato di tipo boolean (se vuoto false) /// /// /// public bool BoolCacheObj(string nomeVar) { bool answ = false; // ...se uso redis... if (cacheOnRedis) { string redVal = JsonConvert.DeserializeObject(getRSV(redHash(nomeVar))).ToString(); bool.TryParse(redVal, out answ); } else { if (HttpContext.Current.Cache[nomeVar] != null) { answ = (bool)HttpContext.Current.Cache[nomeVar]; } else { answ = false; } } return answ; } /// /// carica dalla sessione un dato di tipo boolean (se vuoto false) /// /// /// public bool BoolSessionObj(string nomeVar) { if (HttpContext.Current.Session[nomeVar] != null) { return (bool)HttpContext.Current.Session[nomeVar]; } else { return false; } } /// /// Configurations da tabella DB Config (short form wrapper) /// /// Valore chiave /// public string cdv(string chiave) { return configDbVal(chiave); } /// /// Configurations da tabella DB Config (short form wrapper) convertito a bOOL /// /// Valore chiave /// public bool cdvb(string chiave) { bool answ = false; string sVal = configDbVal(chiave); if (sVal != "") { try { //answ = Convert.ToBoolean(configDbVal(chiave)); bool fatto = bool.TryParse(sVal, out answ); if (!fatto) { Log.Error($"Errore in lettura chiave [{chiave}] durante cdvb: ricevuto {sVal}"); } } catch (Exception exc) { Log.Error($"Eccezzione in lettura chiave [{chiave}] durante cdvb{Environment.NewLine}{exc}"); } } return answ; } /// /// Configurations da tabella DB Config (short form wrapper) convertito a INT /// /// Valore chiave /// public int cdvi(string chiave) { int answ = -1; string sVal = configDbVal(chiave); if (sVal != "") { try { //answ = Convert.ToInt32(configDbVal(chiave)); bool fatto = int.TryParse(sVal, out answ); if (!fatto) { Log.Error($"Errore in lettura chiave [{chiave}] durante cdvi: ricevuto {sVal}"); } } catch (Exception exc) { Log.Error($"Eccezzione in lettura chiave [{chiave}] durante cdvi{Environment.NewLine}{exc}"); } } return answ; } /// /// Effettua comaprazione x VALORE in KVP ASC /// /// /// /// public int CompareVal(KeyValuePair x, KeyValuePair y) { return x.Value.CompareTo(y.Value); } /// /// Effettua comaprazione x VALORE in KVP DESC /// /// /// /// public int CompareValDesc(KeyValuePair x, KeyValuePair y) { return y.Value.CompareTo(x.Value); } /// /// Configurations da tabella DB Config /// /// Valore chiave /// public string configDbVal(string chiave) { string answ = ""; bool cacheReloaded = false; if (confReadString("DbConfConnectionString") != "") { // verifico esista oggetto... if (AppConf == null) { resetAppConf(); cacheReloaded = true; } if (AppConf != null) { // controllo se ho dati, altrimenti rileggo if (AppConf.Count == 0) { resetAppConf(); cacheReloaded = true; } // controllo SE in redis ci sia ancora il valore, altrimenti rileggo... if (!cacheReloaded && DateTime.Now > vetoCacheCheck && !redKeyPresent(ACBH)) { Log.Info($"Manca HASH in redis --> rileggo da DB --> REDIS --> Memoria | {ACBH} | {chiave}"); resetAppConf(); } // provo a leggere da DICT if (AppConf.ContainsKey(chiave)) { try { answ = AppConf[chiave]; } catch (Exception exc) { Log.Error($"Errore in lettura AppConf[{chiave}] durante configDbVal{Environment.NewLine}{exc}"); } } } } return answ; } /// /// legge dalla config un valore bool /// /// /// public bool confReadBool(string nomeParam) { bool answ = false; try { answ = (bool)configAppSetReader.GetValue(nomeParam, typeof(bool)); } catch { } return answ; } /// /// legge dalla config un valore int /// /// /// public double confReadDouble(string nomeParam) { double answ = -1; try { answ = Convert.ToDouble(configAppSetReader.GetValue(nomeParam, typeof(double))); } catch { } return answ; } /// /// legge dalla config un valore int /// /// /// public int confReadInt(string nomeParam) { int answ = -1; try { answ = (int)configAppSetReader.GetValue(nomeParam, typeof(int)); } catch { } return answ; } /// /// legge dalla config un valore string /// /// /// public string confReadString(string nomeParam) { string answ = ""; try { answ = (string)configAppSetReader.GetValue(nomeParam, typeof(string)); } catch { } return answ; } /// /// shot-form di confReadBool: legge dalla config un valore bool /// /// /// public bool CRB(string nomeParam) { bool answ = false; // PROVO IN PRIMIS a cercare su DB... if (cdv(nomeParam) != "") { answ = cdvb(nomeParam); } else { answ = confReadBool(nomeParam); } return answ; } /// /// shot-form di confReadDouble: legge dalla config un valore double /// /// /// public double CRD(string nomeParam) { double answ = -1; // PROVO IN PRIMIS a cercare su DB... try { answ = Convert.ToDouble(cdv(nomeParam)); } catch { } // se non trovato... if (answ < 0) { answ = confReadDouble(nomeParam); } return answ; } /// /// shot-form di confReadInt: legge dalla config un valore int /// /// /// public int CRI(string nomeParam) { int answ = -1; // PROVO IN PRIMIS a cercare su DB... answ = cdvi(nomeParam); // se non trovato... if (answ < 0) { answ = confReadInt(nomeParam); } return answ; } /// /// shot-form di confReadString: legge dalla config un valore string /// /// /// public string CRS(string nomeParam) { string answ = ""; // PROVO IN PRIMIS a cercare su DB... answ = cdv(nomeParam); if (string.IsNullOrEmpty(answ)) { answ = confReadString(nomeParam); } return answ; } /// /// carica dalla sessione un dato di tipo DateTime /// /// /// public DateTime DateTimeSessionObj(string nomeVar) { DateTime answ = DateTime.Now; // se li ho in sessione ricarico valori... if (HttpContext.Current.Session[nomeVar] != null) { try { answ = Convert.ToDateTime(memLayer.ML.objSessionObj(nomeVar)); } catch { answ = DateTime.Now; } } return answ; } /// /// Deserializzazione di un valore string in oggetto generico /// /// /// public object deserializeVal(string serVal) { object answ = ""; try { answ = JsonConvert.DeserializeObject(serVal); } catch { } return answ; } /// /// carica dalla sessione un dato di tipo DataSet NON Tipizzato /// /// /// public DataSet dsSessionObj(string nomeVar) { if (HttpContext.Current.Session[nomeVar] != null) { string valSer = ML.StringSessionObj(nomeVar); DataSet dataSet = JsonConvert.DeserializeObject(valSer); return dataSet; } else { return null; } } /// /// svuota una variabile dalla Cache /// /// public bool emptyCacheVal(string nomeVar) { bool _done = false; if (cacheOnRedis) { redDelKey(redHash(nomeVar)); } else { try { HttpContext.Current.Cache.Remove(nomeVar); _done = true; } catch { } } return _done; } /// /// elimina un cookie /// /// public bool emptyCookieVal(string nome) { bool _done = false; HttpCookie aCookie; try { aCookie = new HttpCookie(nome); aCookie.Expires = DateTime.Now.AddDays(-1); HttpContext.Current.Response.Cookies.Add(aCookie); _done = true; } catch { } return _done; } /// /// svuota una variabile dalla session /// /// public bool emptySessionVal(string nome) { bool _done = false; try { HttpContext.Current.Session.Remove(nome); _done = true; } catch { } return _done; } /// /// forza lo svuotamento delle tabelle indicate come in cache... /// public void flushRegisteredCache() { // elimino tutte le tab nella pos tabInCache... foreach (KeyValuePair kvp in tabelleInCache) { if (cacheOnRedis) { redDelKey(redHash(kvp.Value)); } else { HttpContext.Current.Cache.Remove(kvp.Value); } } if (cacheOnRedis) { redDelKey(redHash("tabelleInCache")); } else { HttpContext.Current.Cache.Remove("tabelleInCache"); } } /// /// restituisco un valore da cookie /// /// /// public string getCookieVal(string nome) { string answ = ""; if (hasCookieVal(nome)) { try { answ = HttpContext.Current.Request.Cookies[nome].Value; } catch { } } return answ; } /// /// Restituisce oggetto DB richiesto /// /// /// public IMongoDatabase getMongoDatabase(string dbName) { IMongoDatabase answ = currMongoClient.GetDatabase(dbName); return answ; } /// /// Restituisce una chiave COUNTER in RedisCache /// /// /// public int getRCnt(string chiave) { int answInt = 0; string answ = ""; try { answ = cache.StringGet(chiave); answInt = Convert.ToInt32(answ); } catch (Exception exc) { Log.Error($"Errore in getRSV:{Environment.NewLine}{exc}"); } return answInt; } /// /// Restituisce un pò di info sul server redis connesso /// /// public string getRedisInfoData() { string answ = ""; StringBuilder sb = new StringBuilder(); try { sb.AppendLine($"Configuration: {connRedis.Configuration}"); sb.AppendLine($"Connected: {connRedis.IsConnected}"); sb.AppendLine($"ClientName: {connRedis.ClientName}"); sb.AppendLine($"Total Ops: {connRedis.OperationCount}"); sb.AppendLine($"Status: {connRedis.GetStatus()}"); answ = sb.ToString(); } catch { } return answ; } /// /// Restituisce un set KVP (Key Value Pair) salvati in RedisCache /// /// /// public RedisValue[] getRKeys(RedisKey[] chiavi) { RedisValue[] answ = null; try { answ = cache.StringGet(chiavi); } catch (Exception exc) { Log.Error($"Errore in getRKeys:{Environment.NewLine}{exc}"); } return answ; } /// /// Restituisce una chiave salvata in RedisCache /// /// /// public string getRSV(string chiave) { string answ = ""; try { answ = cache.StringGet(chiave); } catch (Exception exc) { Log.Error($"Eccezione in getRSV:{Environment.NewLine}{exc}"); } return answ; } /// /// restituisco se ci sia un dato cookie /// /// /// public bool hasCookieVal(string nome) { bool answ = false; if (HttpContext.Current.Request.Cookies[nome] != null) { try { answ = HttpContext.Current.Request.Cookies[nome].Value != ""; } catch (Exception exc) { Log.Error($"Errore in hasCookieVal:{Environment.NewLine}{exc}"); } } return answ; } /// /// carica dalla sessione un dato di tipo int /// /// /// public int IntSessionObj(string nomeVar) { if (HttpContext.Current.Session[nomeVar] != null) { return Convert.ToInt32(HttpContext.Current.Session[nomeVar].ToString()); } else { return -1; } } /// /// restituisce true se sia presente in cache l'oggetto richiesto /// /// /// public bool isInCacheObject(string nomeVar) { bool answ = false; bool stringAnsw = false; if (cacheOnRedis) { try { // cerco come key... var redVal = getRSV(redHash(nomeVar)); answ = !string.IsNullOrEmpty(redVal); if (!answ) { answ = redKeyPresent(redHash(nomeVar)); // cerco come variabile se NON trovata... if (!answ) { // cerco come hash... answ = redHashPresent(redHash(nomeVar)); } } #if false // cerco come key... answ = redKeyPresent(redHash(nomeVar)); if (!answ) { // cerco come hash... answ = redHashPresent(redHash(nomeVar)); } // cerco come variabile se NON trovata... if (!answ) { var redVal = getRSV(redHash(nomeVar)); answ = !string.IsNullOrEmpty(redVal); } #endif } catch (Exception exc) { Log.Error($"Errore in verifica isInCacheObject REDIS per chiave{nomeVar}{Environment.NewLine}{exc}"); } } else { // cerco di fare cast a stringa... try { stringAnsw = HttpContext.Current.Cache[nomeVar].ToString() != ""; } catch (Exception exc) { Log.Error($"Errore in verifica HttpContext.Current.Cache per chiave{nomeVar}{Environment.NewLine}{exc}"); } // infine condizione doppia... try { answ = (HttpContext.Current.Cache[nomeVar] != null && stringAnsw); } catch (Exception exc) { Log.Error($"Errore in verifica NULL per HttpContext.Current.Cache per chiave{nomeVar}{Environment.NewLine}{exc}"); } } return answ; } /// /// restituisce true se sia presente in session l'oggetto richiesto /// /// /// public bool isInSessionObject(string nomeVar) { bool answ = false; bool stringAnsw = false; // cerco se ci sia... try { //stringAnsw = (string)HttpContext.Current.Session[nomeVar].ToString() != ""; stringAnsw = HttpContext.Current.Session[nomeVar] != null; } catch (Exception exc) { Log.Error($"Errore 01 | isInSessionObject:{Environment.NewLine}{exc}"); } // infine condizione doppia... try { answ = (HttpContext.Current.Session[nomeVar] != null && stringAnsw); } catch (Exception exc) { Log.Error($"Errore 02 | isInSessionObject:{Environment.NewLine}{exc}"); } return answ; } /// /// carica dalla sessione un dato di tipo long /// /// /// public long LongSessionObj(string nomeVar) { if (HttpContext.Current.Session[nomeVar] != null) { return Convert.ToInt32(HttpContext.Current.Session[nomeVar].ToString()); } else { return 0; } } /// /// carica dalla Cache un dato di tipo object generico /// /// /// public object objCacheObj(string nomeVar) { object answ = null; // ...se uso redis... if (cacheOnRedis) { answ = getRSV(redHash(nomeVar)); } else { if (HttpContext.Current.Cache[nomeVar] != null) { answ = HttpContext.Current.Cache[nomeVar]; } else { answ = ""; } } return answ; } /// /// carica dalla sessione un dato di tipo object generico /// /// /// public object objSessionObj(string nomeVar) { if (HttpContext.Current.Session[nomeVar] != null) { return HttpContext.Current.Session[nomeVar]; } else { return ""; } } /// /// recupera valore querystring BOOL /// /// /// valore string public bool QSB(string nome) { bool answ = false; try { answ = Convert.ToBoolean(HttpContext.Current.Request.QueryString[nome]); } catch (Exception exc) { Log.Error($"Errore in QSB:{Environment.NewLine}{exc}"); } return answ; } /// /// recupera valore querystring DATE /// /// /// valore DATE public DateTime QSD(string nome) { DateTime answ = DateTime.Now; try { answ = Convert.ToDateTime(HttpContext.Current.Request.QueryString[nome]); } catch (Exception exc) { Log.Error($"Errore in QSD:{Environment.NewLine}{exc}"); } return answ; } /// /// recupera valore querystring INT /// /// /// valore INT public int QSI(string nome) { int answ = 0; try { answ = Convert.ToInt32(HttpContext.Current.Request.QueryString[nome]); } catch (Exception exc) { Log.Error($"Errore in QSI:{Environment.NewLine}{exc}"); } return answ; } /// /// recupera valore querystring STRING /// /// /// valore string public string QSS(string nome) { string answ = ""; if (HttpContext.Current.Request.QueryString[nome] != null) { try { answ = HttpContext.Current.Request.QueryString[nome].ToString().Trim(); } catch (Exception exc) { Log.Error($"Errore in QSS:{Environment.NewLine}{exc}"); } } return answ; } /// /// Conta num oggetti cache redis che rispondono a pattern /// /// ** = tutti /// public int redCountKey(string keyPattern) { int answ = 0; // cerco se ci sia valore in redis... se vuoto = ALL... keyPattern = string.IsNullOrEmpty(keyPattern) ? "**" : keyPattern; try { foreach (var ep in connRedis.GetEndPoints()) { var server = connRedis.GetServer(ep); foreach (var key in server.Keys(pattern: keyPattern, database: _currDB.Database)) { answ++; } } } catch (Exception exc) { Log.Error($"Eccezione in redCountKey:{Environment.NewLine}{exc}"); } return answ; } /// /// ELIMINA un SINGOLO VALORE dalla hash (dato field = chiave) /// /// /// /// public bool redDelHashField(string hashKey, string hashField) { bool answ = false; // cerco se ci sia valore in redis... try { RedisKey chiave = hashKey; RedisValue campo = hashField; answ = cache.HashDelete(chiave, campo); } catch (Exception exc) { Log.Error($"Errore in redDelHashField{Environment.NewLine}{exc}"); } return answ; } /// /// Elimina una key (hash, string) /// /// /// public bool redDelKey(string key) { bool answ = false; // cerco se ci sia valore in redis... try { RedisKey chiave = key; cache.KeyDelete(chiave); answ = true; } catch (Exception exc) { Log.Error($"Errore in redDelKey:{Environment.NewLine}{exc}"); } return answ; } /// /// Flush completo cache redis /// /// ** = tutti /// public bool redFlushKey(string keyPattern) { bool answ = false; // cerco se ci sia valore in redis... se vuoto = ALL... keyPattern = string.IsNullOrEmpty(keyPattern) ? "**" : keyPattern; try { foreach (var ep in connRedis.GetEndPoints()) { var server = connRedis.GetServer(ep); var keys = server.Keys(database: confReadInt("redisDb"), pattern: $"{keyPattern}*"); foreach (var key in keys) { cache.KeyDelete(key); } } answ = true; } catch (Exception exc) { Log.Error($"Eccezione in redFlushKey{Environment.NewLine}{exc}"); } return answ; } /// /// Restituisce oggetti cache redis che rispondono a pattern /// /// ** = tutti /// Tipo di ordinamento per kvp /// public List> redGetCounterByKey(string keyPattern, kvpOrderBy orderBy) { int numAnsw = redCountKey(keyPattern); RedisKey[] chiavi = new RedisKey[numAnsw]; List> answ = new List>(); // se vuoto = ALL... keyPattern = string.IsNullOrEmpty(keyPattern) ? "**" : keyPattern; // recupero in primis elenco chiavi try { int i = 0; foreach (var ep in connRedis.GetEndPoints()) { var server = connRedis.GetServer(ep); foreach (var key in server.Keys(pattern: keyPattern)) { chiavi[i] = key; i++; } } } catch (Exception exc) { Log.Error($"Eccezione in redGetCounterByKey{Environment.NewLine}{exc}"); } // ora recupero valori! var valori = getRKeys(chiavi); int currVal = 0; // popolo rispsota try { for (int i = 0; i < numAnsw; i++) { Int32.TryParse(valori[i], out currVal); answ.Add(new KeyValuePair(chiavi[i], currVal)); } } catch (Exception exc) { Log.Error($"Errore in redGetCounterByKey 02{Environment.NewLine}{exc}"); } // se richiesto riordino... switch (orderBy) { case kvpOrderBy.KeyAsc: answ.Sort(CompareKey); break; case kvpOrderBy.KeyDesc: answ.Sort(CompareKeyDesc); break; case kvpOrderBy.ValAsc: answ.Sort(CompareVal); break; case kvpOrderBy.ValDesc: answ.Sort(CompareValDesc); break; default: break; } return answ; } /// /// Recupera tutti i valori dalla hash /// /// /// public KeyValuePair[] redGetHash(string hashKey) { KeyValuePair[] answ = new KeyValuePair[1]; // cerco se ci sia valore in redis... try { RedisKey chiave = hashKey; HashEntry[] valori = cache.HashGetAll(chiave); answ = new KeyValuePair[valori.Length]; int i = 0; foreach (HashEntry item in valori) { answ[i] = new KeyValuePair(item.Name, item.Value); i++; } } catch (Exception exc) { Log.Error($"Errore in redGetHash{Environment.NewLine}{exc}"); } return answ; } /// /// Recupera tutti i valori dalla hash in formato Dictionary /// /// /// public Dictionary redGetHashDict(string hashKey) { Dictionary answ = new Dictionary(); // cerco se ci sia valore in redis... try { RedisKey chiave = hashKey; HashEntry[] valori = cache.HashGetAll(chiave); foreach (HashEntry item in valori) { answ.Add(item.Name, item.Value); } } catch (Exception exc) { Log.Error($"Errore in redGetHashDict{Environment.NewLine}{exc}"); } return answ; } /// /// Recupera UN SINGOLO VALORE dalla hash per un dato field /// /// /// /// public string redGetHashField(string hashKey, string hashField) { string answ = ""; // cerco se ci sia valore in redis... try { RedisKey chiave = hashKey; RedisValue campo = hashField; RedisValue valOut = cache.HashGet(chiave, campo); answ = valOut.ToString(); } catch (Exception exc) { Log.Error($"Errore in redGetHashField{Environment.NewLine}{exc}"); } return answ; } /// /// Elenco oggetti cache redis che rispondono a pattern /// /// ** = tutti /// public List redGetKeys(string keyPattern) { List answ = new List(); // cerco se ci sia valore in redis... se vuoto = ALL... keyPattern = string.IsNullOrEmpty(keyPattern) ? "**" : keyPattern; try { foreach (var ep in connRedis.GetEndPoints()) { var server = connRedis.GetServer(ep); foreach (var key in server.Keys(pattern: keyPattern, database: _currDB.Database)) { answ.Add(key); } } } catch (Exception exc) { Log.Error($"Errore in redGetKeys{Environment.NewLine}{exc}"); } return answ; } /// /// Nome della variabile HASH da utilizzare (dato CodModulo / Server / DB impiegato da /// funzionalita' DbConfig) + keyName richiesto... /// public string redHash(string keyName) { string answ = keyName; try { answ = string.Format("{0}:{1}:{2}:{3}", confReadString("CodModulo"), taConfig.Connection.DataSource, taConfig.Connection.Database, keyName).Replace("\\", "_"); } catch (Exception exc) { Log.Error($"Errore in redHash{Environment.NewLine}{exc}"); } return answ; } /// /// Verifica se ci siano valori nella hash indicata... /// /// /// public bool redHashPresent(RedisKey key) { bool answ = false; // cerco se ci sia valore in redis... try { answ = cache.HashGetAll(key).Length > 0; } catch (Exception exc) { Log.Error($"Errore in redHashPresent | {key}{Environment.NewLine}{exc}"); } return answ; } /// /// Verifica se ci siano valori nella hash indicata (string) /// /// /// public bool redHashPresentSz(string key) { bool answ = false; try { RedisKey chiave = key; answ = redHashPresent(chiave); } catch (Exception exc) { Log.Error($"Errore in redHashPresentSz | {key}{Environment.NewLine}{exc}"); } return answ; } /// /// Verifica se ci siano valori nella KEY indicata... /// /// /// public bool redKeyPresent(RedisKey key) { bool answ = false; // cerco se ci sia valore in redis... try { answ = cache.KeyExists(key); } catch (Exception exc) { Log.Error($"Errore in redKeyPresent | RedisKey: {key}{Environment.NewLine}{exc}"); } return answ; } /// /// Verifica se ci siano valori nella KEY indicata (string) /// /// /// public bool redKeyPresentSz(string key) { bool answ = false; try { RedisKey chiave = key; answ = redKeyPresent(chiave); } catch (Exception exc) { Log.Error($"Errore in redKeyPresentSz | {key}{Environment.NewLine}{exc}"); } return answ; } /// /// Salvataggio di una hash di valori /// /// chiave /// valori /// public bool redSaveHash(string hashKey, KeyValuePair[] hashFields) { bool answ = false; // cerco se ci sia valore in redis... try { RedisKey chiave = hashKey; HashEntry[] valori = new HashEntry[hashFields.Length]; int i = 0; foreach (KeyValuePair kvp in hashFields) { valori[i] = new HashEntry(kvp.Key, kvp.Value); i++; } cache.HashSet(chiave, valori); answ = true; } catch (Exception exc) { Log.Error($"Errore in redSaveHash{Environment.NewLine}{exc}"); } return answ; } /// /// Salvataggio di una hash di valori /// /// chiave /// valori /// /// scadenza preimpostata hash (secondi) | defaoult = -1 (non scade) /// /// public bool redSaveHash(string hashKey, KeyValuePair[] hashFields, double expireSeconds = -1) { bool answ = false; // cerco se ci sia valore in redis... try { RedisKey chiave = hashKey; answ = redSaveHash(hashKey, hashFields); if (expireSeconds > 0) { cache.KeyExpire(chiave, DateTime.Now.AddSeconds(expireSeconds)); } //answ = true; } catch (Exception exc) { Log.Error($"Errore in redSaveHash | {hashKey}{Environment.NewLine}{exc}"); } return answ; } /// /// Salvataggio di una hash di valori in formato Dictionary /// /// chiave /// valori /// public bool redSaveHashDict(string hashKey, Dictionary hashFields) { bool answ = false; // cerco se ci sia valore in redis... try { RedisKey chiave = hashKey; HashEntry[] valori = new HashEntry[hashFields.Count]; int i = 0; foreach (KeyValuePair kvp in hashFields) { valori[i] = new HashEntry(kvp.Key, kvp.Value); i++; } cache.HashSet(chiave, valori); answ = true; } catch (Exception exc) { Log.Error($"Errore in redSaveHashDict | {hashKey}{Environment.NewLine}{exc}"); } return answ; } /// /// Salvataggio di una hash di valori in formato Dictionary /// /// chiave /// valori /// /// scadenza preimpostata hash (secondi) | defaoult = -1 (non scade) /// /// public bool redSaveHashDict(string hashKey, Dictionary hashFields, double expireSeconds = -1) { bool answ = false; // cerco se ci sia valore in redis... try { RedisKey chiave = hashKey; answ = redSaveHashDict(hashKey, hashFields); if (expireSeconds > 0) { cache.KeyExpire(chiave, DateTime.Now.AddSeconds(expireSeconds)); } //answ = true; } catch { } return answ; } /// /// Salvataggio di una hash di valori /// /// chiave /// valori come lista KVP /// public bool redSaveHashList(string hashKey, List> hashListKVP) { bool answ = false; if (connRedis.IsConnected) { // cerco se ci sia valore in redis... IDatabase cache = connRedis.GetDatabase(); try { RedisKey chiave = hashKey; HashEntry[] valori = new HashEntry[hashListKVP.Count]; int i = 0; foreach (KeyValuePair kvp in hashListKVP) { valori[i] = new HashEntry(kvp.Key, kvp.Value); i++; } cache.HashSet(chiave, valori); answ = true; } catch { } } return answ; } /// /// Restituisce info dei server connessi... /// /// public IServer[] redServInfo() { IServer[] answ = new IServer[1]; try { answ = new IServer[connRedisAdmin.GetEndPoints().Length]; int i = 0; foreach (var ep in connRedisAdmin.GetEndPoints()) { var server = connRedisAdmin.GetServer(ep); answ[i] = server; i++; } } catch (Exception exc) { Log.Error($"redServInfo:{Environment.NewLine}{exc}"); } return answ; } /// /// resetta AppConfig svuotando e rileggendo i dati... /// public void resetAppConf() { redDelKey(ACBH); startupAppConf(); } /// /// Resetta (elimina) un contatore in Redis /// /// /// public bool resetRCnt(string chiave) { bool answ = false; try { answ = cache.KeyDelete(chiave); } catch (Exception exc) { Log.Error(string.Format("Eccezione in resetRCnt:{0}{1}", Environment.NewLine, exc)); } return answ; } /// /// Serializzazione di un oggetto generico /// /// /// public string serializeVal(object origVal) { string answ = ""; try { answ = JsonConvert.SerializeObject(origVal); } catch { } return answ; } /// /// inserisce in Cache un valore /// /// nome della variabile /// valore public bool setCacheVal(string nomeVar, object valore) { bool _done = false; if (cacheOnRedis) { setRSV(redHash(nomeVar), valore.ToString()); _done = true; } else { try { HttpContext.Current.Cache[nomeVar] = valore; _done = true; } catch { } } return _done; } /// /// inserisce in Cache un valore e su richiesta regitra tra le tab in cache da svuotare on update.. /// /// nome della variabile /// valore /// da registrare come tabella da svuotare on update /// public bool setCacheVal(string nome, object valore, bool setInTabInCache) { bool _done = setCacheVal(nome, valore); if (setInTabInCache) { addTabInCache(nome); } return _done; } /// /// salvo un valore come cookie /// /// /// /// public bool setCookieVal(string nome, string valore) { bool _done = false; try { HttpCookie newCookie = new HttpCookie(nome, valore); HttpContext.Current.Response.AppendCookie(newCookie); _done = true; } catch { } return _done; } /// /// salvo un valore come cookie con expiry date esplicita /// /// /// /// /// public bool setCookieVal(string nome, string valore, DateTime expiryDate) { bool _done = false; try { // rimuovo vecchio cookie emptyCookieVal(nome); // creo nuovo cookie HttpCookie newCookie = new HttpCookie(nome, valore); newCookie.Expires = expiryDate; HttpContext.Current.Response.AppendCookie(newCookie); _done = true; } catch { } return _done; } /// /// Decrementa un contatore in Redis /// /// /// public long setRCntD(string chiave) { long answ = 0; try { answ = cache.StringDecrement(chiave, 1); } catch (Exception exc) { Log.Error(string.Format("Eccezzione in setRCD:{0}{1}", Environment.NewLine, exc)); } return answ; } /// /// Incrementa un contatore in Redis /// /// /// public long setRCntI(string chiave) { long answ = 0; try { answ = cache.StringIncrement(chiave, 1); } catch (Exception exc) { Log.Error(string.Format("Eccezzione in setRCI:{0}{1}", Environment.NewLine, exc)); } return answ; } /// /// Salva un set KVP (Key Value Pair) in RedisCache /// /// Set KVP chiave-valore da salvare /// public bool setRKeys(KeyValuePair[] valori) { bool answ = false; try { cache.StringSet(valori); answ = true; } catch (Exception exc) { Log.Error(string.Format("Eccezione in setRKeys:{0}{1}", Environment.NewLine, exc)); } return answ; } /// /// Salva una chiave in RedisCache /// /// /// /// public bool setRSV(string chiave, string valore) { bool answ = false; if (!string.IsNullOrEmpty(chiave)) { try { cache.StringSet(chiave, valore); answ = true; } catch (Exception exc) { Log.Error(string.Format("Eccezzione in setRSV:{0}{1}", Environment.NewLine, exc)); } } else { Log.Error("Errore: chiave non valida (vuota) in setRSV"); } return answ; } /// /// Salva una chiave in RedisCache /// /// /// /// in secondi /// public bool setRSV(string chiave, string valore, int TTL_sec = 5) { bool answ = false; try { TimeSpan expT = new TimeSpan(0, 0, TTL_sec); // salvo con expyry... cache.StringSet(chiave, valore, expT); answ = true; } catch (Exception exc) { Log.Error(string.Format("Eccezzione in setRSV:{0}{1}", Environment.NewLine, exc)); } return answ; } /// /// inserisce in session un DataSet (serializzandolo) /// /// nome della variabile /// DataSet da salvare public bool setSessionDataSet(string nome, DataSet dSet) { bool _done = false; try { string dataSer = JsonConvert.SerializeObject(dSet); _done = setSessionVal(nome, dataSer); } catch { } return _done; } /// /// inserisce in session un DataSet (serializzandolo) /// /// nome della variabile /// DataSet da salvare /// /// indica se debba sopravvivere ad update (inserita in elenco valSess2SurvUpd) /// /// public bool setSessionDataSet(string nome, DataSet dSet, bool surviveUpdate) { bool _done = false; try { string dataSer = JsonConvert.SerializeObject(dSet); _done = setSessionVal(nome, dataSer, surviveUpdate); } catch { } return _done; } /// /// inserisce in session un DataSet (serializzandolo) /// /// nome della variabile /// DataTable da salvare public bool setSessionDataTable(string nome, DataTable dTable) { bool _done = false; try { DataSet dataSet = new DataSet("dataSet"); dataSet.Tables.Add(dTable); string dataSer = JsonConvert.SerializeObject(dataSet); _done = setSessionVal(nome, dataSer); } catch { } return _done; } /// /// inserisce in session un DataSet (serializzandolo) /// /// nome della variabile /// DataTable da salvare /// /// indica se debba sopravvivere ad update (inserita in elenco valSess2SurvUpd) /// public bool setSessionDataTable(string nome, DataTable dTable, bool surviveUpdate) { bool _done = false; try { DataSet dataSet = new DataSet("dataSet"); dataSet.Tables.Add(dTable); string dataSer = JsonConvert.SerializeObject(dataSet); _done = setSessionVal(nome, dataSer, surviveUpdate); } catch { } return _done; } /// /// inserisce in session un valore /// /// /// public bool setSessionVal(string nome, object valore) { bool _done = false; try { HttpContext.Current.Session[nome] = valore; _done = true; } catch { } return _done; } /// /// inserisce in session un valore /// /// nome della variabile /// valore associato /// /// indica se debba sopravvivere ad update (inserita in elenco valSess2SurvUpd) /// /// public bool setSessionVal(string nome, object valore, bool surviveUpdate) { bool _done = false; try { HttpContext.Current.Session[nome] = valore; if (surviveUpdate) { addValInSession(nome, valore.ToString()); } _done = true; } catch { } return _done; } /// /// carica dalla Cachee un dato di tipo string /// /// /// public string StringCacheObj(string nomeVar) { string answ = ""; // ...se uso redis... if (cacheOnRedis) { answ = JsonConvert.DeserializeObject(getRSV(redHash(nomeVar))).ToString(); } else { if (HttpContext.Current.Cache[nomeVar] != null) { answ = HttpContext.Current.Cache[nomeVar].ToString(); } else { answ = ""; } } return answ; } /// /// carica dalla sessione un dato di tipo string /// /// /// public string StringSessionObj(string nomeVar) { string answ = ""; try { if (HttpContext.Current.Session[nomeVar] != null) { answ = HttpContext.Current.Session[nomeVar].ToString(); } } catch { } return answ; } /// /// Aggiornamento di una chiave in tabella config /// /// /// public void updateAppConf(string chiave, string valore) { // recupero valore attuale... memLayer nML = new memLayer(); nML.taConfig.updateQuery(chiave, valore); resetAppConf(); } #endregion Public Methods #region Protected Fields /// /// lettore file configurazione /// protected AppSettingsReader configAppSetReader; /// /// Oggetto MongoDbCLient x accesso al motore /// protected MongoClient currMongoClient; #endregion Protected Fields #region Protected Properties /// /// stringa conn x DB CONF /// protected string connStringDbConf { get { string answ = ""; answ = confReadString("DbConfConnectionString"); // se fosse vuota fallback a path dei permessi... if (string.IsNullOrEmpty(answ)) { answ = confReadString("PermessiConnectionString"); } // se ancora vuota --> devAuth if (string.IsNullOrEmpty(answ)) { answ = confReadString("DevicesAuthConnectionString"); } return answ; } } /// /// Stringa di connessione mongoDb /// protected string mongoConnString { get { string answ = ""; answ = confReadString("mdbConnString"); if (string.IsNullOrEmpty(answ)) { answ = "mongodb://W2019-MONGODB:27017"; } return answ; } } #endregion Protected Properties #region Protected Methods /// /// init dei table adapters /// protected void initTA() { taConfig = new DS_UtilityTableAdapters.ConfigTableAdapter(); taConfigTmp = new DS_UtilityTableAdapters.ConfigTmpTableAdapter(); } /// /// carica in ram oggetto AppConf /// /// protected Dictionary ricaricaAppConf() { Dictionary answ = new Dictionary(); // istanzio un NUOVO oggetto x evitare problemi init contestuali memLayer nML = new memLayer(); DS_Utility.ConfigDataTable tabDati = null; int waitMs = 100; int numTry = 5; do { try { tabDati = nML.taConfig.GetData(); } catch (Exception exc) { numTry--; Log.Error($"Errore procedura nML.taConfig.GetData(), numTry = {numTry}, now {waitMs}ms wait{Environment.NewLine}{exc}"); Thread.Sleep(waitMs); } } while (numTry > 0 && tabDati == null); if (tabDati != null) { // carico foreach (DS_Utility.ConfigRow riga in tabDati) { try { answ.Add(riga.chiave, riga.valore); } catch (Exception exc) { Log.Error($"Errore procedura ricaricaAppConf per kvp: {riga.chiave} / {riga.valore}{Environment.NewLine}{exc}"); } } // log ricarica Log.Info($"Effettuata procedura ricaricaAppConf per {answ.Count} records"); } return answ; } /// /// effettua setup dei connection strings da web.config delal singola applicazione /// protected virtual void setupConnectionStringBase() { // connections del db taConfig.Connection.ConnectionString = connStringDbConf; taConfigTmp.Connection.ConnectionString = connStringDbConf; } /// /// avvio oggetto AppConf in ram /// protected void startupAppConf() { // SOLO SE ho la chiave x abilitare config su DB... if (confReadString("DbConfConnectionString") != "") { try { if (redKeyPresent(ACBH)) { AppConf = new Dictionary(); foreach (var item in redGetHash(ACBH)) { if (AppConf.ContainsKey(item.Key)) { AppConf[item.Key] = item.Value; } else { AppConf.Add(item.Key, item.Value); } } } else { AppConf = ricaricaAppConf(); if (AppConf.Count > 0) { KeyValuePair[] valori = new KeyValuePair[AppConf.Count]; int i = 0; foreach (var item in AppConf) { valori[i] = new KeyValuePair(item.Key, item.Value); i++; } // salvo in redis valori (con TTL) redSaveHash(ACBH, valori, maxAgeAppConf); // salvo info cache riletta 2 sec prima della scadenza vetoCacheCheck = DateTime.Now.AddSeconds(maxAgeAppConf + 1); Log.Info("Completato procedura startupAppConf"); } else { Log.Error("Errore in procedura startupAppConf, ritornato insieme vuoto"); } } } catch (Exception exc) { Log.Error($"Errore in startupAppConf:{Environment.NewLine}{exc}"); } } } #endregion Protected Methods #region Private Fields private static NLog.Logger Log = LogManager.GetCurrentClassLogger(); /// /// Connessione lazy a redis... /// private Lazy lazyConnection = new Lazy(() => { string RedisConn = memLayer.ML.confReadString("RedisConn"); if (string.IsNullOrEmpty(RedisConn)) { RedisConn = "localhost,abortConnect=false,ssl=false"; } return ConnectionMultiplexer.Connect(RedisConn); }); /// /// Connessione lazy a redis... /// private Lazy lazyConnectionAdmin = new Lazy(() => { string RedisConnAdmin = memLayer.ML.confReadString("RedisConnAdmin"); if (string.IsNullOrEmpty(RedisConnAdmin)) { RedisConnAdmin = "localhost,abortConnect=false,ssl=false,allowAdmin=true"; } return ConnectionMultiplexer.Connect(RedisConnAdmin); }); private DateTime vetoCacheCheck = DateTime.Now; #endregion Private Fields #region Private Properties /// /// Oggetto currentDb locale /// private IDatabase _currDB { get; set; } #endregion Private Properties #region Private Methods /// /// Effettua comaprazione x CHIAVE in KVP ASC /// /// /// /// private int CompareKey(KeyValuePair x, KeyValuePair y) { return x.Key.CompareTo(y.Key); } /// /// Effettua comaprazione x CHIAVE in KVP DESC /// /// /// /// private int CompareKeyDesc(KeyValuePair x, KeyValuePair y) { return y.Key.CompareTo(x.Key); } /// /// Init accesso MongoDb /// private void setupMongo() { currMongoClient = new MongoClient(mongoConnString); } private void setupParams() { // default 5 minuti x refresh... int maxAge = 5; try { maxAge = confReadInt("maxAgeAppConf_min"); } catch (Exception exc) { Log.Error($"Errore in lettura valore maxAgeAppConf_min{Environment.NewLine}{exc}"); } // controllo maxage valida... if (maxAge < 1) { maxAge = 5; } maxAgeAppConf = maxAge * 60; } #endregion Private Methods } }