using GPW.CORE.Data; using GPW.CORE.Data.DbModels; using Newtonsoft.Json; using RestSharp; using StackExchange.Redis; using System.Web; namespace GPW.CORE.Smart.Data { /// /// Servizi e dati condivisi a livello applicazione /// public class LicenseService { #region Public Constructors /// /// Init classe /// /// /// /// public LicenseService(IConfiguration configuration, ILogger logger, IConnectionMultiplexer redisConnMult) { _logger = logger; _configuration = configuration; // Conf cache redisConn = redisConnMult; redisDb = this.redisConn.GetDatabase(); } #endregion Public Constructors #region Public Events public event Action EA_InfoUpdated = null!; #endregion Public Events #region Public Properties public List ActivList { get; set; } = new List(); public List AKVList { get; set; } = new List(); public string Applicazione { get; set; } = ""; public LiManObj.ApplicativoDTO AppLicense { get; set; } = new LiManObj.ApplicativoDTO(); public bool HasActivData { get { bool answ = ValidData; // se ok controllo che ci siano attivazioni if (answ) { // provo classe locale... answ = ActivList != null && ActivList.Count > 0; // se non le avessi carico! if (!answ) { var pUpd = Task.Run(async () => { ActivList = await ActivListCache(); }); pUpd.Wait(); answ = ActivList != null && ActivList.Count > 0; } } return answ; } } public bool HasAppData { get { bool answ = !string.IsNullOrEmpty(AppLicense.CodApp); // se ok controllo che ci siano attivazioni if (!answ) { var pUpd = Task.Run(async () => { AppLicense = await AppLicCache(); }); pUpd.Wait(); answ = !string.IsNullOrEmpty(AppLicense.CodApp); } return answ; } } public DateTime infoExpiry { get; set; } = DateTime.Today.AddDays(1); public string Installazione { get; set; } = ""; public string MasterKey { get; set; } = ""; public bool ValidData { get { // controllo valori string base bool checkData = !string.IsNullOrEmpty(Installazione) && !string.IsNullOrEmpty(Applicazione) && !string.IsNullOrEmpty(MasterKey); return checkData; } } #endregion Public Properties #region Public Methods public async Task> ActivListCache() { List dbResult = new List(); string cacheKey = $"{rKeyAttByLic}:{MasterKey}"; string rawData = await getRSV(cacheKey); if (!string.IsNullOrEmpty(rawData)) { var cacheRes = JsonConvert.DeserializeObject?>(rawData); if (cacheRes != null) { dbResult = cacheRes; } } return await Task.FromResult(dbResult); } public async Task AppLicCache() { LiManObj.ApplicativoDTO dbResult = new LiManObj.ApplicativoDTO(); string cacheKey = $"{rKeyLic}:{MasterKey}"; string rawData = await getRSV(cacheKey); if (!string.IsNullOrEmpty(rawData)) { var cacheRes = JsonConvert.DeserializeObject(rawData); if (cacheRes != null) { dbResult = cacheRes; } } return await Task.FromResult(dbResult); } /// /// Init della classe con variabili di base da Redis/DB /// public bool InitAkv() { bool fatto = false; Installazione = getAVKStr("installazione"); MasterKey = getAVKStr(Installazione); fatto = !string.IsNullOrEmpty($"{Installazione}{MasterKey}"); return fatto; } /// /// Init della classe x licenza applicativo /// public async Task RefreshApplic() { bool fatto = false; if (string.IsNullOrEmpty(AppLicense.CodApp)) { var onlineLic = await OnlineApplicationData(); if (onlineLic != null) { // scadenza info a 15 gg... int numDays = 15; AppLicense = onlineLic; fatto = await setAppLicData(AppLicense, numDays); } } await Task.Delay(1); return fatto; } /// /// Init della classe con variabili di base da Redis/DB /// public async Task RefreshLicense() { bool fatto = false; var onlineAct = await OnlineActivationList(); if (onlineAct != null) { if (onlineAct.Count > 0) { // scadenza info a 15 gg... int numDays = 15; infoExpiry = DateTime.Now.AddDays(numDays); ActivList = onlineAct; fatto = await setActivList(onlineAct, numDays); } } await Task.Delay(1); return fatto; } public async Task setActivList(List newActList, int numDays) { bool fatto = false; string cacheKey = $"{rKeyAttByLic}:{MasterKey}"; var rawData = JsonConvert.SerializeObject(newActList); await setRSV(cacheKey, rawData, numDays * 24); fatto = true; if (EA_InfoUpdated != null) { EA_InfoUpdated?.Invoke(); } return fatto; } public async Task setAppLicData(LiManObj.ApplicativoDTO newAppDto, int numDays) { bool fatto = false; string cacheKey = $"{rKeyLic}:{MasterKey}"; var rawData = JsonConvert.SerializeObject(newAppDto); await setRSV(cacheKey, rawData, numDays * 24); fatto = true; if (EA_InfoUpdated != null) { EA_InfoUpdated?.Invoke(); } return fatto; } #endregion Public Methods #region Protected Fields /// /// Chiave redis x attivazioni della licenza /// protected const string rKeyAttByLic = "LongCache:AttByLic"; /// /// Chiave redis x info licenza /// protected const string rKeyLic = "LongCache:LicData"; protected Random rnd = new Random(); #endregion Protected Fields #region Protected Methods /// /// Cerca di recuperare valore string da elenco AKV /// /// Chiave AKV richiesta /// protected string getAVKStr(string varReq) { string answ = ""; if (AKVList != null && AKVList.Count > 0) { var currRec = AKVList.Where(x => x.NomeVar == varReq).FirstOrDefault(); if (currRec != null) { answ = $"{currRec.ValString}"; } } return answ; } /// /// Recupero chiave da redis /// /// /// protected async Task getRSV(string rKey) { string answ = ""; string? rawData = await redisDb.StringGetAsync(rKey); if (!string.IsNullOrEmpty(rawData)) { answ = rawData; } return answ; } /// /// Salvataggio chiave in redis /// /// /// /// /// protected async Task setRSV(string rKey, string rVal, int cacheMult) { bool fatto = false; fatto = await redisDb.StringSetAsync(rKey, rVal, getCache(cacheMult)); return fatto; } /// /// Salvataggio chiave INT in redis /// /// /// /// /// protected async Task setRSV(string rKey, int rValInt, int cacheMult) { return await setRSV(rKey, $"{rValInt}", cacheMult); } #endregion Protected Methods #region Private Fields private static IConfiguration? _configuration; private static ILogger? _logger; /// /// URL dell'API x chiamate gestione licenze /// private static string apiUrl = "https://liman.egalware.com/ELM.API/"; /// /// Oggetto per connessione a REDIS /// private IConnectionMultiplexer redisConn; //ISubscriber sub = redis.GetSubscriber(); /// /// Oggetto DB redis da impiegare x chiamate R/W /// private IDatabase redisDb = null!; #endregion Private Fields #region Private Methods /// /// Durata cache da moltiplicatore (orario) + perturbazione percentuale (+/-10%) /// private TimeSpan getCache(int cacheMult) { return TimeSpan.FromHours((double)cacheMult * rnd.Next(900, 1100) / 1000); } /// /// Elenco attivazioni attuali /// private async Task?> OnlineActivationList() { List? answ = new List(); // cerco online RestClient client = new RestClient(apiUrl); //client.Authenticator = new HttpBasicAuthenticator("username", "password"); string MKeyEnc = HttpUtility.UrlEncode(MasterKey); var request = new RestRequest($"/api/attivazioni/?chiave={MKeyEnc}", Method.Get); var response = await client.GetAsync(request); // controllo risposta if (response.StatusCode == System.Net.HttpStatusCode.OK) { // salvo in redis contenuto serializzato string rawData = $"{response.Content}"; answ = JsonConvert.DeserializeObject?>(rawData); } return await Task.FromResult(answ); } /// /// Dati Applicativo /// private async Task OnlineApplicationData() { LiManObj.ApplicativoDTO? answ = new LiManObj.ApplicativoDTO(); // cerco online RestClient client = new RestClient(apiUrl); //client.Authenticator = new HttpBasicAuthenticator("username", "password"); string ValEnc = HttpUtility.UrlEncode(Applicazione); var request = new RestRequest($"/api/applicazione/{Installazione}?CodApp={ValEnc}", Method.Get); var response = await client.GetAsync(request); // controllo risposta if (response.StatusCode == System.Net.HttpStatusCode.OK) { // salvo in redis contenuto serializzato string rawData = $"{response.Content}"; var rawList = JsonConvert.DeserializeObject>(rawData); if (rawList != null) { answ = rawList.FirstOrDefault(); } //answ = JsonConvert.DeserializeObject(rawData); } return await Task.FromResult(answ); } private void ReportUpdated() { if (EA_InfoUpdated != null) { EA_InfoUpdated?.Invoke(); } } #endregion Private Methods } }