Files
gpw_next/GPW.CORE.Api/Data/ApiDataService.cs
T
2022-01-26 15:37:14 +01:00

317 lines
11 KiB
C#

using GPW.CORE.Data.DbModels;
using Newtonsoft.Json;
using NLog;
using Microsoft.AspNetCore.Identity.UI.Services;
using StackExchange.Redis.Extensions.Core.Abstractions;
using System.Diagnostics;
using GPW.CORE.Data;
namespace GPW.CORE.Api.Data
{
public class ApiDataService
{
#region Private Fields
private static IConfiguration _configuration;
private static ILogger<ApiDataService> _logger;
private static NLog.Logger Log = LogManager.GetCurrentClassLogger();
private readonly IEmailSender _emailSender;
//private readonly IDistributedCache distributedCache;
private readonly IRedisCacheClient _redisCacheClient;
/// <summary>
/// Elenco obj in cache
/// </summary>
private List<string> cachedDataList = new List<string>();
#endregion Private Fields
#region Protected Fields
protected const string rKeyProjAct = "Check:ProjAct";
protected const string rKeyFasiAct = "Check:FasiAct";
protected const string rKeyCalcOreFase = "Check:OreFasi";
/// <summary>
/// TTL da 1 min x cache Redis
/// </summary>
protected const int shortTTL = 60 * 5;
#endregion Protected Fields
#region Public Fields
/// <summary>
/// Classe Accesso metodi DB
/// </summary>
public static CORE.Data.Controllers.GPWController dbController;
#endregion Public Fields
#region Public Constructors
/// <summary>
/// Init classe
/// </summary>
/// <param name="configuration"></param>
/// <param name="logger"></param>
/// <param name="emailSender"></param>
/// <param name="redisCacheClient"></param>
public ApiDataService(IConfiguration configuration, ILogger<ApiDataService> logger, IEmailSender emailSender, IRedisCacheClient redisCacheClient)
//public ApiDataService(IConfiguration configuration, ILogger<ApiDataService> logger, IDistributedCache distributedCache, IEmailSender emailSender, IRedisCacheClient redisCacheClient)
{
_logger = logger;
_configuration = configuration;
_emailSender = emailSender;
_redisCacheClient = redisCacheClient;
// conf DB
string connStrDB = _configuration.GetConnectionString("GPW.DB");
if (string.IsNullOrEmpty(connStrDB))
{
_logger.LogError("ConnString empty!");
}
else
{
dbController = new CORE.Data.Controllers.GPWController(configuration);
_logger.LogInformation("DbController OK");
}
}
#endregion Public Constructors
#region Protected Methods
/// <summary>
/// Recupero chiave da redis
/// </summary>
/// <param name="rKey"></param>
/// <returns></returns>
protected async Task<string> getRSV(string rKey)
{
string answ = await _redisCacheClient.GetDbFromConfiguration().GetAsync<string>(rKey);
return answ;
}
/// <summary>
/// Salvataggio chiave in redis
/// </summary>
/// <param name="rKey"></param>
/// <param name="rVal"></param>
/// <param name="ttlSec"></param>
/// <returns></returns>
protected async Task<bool> setRSV(string rKey, string rVal, int ttlSec)
{
bool fatto = false;
await _redisCacheClient.GetDbFromConfiguration().AddAsync(rKey, rVal, DateTimeOffset.Now.AddSeconds(ttlSec));
fatto = true;
return fatto;
}
/// <summary>
/// Salvataggio chiave in redis
/// </summary>
/// <param name="rKey"></param>
/// <param name="rValInt"></param>
/// <param name="ttlSec"></param>
/// <returns></returns>
protected async Task<bool> setRSV(string rKey, int rValInt, int ttlSec)
{
bool fatto = false;
await _redisCacheClient.GetDbFromConfiguration().AddAsync<int>(rKey, rValInt, DateTimeOffset.Now.AddSeconds(ttlSec));
fatto = true;
return fatto;
}
/// <summary>
/// Registra in cache chiave se non fosse già in elenco
/// </summary>
/// <param name="newKey"></param>
protected void trackCache(string newKey)
{
if (!cachedDataList.Contains(newKey))
{
cachedDataList.Add(newKey);
}
}
#endregion Protected Methods
#region Public Methods
/// <summary>
/// Recupera l'elenco progetti (ATTIVI)
/// </summary>
/// <returns></returns>
public async Task<List<AnagProgettiModel>> AnagProjActiv()
{
List<AnagProgettiModel> dbResult = new List<AnagProgettiModel>();
string cacheKey = $"{rKeyProjAct}";
trackCache(cacheKey);
string rawData = await getRSV(cacheKey);
if (!string.IsNullOrEmpty(rawData))
{
dbResult = JsonConvert.DeserializeObject<List<AnagProgettiModel>>(rawData);
}
else
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
dbResult = dbController.AnagProjAll(true);
rawData = JsonConvert.SerializeObject(dbResult, Formatting.None, new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
await setRSV(cacheKey, rawData, shortTTL);
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB per AnagProjActiv: {ts.TotalMilliseconds} ms");
}
return await Task.FromResult(dbResult);
}
/// <summary>
/// Recupera l'elenco fasi (ATTIVE)
/// </summary>
/// <returns></returns>
public async Task<List<AnagFasiModel>> AnagFasiActiv()
{
List<AnagFasiModel> dbResult = new List<AnagFasiModel>();
string cacheKey = $"{rKeyFasiAct}";
trackCache(cacheKey);
string rawData = await getRSV(cacheKey);
if (!string.IsNullOrEmpty(rawData))
{
dbResult = JsonConvert.DeserializeObject<List<AnagFasiModel>>(rawData);
}
else
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
dbResult = dbController.AnagFasiAll(true);
rawData = JsonConvert.SerializeObject(dbResult, Formatting.None, new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
await setRSV(cacheKey, rawData, shortTTL);
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB per AnagFasiActiv: {ts.TotalMilliseconds} ms");
}
return await Task.FromResult(dbResult);
}
/// <summary>
/// Vista dati per FASE (tipicamente master...) con totalizzaizone ore budget/real e stato fase
/// </summary>
/// <param name="idxFase"></param>
/// <returns></returns>
public async Task<CalcOreFasiModel> CalcOreFase(int idxFase, bool doLog)
{
CalcOreFasiModel? dbResult = new CalcOreFasiModel();
string cacheKey = $"{rKeyCalcOreFase}:{idxFase}";
trackCache(cacheKey);
string rawData = await getRSV(cacheKey);
if (!string.IsNullOrEmpty(rawData))
{
dbResult = JsonConvert.DeserializeObject<CalcOreFasiModel>(rawData);
}
else
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
dbResult = dbController.CalcOreFase(idxFase);
rawData = JsonConvert.SerializeObject(dbResult, Formatting.None, new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
await setRSV(cacheKey, rawData, shortTTL);
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
if (doLog)
{
Log.Trace($"Effettuata lettura da DB per CalcOreFase: {ts.TotalMilliseconds} ms");
}
}
if (dbResult == null)
{
dbResult = new CalcOreFasiModel();
}
return await Task.FromResult(dbResult);
}
/// <summary>
/// invalida tutta la cache in caso di update
/// </summary>
/// <returns></returns>
public async Task InvalidateAllCache()
{
foreach (var item in cachedDataList)
{
await _redisCacheClient.GetDbFromConfiguration().RemoveAsync(item);
}
cachedDataList = new List<string>();
}
public async Task<List<CheckVc19Model>> ChecksGetByDip(int idxDip)
{
DateTime dtFine = DateTime.Today.AddDays(1);
List<CheckVc19Model> dbResult = new List<CheckVc19Model>();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
dbResult = dbController.GetChecksVC19Filt(idxDip, dtFine.AddMonths(-1), dtFine);
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB per ChecksGetByDip: {ts.TotalMilliseconds} ms");
return await Task.FromResult(dbResult);
}
public async Task<List<CheckVc19Model>> ChecksGetLast(int numRecord)
{
List<CheckVc19Model> dbResult = new List<CheckVc19Model>();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
dbResult = dbController.GetChecksVC19(numRecord);
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata lettura da DB per ChecksGetLast: {ts.TotalMilliseconds} ms");
return await Task.FromResult(dbResult);
}
public void Dispose()
{
// Clear database controller
dbController.Dispose();
}
public async Task<bool> InsertCheck(DCCDecode updItem, string clientIp)
{
bool done = false;
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
done = dbController.InsertCheck(updItem, clientIp);
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata operazione InsertCheck: {ts.TotalMilliseconds} ms");
return await Task.FromResult(done);
}
public async Task<bool> InsertManual(int idxDip, string clientIp)
{
bool done = false;
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
done = dbController.InsertManual(idxDip, clientIp);
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Trace($"Effettuata operazione InsertManual: {ts.TotalMilliseconds} ms");
return await Task.FromResult(done);
}
#endregion Public Methods
}
}