618 lines
24 KiB
C#
618 lines
24 KiB
C#
using Core;
|
|
using Core.DTO;
|
|
using LiMan.DB;
|
|
using LiMan.DB.DBModels;
|
|
using LiMan.DB.DTO;
|
|
using LiMan.DB.Services;
|
|
using Microsoft.AspNetCore.Identity.UI.Services;
|
|
using Microsoft.Extensions.Caching.Distributed;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.Logging;
|
|
using Microsoft.Win32;
|
|
using Newtonsoft.Json;
|
|
using NLog;
|
|
using StackExchange.Redis;
|
|
using StackExchange.Redis.Extensions.Core.Abstractions;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using static Core.Enum;
|
|
|
|
namespace LiMan.APi.Data
|
|
{
|
|
/// <summary>
|
|
/// Classe astrazione accesso dati
|
|
/// </summary>
|
|
public class ApiDataService : CommonDataServices
|
|
{
|
|
#region Public Constructors
|
|
|
|
/// <summary>
|
|
/// Init classe
|
|
/// </summary>
|
|
/// <param name="configuration"></param>
|
|
/// <param name="logger"></param>
|
|
/// <param name="emailSender"></param>
|
|
/// <param name="redisCacheClient"></param>
|
|
/// <param name="redisConnMult"></param>
|
|
public ApiDataService(IConfiguration configuration, ILogger<ApiDataService> logger, IEmailSender emailSender, IRedisCacheClient redisCacheClient, IConnectionMultiplexer redisConnMult) : base(configuration, redisConnMult, emailSender)
|
|
{
|
|
_configuration = configuration;
|
|
#if false
|
|
_logger = logger;
|
|
_emailSender = emailSender;
|
|
_redisCacheClient = redisCacheClient;
|
|
//this.distributedCache = distributedCache;
|
|
#endif
|
|
|
|
#if false
|
|
// Conf cache
|
|
redisConn = redisConnMult;
|
|
redisDb = this.redisConn.GetDatabase();
|
|
// json serializer... FIX errore loop circolare https://www.ryadel.com/en/jsonserializationexception-self-referencing-loop-detected-error-fix-entity-framework-asp-net-core/
|
|
JSSettings = new JsonSerializerSettings()
|
|
{
|
|
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
|
|
};
|
|
|
|
// conf messagepipe: setup canali pub/sub
|
|
EnrollMessPipe = new MessagePipe(redisConn, Const.ENRL_MSG_PIPE);
|
|
TaskMessPipe = new MessagePipe(redisConn, Const.TASK_MSG_PIPE);
|
|
UpdActMessPipe = new MessagePipe(redisConn, Const.UPDT_MSG_PIPE);
|
|
|
|
// conf DB
|
|
string connStrDB = _configuration.GetConnectionString("LiMan.DB");
|
|
if (string.IsNullOrEmpty(connStrDB))
|
|
{
|
|
Log.Error("ConnString empty!");
|
|
}
|
|
else
|
|
{
|
|
dbController = new LiMan.DB.Controllers.DbController(configuration);
|
|
Log.Info("DbController OK");
|
|
}
|
|
#endif
|
|
}
|
|
|
|
#endregion Public Constructors
|
|
|
|
#region Public Methods
|
|
|
|
/// <summary>
|
|
/// Recupero da Redis info x elenco info dettaglio di un SINGOLO EgwACC
|
|
/// </summary>
|
|
/// <param name="CodImp">Cod univoco impegno</param>
|
|
public Dictionary<string, string> EgwAccDictDetailGet(string CodImp)
|
|
{
|
|
RedisKey reqKey = (RedisKey)$"{rKeyEACCDetail}:{CodImp}";
|
|
Dictionary<string, string> answ = redisHashDictGet(reqKey);
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salvataggio in Redis info di dettaglio di un EgwACC
|
|
/// </summary>
|
|
/// <param name="CodImp">Cod univoco impegno</param>
|
|
/// <param name="Payload"></param>
|
|
public void EgwAccDictDetailSet(string CodImp, Dictionary<string, string> Payload)
|
|
{
|
|
// salvo in hash info CodImp + versione
|
|
RedisKey reqKey = (RedisKey)$"{rKeyEACCDetail}:{CodImp}";
|
|
// imposto scadenza a 60gg...
|
|
double scadenza = 60 * 24 * 60;
|
|
redisHashDictSet(reqKey, Payload, scadenza);
|
|
#if false
|
|
// salvo in altra hash (con key da CodImp) le info specifiche ricevute
|
|
foreach (var res in Payload)
|
|
{
|
|
redisHashKeySet(reqKey, res.Key, res.Value, scadenza);
|
|
}
|
|
#endif
|
|
// invio string in messagepipe x forzare refresh...
|
|
UpdActMessPipe.sendMessage(CodImp);
|
|
}
|
|
|
|
/// <summary>
|
|
/// recupero da Redis info x elenco EgwACC secondo key richiesta
|
|
/// </summary>
|
|
/// <param name="KeyName">Chiave Richiesta (es Vers, Last, ...)</param>
|
|
public Dictionary<string, string> EgwAccDictValGet(string KeyName)
|
|
{
|
|
RedisKey reqKey = (RedisKey)$"{rKeyEACCList}:{KeyName}";
|
|
Dictionary<string, string> answ = redisHashDictGet(reqKey);
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salvataggio in Redis info x elenco EgwACC sul campo
|
|
/// </summary>
|
|
/// <param name="CodImp">Cod univoco impegno</param>
|
|
/// <param name="KeyName">Chiave salvata (es Vers, Last, ...)</param>
|
|
/// <param name="Value">Valore serializzato</param>
|
|
public void EgwAccDictValSet(string CodImp, string KeyName, string Value)
|
|
{
|
|
// salvo in hash info CodImp + versione
|
|
RedisKey reqKey = (RedisKey)$"{rKeyEACCList}:{KeyName}";
|
|
// salvo in altra hash (con key da CodImp) le info specifiche ricevute
|
|
redisHashKeySet(reqKey, CodImp, Value);
|
|
// invio string in messagepipe x forzare refresh...
|
|
UpdActMessPipe.sendMessage(CodImp);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Crea record richiesta enroll (univoco rispetto richieste correnti)
|
|
/// </summary>
|
|
/// <param name="MachineInfo">Dati da associare alla richeista</param>
|
|
/// <returns></returns>
|
|
public async Task<EnrollRequestModel> EnrollReqCreate(Dictionary<string, string> MachineInfo)
|
|
{
|
|
Stopwatch sw = new Stopwatch();
|
|
sw.Start();
|
|
// svuoto elenco richieste scaduteù
|
|
var cleanDone = await EnrollReqPurgeInvalid();
|
|
// prendo elenco attive x evitare duplicazioni codici TOTP...
|
|
var resList = await EnrollReqGetActive();
|
|
int totpCode = rnd.Next(1, 100000000);
|
|
// verifico che non sia preesistente...
|
|
if (resList.Count > 0)
|
|
{
|
|
// cerco se fosse già presente...
|
|
while (resList.Where(x => x.Passcode == totpCode).Any())
|
|
{
|
|
// genero nuovo...
|
|
await Task.Delay(rnd.Next(50));
|
|
totpCode = rnd.Next(1, 100000000);
|
|
}
|
|
}
|
|
|
|
// serializzo i dati della richiesta..
|
|
string reqPayload = JsonConvert.SerializeObject(MachineInfo);
|
|
|
|
// preparo il record da registrare...
|
|
EnrollRequestModel newReq = new EnrollRequestModel()
|
|
{
|
|
DtReq = DateTime.Now,
|
|
Passcode = totpCode,
|
|
ReqPayload = reqPayload
|
|
};
|
|
|
|
var dbRec = await EnrollReqUpsert(newReq);
|
|
sw.Stop();
|
|
TimeSpan ts = sw.Elapsed;
|
|
Log.Trace($"Effettuata EnrollReqCreate: {ts.TotalMilliseconds} ms");
|
|
|
|
// invio string in messagepipe x forzare refresh...
|
|
EnrollMessPipe.sendMessage("NewEnrollReq");
|
|
|
|
// restituisce record
|
|
return dbRec;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue aggiunta file dato ticket e list uploadResult
|
|
/// </summary>
|
|
/// <param name="idxTicket">Identificativo del ticket</param>
|
|
/// <param name="baseDir">Directory di salvataggio dei file</param>
|
|
/// <param name="fileUploaded">lista risultati della funzione di upload</param>
|
|
/// <returns></returns>
|
|
public async Task<bool> FileAdd(int idxTicket, string baseDir, List<UploadResult> fileUploaded)
|
|
{
|
|
bool fatto = false;
|
|
// inserimento!
|
|
Stopwatch sw = new Stopwatch();
|
|
sw.Start();
|
|
fatto = dbController.FileAdd(idxTicket, baseDir, fileUploaded);
|
|
sw.Stop();
|
|
TimeSpan ts = sw.Elapsed;
|
|
Log.Trace($"Effettuata inserimento con FileAdd: {ts.TotalMilliseconds} ms");
|
|
|
|
// restituisce elenco
|
|
return await Task.FromResult(fatto);
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Effettua registrazione chiamata verificando se vada messa sul DB o in redis...
|
|
/// </summary>
|
|
/// <param name="codInst"></param>
|
|
/// <param name="codApp"></param>
|
|
/// <param name="targetUrl"></param>
|
|
public async Task<bool> recordCall(string codInst, string codApp, string targetUrl)
|
|
{
|
|
bool fatto = false;
|
|
|
|
// in primis recupero statistiche (e nel mentre eventualmente salvo su DB)
|
|
SampleStats currStats = await getCurrStats();
|
|
|
|
// preparo chiave x dato da loggare
|
|
string currKey = $"{rKeySampleVars}:{codInst}:{codApp}:{targetUrl}";
|
|
|
|
// verifico presenza contatore corrente altrimenti aggiungo e salvo...
|
|
if (!currStats.VList.Contains(currKey))
|
|
{
|
|
currStats.VList.Add(currKey);
|
|
// salvo!
|
|
await setCurrStats(currStats);
|
|
}
|
|
// incremento valore contatore corrente
|
|
await redCountIncr(currKey);
|
|
|
|
return fatto;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effettua registrazione da codice chiave...
|
|
/// </summary>
|
|
/// <param name="chiave"></param>
|
|
/// <param name="targetUrl"></param>
|
|
public async Task<bool> recordCall(string chiave, string targetUrl)
|
|
{
|
|
bool fatto = false;
|
|
// valutare se cache key --> lic...
|
|
if (!string.IsNullOrEmpty(chiave))
|
|
{
|
|
var currLic = await LicenzaByMasterKey(chiave);
|
|
if (currLic != null)
|
|
{
|
|
fatto = await recordCall(currLic.CodInst, currLic.CodApp, targetUrl);
|
|
}
|
|
}
|
|
return fatto;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Elenco Release dato Applicativo
|
|
/// </summary>
|
|
/// <param name="CodApp">Codice Applicazione</param>
|
|
/// <returns></returns>
|
|
public async Task<List<ReleaseDTO>> ReleaseDtoGetByApp(string CodApp)
|
|
{
|
|
await Task.Delay(1);
|
|
List<ReleaseDTO> dbResult = new List<ReleaseDTO>();
|
|
Stopwatch stopWatch = new Stopwatch();
|
|
stopWatch.Start();
|
|
dbResult = dbController.ReleaseDtoGetByApp(CodApp);
|
|
stopWatch.Stop();
|
|
TimeSpan ts = stopWatch.Elapsed;
|
|
Log.Trace($"Effettuata lettura da DB per ReleaseDtoGetByApp | {CodApp} | {ts.TotalMilliseconds} ms");
|
|
return dbResult;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Elenco Release dato Applicativo + versione minima
|
|
/// </summary>
|
|
/// <param name="CodApp">Codice Applicazione</param>
|
|
/// <param name="VersMin">Versione minima richiesta</param>
|
|
/// <returns></returns>
|
|
public async Task<List<ReleaseDTO>> ReleaseDtoGetByAppVers(string CodApp, string VersMin)
|
|
{
|
|
await Task.Delay(1);
|
|
List<ReleaseDTO> dbResult = new List<ReleaseDTO>();
|
|
Stopwatch stopWatch = new Stopwatch();
|
|
stopWatch.Start();
|
|
dbResult = dbController.ReleaseDtoGetByAppVers(CodApp, VersMin);
|
|
stopWatch.Stop();
|
|
TimeSpan ts = stopWatch.Elapsed;
|
|
Log.Trace($"Effettuata lettura da DB per ReleaseDtoGetByAppVers | {CodApp} | vers >= {VersMin} | {ts.TotalMilliseconds} ms");
|
|
return dbResult;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Elenco Release dato Applicativo + versione minima
|
|
/// </summary>
|
|
/// <param name="CodApp">Codice Applicazione</param>
|
|
/// <param name="VersMin">Versione minima richiesta</param>
|
|
/// <param name="VersMax">Versione massima consentita</param>
|
|
/// <returns></returns>
|
|
public async Task<List<ReleaseDTO>> ReleaseGetByAppVersLimit(string CodApp, string VersMin, string VersMax)
|
|
{
|
|
await Task.Delay(1);
|
|
List<ReleaseDTO> dbResult = new List<ReleaseDTO>();
|
|
Stopwatch stopWatch = new Stopwatch();
|
|
stopWatch.Start();
|
|
dbResult = dbController.ReleaseDtoGetByAppVersLimit(CodApp, VersMin, VersMax);
|
|
stopWatch.Stop();
|
|
TimeSpan ts = stopWatch.Elapsed;
|
|
Log.Trace($"Effettuata lettura da DB per ReleaseDtoGetByAppVersLimit | {CodApp} | vers >= {VersMin} | {ts.TotalMilliseconds} ms");
|
|
return dbResult;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Elenco di TUTTE le release CRITICAL come dizionario CodApp - release
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public async Task<Dictionary<string, ReleaseDTO>> ReleaseGetCritical()
|
|
{
|
|
Dictionary<string, ReleaseDTO> dbResult = new Dictionary<string, ReleaseDTO>();
|
|
Stopwatch sw = new Stopwatch();
|
|
sw.Start();
|
|
string cacheKey = $"{rKeyAttivByLic}:AppReleases:CRITICAL";
|
|
string source = "REDIS";
|
|
trackCache(cacheKey);
|
|
string rawData = await getRSV(cacheKey);
|
|
if (!string.IsNullOrEmpty(rawData))
|
|
{
|
|
dbResult = JsonConvert.DeserializeObject<Dictionary<string, ReleaseDTO>>(rawData);
|
|
}
|
|
else
|
|
{
|
|
source = "DB";
|
|
dbResult = dbController.ReleaseGetCritical();
|
|
rawData = JsonConvert.SerializeObject(dbResult);
|
|
await setRSV(cacheKey, rawData, redCacheTtlFast);
|
|
}
|
|
sw.Stop();
|
|
Log.Trace($"Effettuata lettura da DB per ReleaseGetCritical | {source} | # found: {dbResult.Count} | {sw.ElapsedMilliseconds} ms");
|
|
return dbResult;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Registro su DB le statistiche delle chiavi in elenco, resettando i vari contatori quando res
|
|
/// </summary>
|
|
/// <param name="keyList">Elenco key nel formato {rKeySampleVars}:{codInst}:{codApp}:{targetUrl}</param>
|
|
public async Task<bool> saveStatsToDb(List<string> keyList)
|
|
{
|
|
bool fatto = false;
|
|
// ciclo x eseguire 1:1
|
|
foreach (var item in keyList)
|
|
{
|
|
// recupero counter...
|
|
var currCount = await redCount(item);
|
|
// scompongo key... senza url di base
|
|
string[] valStr = item.Replace($"{rKeySampleVars}:", "").Split(":");
|
|
if (valStr.Length > 2)
|
|
{
|
|
LogCallModel newRec = new LogCallModel()
|
|
{
|
|
CodInst = valStr[0],
|
|
CodApp = valStr[1],
|
|
TargetUrl = item.Replace($"{rKeySampleVars}:", "").Replace($"{valStr[0]}:{valStr[1]}:", ""),
|
|
DataRif = DateTime.Now,
|
|
NumCall = currCount
|
|
};
|
|
fatto = await dbController.LogCallUpsert(newRec);
|
|
if (fatto)
|
|
{
|
|
await redCountClear(item);
|
|
}
|
|
}
|
|
}
|
|
return fatto;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Restituisce i task associati ad un dato EgwACC
|
|
/// </summary>
|
|
/// <param name="CodImp"></param>
|
|
/// <returns></returns>
|
|
public Dictionary<string, string> TaskListGet(string CodImp)
|
|
{
|
|
RedisKey currKey = (RedisKey)$"{rKeyTaskReq}:{CodImp}";
|
|
Dictionary<string, string> answ = redisHashDictGet(currKey);
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Resetta i task di un dato EgwACC
|
|
/// </summary>
|
|
/// <param name="CodImp"></param>
|
|
/// <returns></returns>
|
|
public Dictionary<string, string> TaskListReset(string CodImp)
|
|
{
|
|
Dictionary<string, string> answ = new Dictionary<string, string>();
|
|
// svuoto dizoinari specifici
|
|
bool ok01 = redisHashDictDelete((RedisKey)$"{rKeyTaskReq}:{CodImp}");
|
|
bool ok02 = redisHashDictDelete((RedisKey)$"{rKeyTaskRun}:{CodImp}");
|
|
bool ok03 = redisHashDictDelete((RedisKey)$"{rKeyTaskDone}:{CodImp}");
|
|
// svuoto in elenco task x imp...
|
|
redisHashKeyDelete((RedisKey)$"{rKeyTaskReq}List", CodImp);
|
|
redisHashKeyDelete((RedisKey)$"{rKeyTaskRun}List", CodImp);
|
|
redisHashKeyDelete((RedisKey)$"{rKeyTaskDone}List", CodImp);
|
|
// leggo remaining x verificare sia ok..
|
|
var dictReq = new Dictionary<string, string>(redisHashDictGet((RedisKey)$"{rKeyTaskReq}:{CodImp}"));
|
|
var dictRun = new Dictionary<string, string>(redisHashDictGet((RedisKey)$"{rKeyTaskRun}:{CodImp}"));
|
|
var dictDone = new Dictionary<string, string>(redisHashDictGet((RedisKey)$"{rKeyTaskDone}:{CodImp}"));
|
|
answ = new Dictionary<string, string>(dictReq);
|
|
foreach (var item in dictRun)
|
|
{
|
|
answ.TryAdd(item.Key, item.Value);
|
|
}
|
|
foreach (var item in dictDone)
|
|
{
|
|
answ.TryAdd(item.Key, item.Value);
|
|
}
|
|
// invio string in messagepipe x forzare refresh...
|
|
UpdActMessPipe.sendMessage(CodImp);
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salva il risultato dell'esecuzione dei task effettuata
|
|
/// </summary>
|
|
/// <param name="CodImp"></param>
|
|
/// <param name="DataPayload"></param>
|
|
/// <returns></returns>
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
public int TaskSetDone(string CodImp, Dictionary<string, string> DataPayload)
|
|
{
|
|
int done = 0;
|
|
// imposto scadenza a 30gg...
|
|
double scadenza = 60 * 24 * 30;
|
|
// upsert per ogni singolo record + rimozione da running
|
|
foreach (var res in DataPayload)
|
|
{
|
|
bool answ = redisHashKeySet((RedisKey)$"{rKeyTaskDone}:{CodImp}", res.Key, res.Value, scadenza);
|
|
redisHashKeyDelete((RedisKey)$"{rKeyTaskRun}:{CodImp}", res.Key);
|
|
// sistemo hashset...
|
|
redisHashKeySet((RedisKey)$"{rKeyTaskDone}List", CodImp, $"{DateTime.Now:yyyy-MM-dd HH:mm:ss}");
|
|
redisHashKeyDelete((RedisKey)$"{rKeyTaskRun}List", CodImp);
|
|
// segnalo fatto
|
|
done += answ ? 1 : 0;
|
|
}
|
|
// invio string in messagepipe x forzare refresh...
|
|
UpdActMessPipe.sendMessage(CodImp);
|
|
return done;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salva come running i task indicati (togliendo da richiesti)
|
|
/// </summary>
|
|
/// <param name="CodImp"></param>
|
|
/// <param name="DataPayload"></param>
|
|
/// <returns></returns>
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
public int TaskSetRunning(string CodImp, Dictionary<string, string> DataPayload)
|
|
{
|
|
int done = 0;
|
|
// imposto scadenza a 30gg...
|
|
double scadenza = 60 * 24 * 30;
|
|
// upsert per ogni singolo record + rimozione da richiesti
|
|
foreach (var res in DataPayload)
|
|
{
|
|
// sposto il valore in key
|
|
bool answ = redisHashKeySet((RedisKey)$"{rKeyTaskRun}:{CodImp}", res.Key, res.Value, scadenza);
|
|
redisHashKeyDelete((RedisKey)$"{rKeyTaskReq}:{CodImp}", res.Key);
|
|
|
|
// sistemo list task...
|
|
redisHashKeySet((RedisKey)$"{rKeyTaskRun}List", CodImp, $"{DateTime.Now:yyyy-MM-dd HH:mm:ss}");
|
|
redisHashKeyDelete((RedisKey)$"{rKeyTaskReq}List", CodImp);
|
|
// segnalo fatto
|
|
done += answ ? 1 : 0;
|
|
}
|
|
// invio string in messagepipe x forzare refresh...
|
|
UpdActMessPipe.sendMessage(CodImp);
|
|
return done;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue aggiunta Ticket richiesto + restitusice aperti x cliente
|
|
/// </summary>
|
|
/// <param name="currRequest"></param>
|
|
/// <returns></returns>
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
public async Task<bool> TicketAdd(SupportRequest currRequest)
|
|
{
|
|
bool fatto = false;
|
|
// inserimento!
|
|
Stopwatch stopWatch = new Stopwatch();
|
|
stopWatch.Start();
|
|
fatto = dbController.TicketAddNew(currRequest);
|
|
stopWatch.Stop();
|
|
TimeSpan ts = stopWatch.Elapsed;
|
|
Log.Trace($"Effettuata inserimento con TicketAdd: {ts.TotalMilliseconds} ms");
|
|
|
|
// restituisce elenco
|
|
return await Task.FromResult(fatto);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Elenco ticket dato cliente + App + MasterKey
|
|
/// </summary>
|
|
/// <param name="CodInst"></param>
|
|
/// <param name="CodApp"></param>
|
|
/// <param name="MasterKey"></param>
|
|
/// <param name="numRec"></param>
|
|
/// <returns></returns>
|
|
public async Task<List<TicketDTO>> TicketByCliente(string CodInst, string CodApp, string MasterKey, int numRec = 1000)
|
|
{
|
|
List<TicketDTO> dbResult = new List<TicketDTO>();
|
|
Stopwatch stopWatch = new Stopwatch();
|
|
stopWatch.Start();
|
|
|
|
dbResult = dbController.TicketGetFilt(false, TipologiaTicket.ND, CodApp, CodInst, MasterKey, numRec);
|
|
stopWatch.Stop();
|
|
TimeSpan ts = stopWatch.Elapsed;
|
|
Log.Trace($"Effettuata lettura da DB per TicketByCliente: {ts.TotalMilliseconds} ms");
|
|
|
|
return await Task.FromResult(dbResult);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salva ultima dataora di comunicazione con un updater
|
|
/// </summary>
|
|
/// <param name="CodImp"></param>
|
|
/// <param name="CodAction"></param>
|
|
/// <returns></returns>
|
|
public int UpdaterRecordAction(string CodImp, string CodAction)
|
|
{
|
|
int done = 0;
|
|
|
|
// salvo info sul TIPO di chiamata
|
|
bool answ = redisHashKeyIncDecBy((RedisKey)$"{rKeyUpdLastAct}:{CodImp}", CodAction, 1);
|
|
|
|
// registro ultima chiamata
|
|
redisHashKeySet((RedisKey)$"{rKeyUpdLastAct}List", CodImp, $"{DateTime.Now:yyyy-MM-dd HH:mm:ss}");
|
|
|
|
// invio string in messagepipe x forzare refresh...
|
|
UpdActMessPipe.sendMessage(CodImp);
|
|
// scambio tipo di pipe messaggi (update e non task)
|
|
//TaskMessPipe.sendMessage(CodImp);
|
|
return done;
|
|
}
|
|
|
|
#endregion Public Methods
|
|
|
|
#region Protected Fields
|
|
|
|
protected new static Logger Log = LogManager.GetCurrentClassLogger();
|
|
|
|
#endregion Protected Fields
|
|
|
|
#region Protected Methods
|
|
|
|
/// <summary>
|
|
/// Recupera statistiche correnti
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
protected async Task<SampleStats> getCurrStats()
|
|
{
|
|
DateTime adesso = DateTime.Now;
|
|
SampleStats answ = new SampleStats()
|
|
{
|
|
Name = "ApiStats"
|
|
};
|
|
// in primis check data/ora prima/ultima scrittura del set... (2 date, lista chiavi gestite)
|
|
string rawData = await getRSV(rKeySampleStats);
|
|
if (rawData != null)
|
|
{
|
|
answ = JsonConvert.DeserializeObject<SampleStats>(rawData);
|
|
// aggiorno ultimo controllo e salvo...
|
|
answ.DtLast = adesso;
|
|
// salvo!
|
|
await setCurrStats(answ);
|
|
}
|
|
// controllo se scadute...
|
|
if (adesso.Subtract(answ.DtFirst).TotalMinutes > 60)
|
|
{
|
|
// se scaduto --> registrazione set sul DB (async), resettando i vari contatori...
|
|
bool salvato = await saveStatsToDb(answ.VList);
|
|
// inizio NUOVO set vuoto con record corrente
|
|
answ = new SampleStats()
|
|
{
|
|
Name = "ApiStats"
|
|
};
|
|
// salvo!
|
|
await setCurrStats(answ);
|
|
}
|
|
// restituisco record!
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salva statistiche correnti
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
protected async Task<bool> setCurrStats(SampleStats newVal)
|
|
{
|
|
bool answ = false;
|
|
string rawData = JsonConvert.SerializeObject(newVal);
|
|
answ = await setRSV(rKeySampleStats, rawData, 24 * hourTTL);
|
|
return answ;
|
|
}
|
|
|
|
#endregion Protected Methods
|
|
}
|
|
} |