Files
webdoorcreator/WebDoorCreator.API/Data/ApiDataService.cs
T
Samuele Locatelli 96fdf85b27 Update webAPI:
- Riorganizzazione costanti
- aggiunta metodi a progetto
- aggiunta pacchetti nuget
2023-04-18 20:18:22 +02:00

253 lines
7.7 KiB
C#

using Microsoft.AspNetCore.Identity.UI.Services;
using Newtonsoft.Json;
using NLog;
using StackExchange.Redis;
using System.Diagnostics;
using WebDoorCreator.Core;
using WebDoorCreator.Data.DbModels;
namespace WebDoorCreator.API.Data
{
public class ApiDataService : IDisposable
{
#region Public Fields
/// <summary>
/// Classe Accesso metodi DB
/// </summary>
public static WebDoorCreator.Data.Controllers.WebDoorCreatorController dbController = null!;
#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, IEmailSender emailSender, IConnectionMultiplexer redisConn)
{
_configuration = configuration;
_emailSender = emailSender;
// setup compoenti REDIS
var redConnString = _configuration.GetConnectionString("Redis");
if (redConnString == null)
{
Log.Error("REDIS ConnString empty!");
}
else
{
this.redisConn = ConnectionMultiplexer.Connect(redConnString);
this.redisDb = this.redisConn.GetDatabase();
}
// Conf DB
var connStrDB = _configuration.GetConnectionString("WDC.DB");
if (string.IsNullOrEmpty(connStrDB))
{
Log.Error("ConnString empty!");
}
else
{
dbController = new WebDoorCreator.Data.Controllers.WebDoorCreatorController(configuration);
Log.Info("DbController OK");
}
}
#endregion Public Constructors
#region Public Methods
public void Dispose()
{
// Clear database controller
dbController.Dispose();
}
/// <summary>
/// Doors list by orderId
/// </summary>
public async Task<List<DoorModel>?> DoorGetByOrderId(int orderId)
{
string source = "DB";
List<DoorModel>? dbResult = new List<DoorModel>();
// cerco da cache
string currKey = $"{Constants.rKeyOrderDetail}:{orderId}";
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
string? rawData = await redisDb.StringGetAsync(currKey);
if (!string.IsNullOrEmpty(rawData))
{
source = "REDIS";
var tempResult = JsonConvert.DeserializeObject<List<DoorModel>>(rawData);
if (tempResult == null)
{
dbResult = new List<DoorModel>();
}
else
{
dbResult = tempResult;
}
}
else
{
dbResult = dbController.DoorsGetByOrderId(orderId);
rawData = JsonConvert.SerializeObject(dbResult, JSSettings);
await redisDb.StringSetAsync(currKey, rawData, UltraLongCache);
}
if (dbResult == null)
{
dbResult = new List<DoorModel>();
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Log.Debug($"DoorGetByOrderId | {source} in: {ts.TotalMilliseconds} ms");
return dbResult;
}
#endregion Public Methods
#region Protected Fields
protected const string rKeyCalcOreFase = "Check:OreFasi";
protected const string rKeyFasiAct = "Check:FasiAct";
protected const string rKeyProjAct = "Check:ProjAct";
/// <summary>
/// TTL da 1 min x cache Redis
/// </summary>
protected const int shortTTL = 60 * 5;
protected Random rnd = new Random();
#endregion Protected Fields
#region Protected Methods
/// <summary>
/// Recupero chiave da redis
/// </summary>
/// <param name="rKey"></param>
/// <returns></returns>
protected async Task<string> getRSV(string rKey)
{
string answ = "";
var rawData = await redisDb.StringGetAsync(rKey);
if (rawData.HasValue)
{
answ = $"{rawData}";
}
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 redisDb.StringSetAsync(rKey, rVal, TimeSpan.FromSeconds(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 redisDb.StringSetAsync(rKey, rValInt, TimeSpan.FromSeconds(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 Private Fields
private static IConfiguration _configuration = null!;
private static JsonSerializerSettings? JSSettings;
private static Logger Log = LogManager.GetCurrentClassLogger();
private readonly IEmailSender _emailSender;
/// <summary>
/// Elenco obj in cache
/// </summary>
private List<string> cachedDataList = new List<string>();
/// <summary>
/// Durata cache lunga IN SECONDI
/// </summary>
private int cacheTtlLong = 60 * 5;
/// <summary>
/// Durata cache breve IN SECONDI
/// </summary>
private int cacheTtlShort = 60 * 1;
/// <summary>
/// Oggetto per connessione a REDIS
/// </summary>
private ConnectionMultiplexer redisConn = null!;
/// <summary>
/// Oggetto DB redis da impiegare x chiamate R/W
/// </summary>
private IDatabase redisDb = null!;
#endregion Private Fields
#region Private Properties
/// <summary>
/// Durata cache lunga (+ perturbazione percentuale +/-10%)
/// </summary>
private TimeSpan FastCache
{
get => TimeSpan.FromSeconds(cacheTtlShort * rnd.Next(900, 1100) / 1000);
}
/// <summary>
/// Durata cache lunga (+ perturbazione percentuale +/-10%)
/// </summary>
private TimeSpan LongCache
{
get => TimeSpan.FromSeconds(cacheTtlLong * rnd.Next(900, 1100) / 1000);
}
/// <summary>
/// Durata cache lunga (+ perturbazione percentuale +/-10%)
/// </summary>
private TimeSpan UltraLongCache
{
get => TimeSpan.FromSeconds(cacheTtlLong * 10 * rnd.Next(900, 1100) / 1000);
}
#endregion Private Properties
}
}