using GPW.CORE.Data;
using GPW.CORE.Data.DbModels;
using Microsoft.Extensions.Caching.Distributed;
using Newtonsoft.Json;
using RestSharp;
using System.Diagnostics;
using System.Text;
using System.Web;
namespace GPW.CORE.UI.Data
{
///
/// Servizi e dati condivisi a livello applicazione
///
public class LicenseService
{
#region Private Fields
private static ILogger _logger;
private static IConfiguration _configuration;
private readonly IDistributedCache distributedCache;
///
/// Chiave redis x attivazioni della licenza
///
protected const string rKeyAttByLic = "LongCache:AttByLic";
///
/// Durata assoluta massima della cache IN SECONDI
///
private int chAbsExp = 60 * 5;
///
/// Durata della cache IN SECONDI in modalità inattiva (non acceduta) prima di venire rimossa
/// NON estende oltre il tempo massimo di validità della cache (chAbsExp)
///
private int chSliExp = 60 * 1;
///
/// Fattorte conversione cache sliding --> 1 h
///
private int cacheFact = 12;
///
/// Opzioni cache con moltiplicatore durata risp durata base (1/5 minuti)
///
///
///
private DistributedCacheEntryOptions cacheOpt(int multFact)
{
var numSecAbsExp = chAbsExp * multFact;
var numSecSliExp = chSliExp * multFact;
return new DistributedCacheEntryOptions().SetAbsoluteExpiration(DateTime.Now.AddSeconds(numSecAbsExp)).SetSlidingExpiration(TimeSpan.FromSeconds(numSecSliExp));
}
///
/// Elenco obj in cache
///
private List cachedDataList = new List();
///
/// Init classe
///
///
///
///
public LicenseService(IConfiguration configuration, ILogger logger, IDistributedCache distributedCache)
{
_logger = logger;
_configuration = configuration;
this.distributedCache = distributedCache;
}
///
/// Recupero chiave da redis
///
///
///
protected async Task getRSV(string rKey)
{
string answ = "";
var redisDataList = await distributedCache.GetAsync(rKey);
if (redisDataList != null)
{
answ = Encoding.UTF8.GetString(redisDataList);
}
return answ;
}
///
/// Salvataggio chiave in redis
///
///
///
///
///
protected async Task setRSV(string rKey, string rVal, int cacheMult)
{
bool fatto = false;
var redisDataList = Encoding.UTF8.GetBytes(rVal);
await distributedCache.SetAsync(rKey, redisDataList, cacheOpt(cacheMult));
fatto = true;
return fatto;
}
///
/// Salvataggio chiave in redis
///
///
///
///
///
protected async Task setRSV(string rKey, int rValInt, int cacheMult)
{
bool fatto = false;
var redisDataList = Encoding.UTF8.GetBytes($"{rValInt}");
await distributedCache.SetAsync(rKey, redisDataList, cacheOpt(cacheMult));
fatto = true;
return fatto;
}
///
/// Registra in cache chiave se non fosse già in elenco
///
///
protected void trackCache(string newKey)
{
if (!cachedDataList.Contains(newKey))
{
cachedDataList.Add(newKey);
}
}
#endregion Private Fields
#region Public Events
public event Action EA_InfoUpdated = null!;
public List ActivList { get; set; } = new List();
#endregion Public Events
#region Public Properties
public async Task> ActivListCache()
{
List dbResult = new List();
string cacheKey = $"{rKeyAttByLic}:{MasterKey}";
trackCache(cacheKey);
string rawData = await getRSV(cacheKey);
if (!string.IsNullOrEmpty(rawData))
{
dbResult = JsonConvert.DeserializeObject>(rawData);
}
return await Task.FromResult(dbResult);
}
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 * cacheFact * 24);
fatto = true;
if (EA_InfoUpdated != null)
{
EA_InfoUpdated?.Invoke();
}
return fatto;
}
public List AKVList { get; set; } = new List();
public string Installazione { get; set; } = "";
public string Applicazione { 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;
}
}
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();
}
}
return answ;
}
}
public DateTime infoExpiry { get; set; } = DateTime.Today.AddDays(1);
#endregion Public Properties
#region Private Methods
private void ReportUpdated()
{
if (EA_InfoUpdated != null)
{
EA_InfoUpdated?.Invoke();
}
}
///
/// 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;
}
///
/// 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 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;
}
///
/// URL dell'API x chiamate gestione licenze
///
private static string apiUrl = "https://liman.egalware.com/ELM.API/";
///
/// 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);
}
#endregion Private Methods
}
}