Files
2026-02-25 11:27:59 +01:00

3360 lines
137 KiB
C#

using DnsClient.Protocol;
using EgwCoreLib.Utils;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using MP.Core.Conf;
using MP.Core.DTO;
using MP.Core.Objects;
using MP.Data;
using MP.Data.Controllers;
using MP.Data.DbModels;
using MP.Data.MgModels;
using MP.Data.Services;
using MP.SPEC.Components.ProdKit;
using Newtonsoft.Json;
using NLog;
using StackExchange.Redis;
using System.Data;
using System.Diagnostics;
using ZXing;
namespace MP.SPEC.Data
{
public class MpDataService : IDisposable
{
#region Public Constructors
public MpDataService(IConfiguration configuration)
{
// fix oggetto configurazion
_configuration = configuration;
// Verifica conf trace...
traceEnabled = _configuration.GetValue<bool>("Otel:EnableTracing", false);
Log.Info($"MpDataService | INIT | Trace enabled: {traceEnabled}");
// setup compoenti REDIS
redisConn = ConnectionMultiplexer.Connect(_configuration.GetConnectionString("Redis") ?? "localhost:6379");
redisConnAdmin = ConnectionMultiplexer.Connect(_configuration.GetConnectionString("RedisAdmin") ?? "localhost:6379");
redisDb = redisConn.GetDatabase();
// leggo cache lungo periodo
int.TryParse(_configuration.GetValue<string>("ServerConf:redisLongTimeCache"), out redisLongTimeCache);
// setup MsgPipe
BroadastMsgPipe = new MessagePipe(redisConn, Constants.BROADCAST_M_PIPE);
Log.Info("MpDataService | Redis OK");
// conf DB
string connStr = _configuration.GetConnectionString("MP.Data") ?? "";
if (string.IsNullOrEmpty(connStr))
{
Log.Error("DbController: ConnString empty!");
}
else
{
dbController = new MpSpecController(configuration);
Log.Info("DbController OK");
}
// conf x lettura dati da area REDIS di MP-IO
MpIoNS = _configuration.GetValue<string>("ServerConf:MpIoNS") ?? "";
// conf mongo...
connStr = _configuration.GetConnectionString("mdbConnString") ?? "";
if (string.IsNullOrEmpty(connStr))
{
Log.Error("MongoController: ConnString empty!");
}
else
{
mongoController = new MpMongoController(configuration);
Log.Info("MongoController OK");
}
Log.Info("MpDataService | INIT completed");
}
/// <summary>
/// Helper trace messaggio log (SE abilitato)
/// </summary>
/// <param name="traceMsg"></param>
private void LogTrace(string traceMsg, NLog.LogLevel? reqLevel = null)
{
if (!traceEnabled)
return;
reqLevel ??= NLog.LogLevel.Debug;
// Loggo!
Log.Log(reqLevel, traceMsg);
}
private bool traceEnabled = false;
#endregion Public Constructors
#region Public Events
/// <summary>
/// Evento richiesta rilettura dati pagina (x refresh pagine aperte)
/// </summary>
public event EventHandler ReloadRequest = delegate { };
#endregion Public Events
#region Public Properties
public static MpSpecController dbController { get; set; } = null!;
public static MpMongoController mongoController { get; set; } = null!;
public MessagePipe BroadastMsgPipe { get; set; } = null!;
/// <summary>
/// Dizionario dei tag configurati per IOB
/// </summary>
public Dictionary<string, List<TagData>> currTagConf { get; set; } = new Dictionary<string, List<TagData>>();
#endregion Public Properties
#region Public Methods
/// <summary>
/// Recupera eventuali azioni richieste
/// </summary>
/// <returns></returns>
public async Task<DisplayAction> ActionGetReq()
{
using var activity = ActivitySource.StartActivity("ActionGetReq");
string source = "REDIS";
DisplayAction? result = null;
// cerco in redis...
RedisValue rawData = await redisDb.StringGetAsync(Utils.redisActionReq);
if (!string.IsNullOrEmpty($"{rawData}"))
{
result = JsonConvert.DeserializeObject<DisplayAction>($"{rawData}");
}
if (result == null)
{
result = new DisplayAction();
}
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"ActionGetReq Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Salva richiesta azione
/// </summary>
/// <param name="act2save"></param>
/// <returns></returns>
public bool ActionSetReq(DisplayAction? act2save)
{
using var activity = ActivitySource.StartActivity("ActionSetReq");
string source = "REDIS";
bool fatto = false;
// cerco in redis...
string rawData = JsonConvert.SerializeObject(act2save);
// invio broadcast + salvo in redis
BroadastMsgPipe.saveAndSendMessage(Utils.redisActionReq, rawData);
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"ActionSetReq {source} send to broadcast + Write cache: {activity?.Duration.TotalMilliseconds}ms");
return fatto;
}
/// <summary>
/// Stacca un nuovo counter x il tipo richiesto
/// </summary>
/// <returns></returns>
public AnagCountersModel AnagCountersGetNext(string cntType)
{
using var activity = ActivitySource.StartActivity("AnagCountersGetNext");
AnagCountersModel result = new AnagCountersModel();
string source = "DB";
result = dbController.AnagCountersGetNext(cntType);
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"AnagCountersGetNext | {source} | {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Elenco EVENTI validi x ogni macchina secondo conf standard macchina
/// </summary>
/// <returns></returns>
public List<vSelEventiBCodeModel> AnagEventiGeneral()
{
using var activity = ActivitySource.StartActivity("AnagEventiGeneral");
string source = "DB";
List<vSelEventiBCodeModel>? result = new List<vSelEventiBCodeModel>();
// cerco in redisConn...
string currKey = $"{Utils.redisEventList}:VSEB:GENERAL";
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<vSelEventiBCodeModel>>($"{rawData}");
source = "REDIS";
}
else
{
result = dbController.AnagEventiGeneral();
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
}
if (result == null)
{
result = new List<vSelEventiBCodeModel>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"AnagEventiGeneral | {source} | {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Elenco EVENTI validi x macchina
/// </summary>
/// <returns></returns>
public List<vSelEventiBCodeModel> AnagEventiGetByMacch(string IdxMacch)
{
using var activity = ActivitySource.StartActivity("AnagEventiGetByMacch");
string source = "DB";
List<vSelEventiBCodeModel>? result = new List<vSelEventiBCodeModel>();
// cerco in redisConn...
string currKey = $"{Utils.redisEventList}:VSEB:{IdxMacch}";
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<vSelEventiBCodeModel>>($"{rawData}");
source = "REDIS";
}
else
{
result = dbController.AnagEventiGetByMacc(IdxMacch);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
}
if (result == null)
{
result = new List<vSelEventiBCodeModel>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"AnagEventiGetByMacch | {source} | {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Delete record AnagraficaGruppi
/// </summary>
/// <returns></returns>
public bool AnagGruppiDelete(AnagGruppiModel updRec)
{
using var activity = ActivitySource.StartActivity("AnagGruppiDelete");
bool result = false;
result = dbController.AnagGruppiDelete(updRec);
// elimino cache redis...
string pattern = $"{Utils.redisAnagGruppi}:*";
bool answ = ExecFlushRedisPattern(pattern);
activity?.SetTag("data.source", "DB+REDIS");
activity?.Stop();
LogTrace($"AnagGruppiDelete | CodGruppo {updRec.CodGruppo} | {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Upsert record AnagraficaGruppi
/// </summary>
/// <param name="UpdRec"></param>
/// <returns></returns>
public bool AnagGruppiUpsert(AnagGruppiModel UpdRec)
{
using var activity = ActivitySource.StartActivity("AnagGruppiUpsert");
bool result = false;
result = dbController.AnagGruppiUpsert(UpdRec);
// elimino cache redis...
string pattern = $"{Utils.redisAnagGruppi}:*";
bool answ = ExecFlushRedisPattern(pattern);
activity?.SetTag("data.source", "DB+REDIS");
activity?.Stop();
LogTrace($"AnagGruppiUpsert | CodGruppo {UpdRec.CodGruppo} | {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Elenco Gruppi
/// </summary>
/// <returns></returns>
public async Task<List<AnagKeyValueModel>> AnagKeyValGetAll()
{
// nuovo oggetto span activity
using var activity = ActivitySource.StartActivity("AnagKeyValGetAll");
string source = "DB";
List<AnagKeyValueModel>? result = new List<AnagKeyValueModel>();
// cerco in redis...
RedisValue rawData = await redisDb.StringGetAsync(Utils.redisAKVKey);
if (!string.IsNullOrEmpty($"{rawData}"))
{
result = JsonConvert.DeserializeObject<List<AnagKeyValueModel>>($"{rawData}");
source = "REDIS";
}
else
{
result = await Task.FromResult(dbController.AnagKeyValGetAll());
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
await redisDb.StringSetAsync(Utils.redisConfKey, rawData, getRandTOut(redisLongTimeCache));
}
if (result == null)
{
result = new List<AnagKeyValueModel>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"AnagKeyValGetAll Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return result;
}
public async Task<List<ListValuesModel>> AnagStatiComm()
{
using var activity = ActivitySource.StartActivity("AnagStatiComm");
string source = "DB";
List<ListValuesModel>? result = new List<ListValuesModel>();
// cerco in redis...
RedisValue rawData = await redisDb.StringGetAsync(Utils.redisStatoCom);
if (!string.IsNullOrEmpty($"{rawData}"))
{
result = JsonConvert.DeserializeObject<List<ListValuesModel>>($"{rawData}");
source = "REDIS";
}
else
{
result = await Task.FromResult(dbController.AnagStatiComm());
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
await redisDb.StringSetAsync(Utils.redisStatoCom, rawData, getRandTOut(redisLongTimeCache));
}
if (result == null)
{
result = new List<ListValuesModel>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"AnagStatiComm Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return result;
}
public async Task<List<ListValuesModel>> AnagTipoArtLV()
{
using var activity = ActivitySource.StartActivity("AnagStatiComm");
string source = "DB";
List<ListValuesModel>? result = new List<ListValuesModel>();
// cerco in redis...
RedisValue rawData = await redisDb.StringGetAsync(Utils.redisTipoArt);
if (!string.IsNullOrEmpty($"{rawData}"))
{
result = JsonConvert.DeserializeObject<List<ListValuesModel>>($"{rawData}");
source = "REDIS";
}
else
{
result = await Task.FromResult(dbController.AnagTipoArtLV());
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
await redisDb.StringSetAsync(Utils.redisTipoArt, rawData, getRandTOut(redisLongTimeCache));
}
if (result == null)
{
result = new List<ListValuesModel>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"AnagTipoArtLV Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Elenco Codice articolo con dati dossier gestiti
/// </summary>
/// <returns></returns>
public async Task<List<string>> ArticleWithDossier()
{
using var activity = ActivitySource.StartActivity("ArticleWithDossier");
List<string>? result = new List<string>();
string source = "DB";
string currKey = Utils.redisArtByDossier;
// cerco in redis dato valore sel idxMaccSel...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<string>>($"{rawData}");
source = "REDIS";
}
else
{
result = await Task.FromResult(dbController.ArticleWithDossier());
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
}
if (result == null)
{
result = new List<string>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"ArticleWithDossier | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Eliminazione record selezionato
/// </summary>
/// <param name="currRec"></param>
/// <returns></returns>
public async Task<bool> ArticoliDeleteRecord(AnagArticoliModel currRec)
{
using var activity = ActivitySource.StartActivity("ArticoliDeleteRecord");
string source = "DB+REDIS";
bool fatto = await dbController.ArticoliDeleteRecord(currRec);
await resetCacheArticoli();
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"ArticoliDeleteRecord | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return fatto;
}
/// <summary>
/// Restitusice elenco articoli dato tipo (es KIT)
/// </summary>
/// <param name="tipo"></param>
/// <param name="azienda"></param>
/// <returns></returns>
public List<AnagArticoliModel> ArticoliGetByTipo(string tipo, string azienda = "*")
{
using var activity = ActivitySource.StartActivity("ArticoliGetByTipo");
List<AnagArticoliModel>? result = new List<AnagArticoliModel>();
string source = "DB";
string sKey = string.IsNullOrEmpty(tipo) ? "ALL" : tipo;
string currKey = $"{Utils.redisArtList}:{azienda}:Tipo:{sKey}";
// cerco in redis dato valore sel idxMaccSel...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<AnagArticoliModel>>($"{rawData}");
source = "REDIS";
}
else
{
result = dbController.ArticoliGetByTipo(tipo, azienda);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
}
if (result == null)
{
result = new List<AnagArticoliModel>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"ArticoliGetByTipo | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Restitusice elenco articoli cercati
/// </summary>
/// <param name="numRecord"></param>
/// <param name="searchVal"></param>
/// <returns></returns>
public async Task<List<AnagArticoliModel>> ArticoliGetSearch(int numRecord, string azienda, string searchVal)
{
using var activity = ActivitySource.StartActivity("ArticoliGetSearch");
List<AnagArticoliModel>? result = new List<AnagArticoliModel>();
string source = "DB";
string sKey = string.IsNullOrEmpty(searchVal) ? "***" : searchVal;
string currKey = $"{Utils.redisArtList}:{azienda}:{sKey}";
// cerco in redis dato valore sel idxMaccSel...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<AnagArticoliModel>>($"{rawData}");
source = "REDIS";
}
else
{
result = await Task.FromResult(dbController.ArticoliGetSearch(numRecord, azienda, searchVal));
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache / 5));
}
if (result == null)
{
result = new List<AnagArticoliModel>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"ArticoliGetSearch | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Aggiornamento record selezionato
/// </summary>
/// <param name="currRec"></param>
/// <returns></returns>
public async Task<bool> ArticoliUpdateRecord(AnagArticoliModel currRec)
{
using var activity = ActivitySource.StartActivity("ArticoliUpdateRecord");
string source = "DB+REDIS";
bool fatto = await dbController.ArticoliUpdateRecord(currRec);
await resetCacheArticoli();
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"ArticoliUpdateRecord | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return fatto;
}
/// <summary>
/// Verifica se sia possiubile cancellare articolo dato suo CodArt cercando su redis o su
/// tab veto da DB
/// </summary>
/// <param name="CodArt"></param>
/// <returns></returns>
public bool ArticoloDelEnabled(object CodArt)
{
using var activity = ActivitySource.StartActivity("ArticoloDelEnabled");
string source = "DB";
bool answ = false;
string codArticolo = $"{CodArt}";
int cacheCheckArtUsato = 1;
int.TryParse(_configuration.GetValue<string>("ServerConf:cacheCheckArtUsato"), out cacheCheckArtUsato);
TimeSpan TTLCache = getRandTOut(cacheCheckArtUsato);
// cerco in cache redis...
string redKeyArtUsed = $"{Utils.redKeyArtUsed}:{codArticolo}";
string redKeyTabCheckArt = Utils.redKeyTabCheckArt;
var rawData = redisDb.StringGet(redKeyArtUsed);
if (!string.IsNullOrEmpty(rawData))
{
bool.TryParse(rawData, out answ);
}
else
{
// controllo non sia stato mai prodotto sennò non posso cancellare...
try
{
// cerco in cache se ci sia la tabella con gli articoli impiegati...
var rawTable = redisDb.StringGet(redKeyTabCheckArt);
List<string>? artList = new List<string>();
if (!string.IsNullOrEmpty(rawTable))
{
artList = JsonConvert.DeserializeObject<List<string>>($"{rawTable}");
}
// rileggo...
if (artList == null || artList.Count == 0)
{
artList = new List<string>();
var tabArticoli = dbController.ArticoliGetUsed();
var codList = tabArticoli.Select(x => x.CodArticolo);
foreach (string cod in codList)
{
artList.Add(cod);
}
// SE fosse vuoto aggiungo comunque il cado "ND"...
if (artList.Count == 0)
{
artList.Add("ND");
}
// salvo
rawTable = JsonConvert.SerializeObject(artList);
redisDb.StringSet(redKeyTabCheckArt, rawTable, TTLCache);
}
// cerco nella tabella: se ci fosse --> disabilitato delete
bool usato = false;
if (artList != null && artList.Count > 0)
{
usato = artList.Contains(codArticolo);
}
answ = !usato;
redisDb.StringSet(redKeyArtUsed, $"{answ}", TTLCache);
}
catch
{ }
}
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"ArticoloDelEnabled | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return answ;
}
public string CalcRecipe(RecipeModel currRecipe)
{
using var activity = ActivitySource.StartActivity("CalcRecipe");
var result = mongoController.CalcRecipe(currRecipe);
activity?.SetTag("data.source", "MONGO");
return result;
}
/// <summary>
/// Recupero tab config in modalità Sincrona
/// </summary>
/// <returns></returns>
public List<ConfigModel> ConfigGetAll()
{
using var activity = ActivitySource.StartActivity("ConfigGetAll");
string source = "REDIS";
List<ConfigModel>? result = new List<ConfigModel>();
// cerco in redis...
RedisValue rawData = redisDb.StringGet(Utils.redisConfKey);
if (!string.IsNullOrEmpty($"{rawData}"))
{
result = JsonConvert.DeserializeObject<List<ConfigModel>>($"{rawData}");
}
else
{
source = "DB";
result = dbController.ConfigGetAll();
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(Utils.redisConfKey, rawData, getRandTOut(redisLongTimeCache));
}
if (result == null)
{
result = new List<ConfigModel>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"ConfigGetAll Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Recupero tab config in modalità Asincrona
/// </summary>
/// <returns></returns>
public async Task<List<ConfigModel>> ConfigGetAllAsync()
{
using var activity = ActivitySource.StartActivity("ConfigGetAllAsync");
string source = "REDIS";
List<ConfigModel>? result = new List<ConfigModel>();
// cerco in redis...
RedisValue rawData = await redisDb.StringGetAsync(Utils.redisConfKey);
if (!string.IsNullOrEmpty($"{rawData}"))
{
result = JsonConvert.DeserializeObject<List<ConfigModel>>($"{rawData}");
source = "REDIS";
}
else
{
result = await Task.FromResult(dbController.ConfigGetAll());
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
await redisDb.StringSetAsync(Utils.redisConfKey, rawData, getRandTOut(redisLongTimeCache));
}
if (result == null)
{
result = new List<ConfigModel>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"ConfigGetAllAsync Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Reset dati cache config
/// </summary>
/// <returns></returns>
public async Task ConfigResetCache()
{
using var activity = ActivitySource.StartActivity("ConfigResetCache");
string source = "REDIS";
await redisDb.StringSetAsync(Utils.redisConfKey, "");
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"ConfigResetCache Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
}
/// <summary>
/// Restituisce valore della stringa (SE disponibile)
/// </summary>
/// <param name="keyName"></param>
/// <returns></returns>
public string ConfigTryGet(string keyName)
{
string answ = "";
using var activity = ActivitySource.StartActivity("ConfigTryGet");
string source = "DB+REDIS";
// preselezione valori
if (configData == null || configData.Count == 0)
{
configData = ConfigGetAll();
}
var currRec = configData.FirstOrDefault(x => x.Chiave == keyName);
// se non trovato provo a ricaricare..
if (currRec == null)
{
configData = ConfigGetAll();
currRec = configData.FirstOrDefault(x => x.Chiave == keyName);
}
// verifico se ci sia il dato...
if (currRec != null)
{
answ = currRec.Valore;
}
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"ConfigTryGet Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return answ;
}
/// <summary>
/// Restituisce valore della stringa (SE disponibile) - modalità async
/// </summary>
/// <param name="keyName"></param>
/// <returns></returns>
public async Task<string> ConfigTryGetAsync(string keyName)
{
string answ = "";
using var activity = ActivitySource.StartActivity("ConfigTryGetAsync");
string source = "DB+REDIS";
// preselezione valori
if (configData == null || configData.Count == 0)
{
configData = await ConfigGetAllAsync();
}
var currRec = configData.FirstOrDefault(x => x.Chiave == keyName);
// se non trovato provo a ricaricare..
if (currRec != null)
{
configData = await ConfigGetAllAsync();
currRec = configData.FirstOrDefault(x => x.Chiave == keyName);
}
// verifico se ci sia il dato...
if (currRec != null)
{
answ = currRec.Valore;
}
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"ConfigTryGetAsync Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return answ;
}
/// <summary>
/// Update chiave config
/// </summary>
/// <returns></returns>
public bool ConfigUpdate(ConfigModel updRec)
{
using var activity = ActivitySource.StartActivity("ConfigUpdate");
string source = "DB";
var updRes = dbController.ConfigUpdate(updRec);
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"ConfigUpdate Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return updRes;
}
/// <summary>
/// Restituisce le statistiche di DB maintenance eseguite
/// </summary>
/// <returns></returns>
public Dictionary<DateTime, double> DbDedupStats()
{
using var activity = ActivitySource.StartActivity("DbDedupStats");
string source = "REDIS";
Dictionary<DateTime, double> actStats = new Dictionary<DateTime, double>();
string currKey = $"{Utils.redisStatsDbMaint}";
// recupero i record statistiche correnti
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
var rawStats = JsonConvert.DeserializeObject<Dictionary<DateTime, double>>($"{rawData}");
if (rawStats != null)
{
actStats = rawStats;
}
}
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"DbDedupStats Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return actStats;
}
/// <summary>
/// Dispose del connettore ai dati
/// </summary>
public void Dispose()
{
// Clear database controller
dbController.Dispose();
mongoController.Dispose();
redisConn.Dispose();
}
/// <summary>
/// Eliminazione di un dossier
/// </summary>
/// <param name="selRecord">record dossier da eliminare</param>
/// <returns></returns>
public async Task<bool> DossiersDeleteRecord(DossierModel selRecord)
{
using var activity = ActivitySource.StartActivity("DossiersDeleteRecord");
bool result = false;
result = await dbController.DossiersDeleteRecord(selRecord);
// elimino cache redis...
RedisValue pattern = new RedisValue($"{Utils.redisDossByMac}:*");
bool answ = await ExecFlushRedisPatternAsync(pattern);
activity?.SetTag("data.source", "DB+REDIS");
activity?.Stop();
LogTrace($"DossiersDeleteRecord | IdxMacchina {selRecord.IdxMacchina} | DtRif {selRecord.DtRif} | IdxODL {selRecord.IdxODL} | {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Elenco ultimi n record DOssiers (che contengono ad esempio "salvataggi" di FLuxLog) dato
/// idxMaccSel (ordinato x data registrazione)
/// </summary>
/// <param name="IdxMacchina">* = tutte, altrimenti solo x una data idxMaccSel</param>
/// <param name="DtStart">Data minima per estrazione records</param>
/// <param name="DtEnd">Data Massima per estrazione records</param>
/// <param name="MaxRec">Num Max records da recuperare</param>
/// <returns></returns>
public async Task<List<DossierModel>> DossiersGetLastFilt(string IdxMacchina, string CodArticolo, DateTime DtStart, DateTime DtEnd, int MaxRec)
{
using var activity = ActivitySource.StartActivity("DossiersGetLastFiltAsync");
List<DossierModel>? result = new List<DossierModel>();
string source = "DB";
string currKey = $"{Utils.redisDossByMac}:{IdxMacchina}:{CodArticolo}:{DtStart:yyyyMMddHHmm}:{DtEnd:yyyyMMddHHmm}:{MaxRec}";
// cerco in redis dato valore sel idxMaccSel...
RedisValue rawData = await redisDb.StringGetAsync(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<DossierModel>>($"{rawData}");
source = "REDIS";
}
else
{
result = await dbController.DossiersGetLastFiltAsync(IdxMacchina, CodArticolo, DtStart, DtEnd, MaxRec);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
await redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache / 5));
}
if (result == null)
{
result = new List<DossierModel>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"DossiersGetLastFiltAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Inserimento nuovo record dossier
/// </summary>
/// <param name="currDoss"></param>
/// <returns></returns>
public async Task<bool> DossiersInsert(DossierModel currDoss)
{
using var activity = ActivitySource.StartActivity("DossiersInsert");
string source = "DB";
// aggiorno record sul DB
bool answ = await dbController.DossiersInsert(currDoss);
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"DossiersInsert | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return answ;
}
/// <summary>
/// Effettua salvataggio snapshot parametri (con stored) + svuota eventuale cache redis
/// </summary>
/// <param name="IdxMacchina">idxMaccSel</param>
/// <param name="MaxSec">NUm massimo secondi per recuperare dati correnti</param>
/// <param name="DtRif">DataOra riferimento x cui prendere valori antecedenti</param>
/// <returns></returns>
public async Task<bool> DossiersTakeParamsSnapshotLast(string IdxMacchina, DateTime dtMin, DateTime dtMax)
{
using var activity = ActivitySource.StartActivity("DossiersUpdateValore");
string source = "DB+REDIS";
bool answ = false;
Log.Info($"Richiesta snapshot per idxMaccSel {IdxMacchina} | periodo {dtMin} --> {dtMax}");
// chiamo stored x salvare parametri
dbController.DossiersTakeParamsSnapshotLast(IdxMacchina, dtMin, dtMax);
// elimino cache redis...
RedisValue pattern = new RedisValue($"{Utils.redisDossByMac}:*");
answ = await ExecFlushRedisPatternAsync(pattern);
activity?.SetTag("data.source", "DB+REDIS");
activity?.Stop();
LogTrace($"DossiersTakeParamsSnapshotLast | Svuotata cache dossier | {pattern} | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return answ;
}
/// <summary>
/// Update valore dossier
/// </summary>
/// <param name="currDoss"></param>
/// <returns></returns>
public async Task<bool> DossiersUpdateValore(DossierModel currDoss)
{
using var activity = ActivitySource.StartActivity("DossiersUpdateValore");
string source = "DB";
// aggiorno record sul DB
bool answ = await dbController.DossiersUpdateValore(currDoss);
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"DossiersUpdateValore | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return answ;
}
/// <summary>
/// Restitusice elenco aziende
/// </summary>
/// <returns></returns>
public List<AnagGruppiModel> ElencoAziende()
{
using var activity = ActivitySource.StartActivity("ElencoAziende");
string source = "DB";
var listAz = dbController.AnagGruppiAziende();
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"ElencoAziende | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return listAz;
}
/// <summary>
/// Restitusice elenco Fasi
/// </summary>
/// <returns></returns>
public List<AnagGruppiModel> ElencoGruppiFase()
{
using var activity = ActivitySource.StartActivity("ElencoGruppiFase");
List<AnagGruppiModel> result = new List<AnagGruppiModel>();
string source = "DB";
string currKey = $"{Utils.redisAnagGruppi}:FASE";
// cerco in redis dato valore sel idxMaccSel...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
var rawResult = JsonConvert.DeserializeObject<List<AnagGruppiModel>>($"{rawData}");
if (rawResult != null)
{
result = rawResult;
}
source = "REDIS";
}
else
{
result = dbController.AnagGruppiFase();
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache / 5));
}
if (result == null)
{
result = new List<AnagGruppiModel>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"ElencoGruppiFase | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Elenco link validi
/// </summary>
/// <returns></returns>
public List<LinkMenuModel> ElencoLink()
{
using var activity = ActivitySource.StartActivity("ElencoLink");
string source = "DB";
var linkList = dbController.ElencoLink();
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"ElencoLink | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return linkList;
}
/// <summary>
/// Restitusice elenco Reparti
/// </summary>
/// <returns></returns>
public List<RepartiDTO> ElencoRepartiDTO()
{
using var activity = ActivitySource.StartActivity("ElencoRepartiDTO");
List<RepartiDTO> result = new List<RepartiDTO>();
string source = "DB";
string currKey = $"{Utils.redisAnagGruppi}:REPARTO";
// cerco in redis dato valore sel idxMaccSel...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
var rawResult = JsonConvert.DeserializeObject<List<RepartiDTO>>($"{rawData}");
if (rawResult != null)
{
result = rawResult;
}
source = "REDIS";
}
else
{
result = dbController.AnagGruppiRepartoDTO();
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
}
if (result == null)
{
result = new List<RepartiDTO>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"ElencoRepartiDTO | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Aggiunta record EventList
/// </summary>
/// <param name="newRec"></param>
/// <returns></returns>
public async Task<bool> EvListInsert(EventListModel newRec)
{
using var activity = ActivitySource.StartActivity("EvListInsert");
string source = "DB";
var result = await dbController.EvListInsert(newRec);
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"EvListInsert | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Esegue flush memoria redis dato keyVal
/// </summary>
/// <param name="pat2Flush"></param>
/// <returns></returns>
public bool ExecFlushRedisPattern(string pat2Flush)
{
using var activity = ActivitySource.StartActivity("ExecFlushRedisPattern");
string source = "REDIS";
bool answ = false;
var masterEndpoint = redisConn.GetEndPoints()
.Where(ep => redisConn.GetServer(ep).IsConnected && !redisConn.GetServer(ep).IsReplica)
.FirstOrDefault();
// sepattern è "*" elimino intero DB...
if (masterEndpoint != null && (pat2Flush.Equals(new RedisValue("*")) || pat2Flush == RedisValue.Null))
{
redisConn.GetServer(masterEndpoint).FlushDatabase(database: redisDb.Database);
}
else
{
var server = redisConn.GetServer(masterEndpoint);
var keys = server.Keys(database: redisDb.Database, pattern: pat2Flush, pageSize: 1000);
var batch = new List<RedisKey>();
foreach (var key in keys)
{
batch.Add(key);
// Flush in batches of 1000
if (batch.Count >= 1000)
{
foreach (var item in batch)
redisDb.KeyDelete(item);
batch.Clear();
}
}
// Flush remaining keys
foreach (var item in batch)
redisDb.KeyDelete(item);
}
answ = true;
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"ExecFlushRedisPattern | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return answ;
}
/// <summary>
/// Esegue flush memoria redis dato keyVal, async
/// </summary>
/// <param name="pat2Flush"></param>
/// <returns></returns>
public async Task<bool> ExecFlushRedisPatternAsync(RedisValue pat2Flush)
{
bool answ = false;
using var activity = ActivitySource.StartActivity("ExecFlushRedisPatternAsync");
string source = "REDIS";
var masterEndpoint = redisConn.GetEndPoints()
.Where(ep => redisConn.GetServer(ep).IsConnected && !redisConn.GetServer(ep).IsReplica)
.FirstOrDefault();
// sepattern è "*" elimino intero DB...
if (masterEndpoint != null && (pat2Flush.Equals(new RedisValue("*")) || pat2Flush == RedisValue.Null))
{
redisConn.GetServer(masterEndpoint).FlushDatabase(database: redisDb.Database);
}
else
{
var server = redisConn.GetServer(masterEndpoint);
var keys = server.Keys(database: redisDb.Database, pattern: pat2Flush, pageSize: 1000);
var deleteTasks = new List<Task>();
foreach (var key in keys)
{
deleteTasks.Add(redisDb.KeyDeleteAsync(key));
if (deleteTasks.Count >= 1000)
{
await Task.WhenAll(deleteTasks);
deleteTasks.Clear();
}
}
if (deleteTasks.Count > 0)
{
await Task.WhenAll(deleteTasks);
}
}
answ = true;
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"ExecFlushRedisPatternAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return answ;
}
/// <summary>
/// Imposta in redis la scadenza della pagina x il reload
/// </summary>
/// <param name="expTime"></param>
/// <returns></returns>
public DateTime ExpiryReloadParamGet()
{
using var activity = ActivitySource.StartActivity("ExpiryReloadParamGet");
string source = "REDIS";
DateTime dtRif = DateTime.Now;
string currKey = $"{Utils.redisParamPageExp}";
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
dtRif = JsonConvert.DeserializeObject<DateTime>($"{rawData}");
}
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"ExpiryReloadParamGet | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return dtRif;
}
/// <summary>
/// Imposta in redis la scadenza della pagina x il reload
/// </summary>
/// <param name="expTime"></param>
/// <returns></returns>
public bool ExpiryReloadParamSet(DateTime expTime)
{
using var activity = ActivitySource.StartActivity("ExpiryReloadParamSet");
string source = "REDIS";
bool fatto = false;
string currKey = $"{Utils.redisParamPageExp}";
string rawData = JsonConvert.SerializeObject(expTime);
fatto = redisDb.StringSet(currKey, rawData);
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"ExpiryReloadParamSet | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return fatto;
}
public async Task<bool> FlushCacheFluxLog()
{
using var activity = ActivitySource.StartActivity("FlushCacheFluxLog");
string source = "REDIS";
bool answ = false;
RedisValue pattern = new RedisValue($"{Utils.redisParetoFLKey}:*");
answ = await ExecFlushRedisPatternAsync(pattern);
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"FlushCacheFluxLog | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return answ;
}
/// <summary>
/// Flush cache relativa a MP-IO x dati ODL
/// </summary>
/// <returns></returns>
public async Task<bool> FlushMpIoOdlCache()
{
using var activity = ActivitySource.StartActivity("FlushMpIoOdlCache");
string source = "REDIS";
// svuoto dalla cache REDIS del server IO...
bool ok01 = await ResetIoCache("CurrODL");
bool ok02 = await ResetIoCache("CurrOdlRow");
bool ok03 = await ResetIoCache("CurrStatoMacc");
bool ok04 = await ResetIoCache("DtMac");
activity?.SetTag("data.source", "REDIS");
activity?.Stop();
LogTrace($"FlushMpIoOdlCache | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return ok01 && ok02 && ok03 && ok04;
}
public async Task<bool> FlushRedisCache()
{
using var activity = ActivitySource.StartActivity("FlushRedisCache");
string source = "REDIS";
RedisValue pattern = Utils.RedValue("*");
bool answ = await ExecFlushRedisPatternAsync(pattern);
// rileggo vocabolario.,..
ObjVocabolario = VocabolarioGetAll();
activity?.Stop();
LogTrace($"FlushRedisCache | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return answ;
}
public async Task<bool> FlushRedisKey(string redKey)
{
using var activity = ActivitySource.StartActivity("FlushRedisKey");
string source = "REDIS";
RedisValue pattern = Utils.RedValue(redKey);
bool answ = await ExecFlushRedisPatternAsync(pattern);
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"FlushRedisKey | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return answ;
}
/// <summary>
/// Funzione di Data Reduction x FluxLog
/// </summary>
/// <param name="idxMaccSel">Macchina</param>
/// <param name="fluxList">Elenco FL da processare</param>
/// <param name="currPeriodo">Periodo</param>
/// <param name="valMode">modalità sel valore</param>
/// <param name="intReq">intervallo di analisi</param>
/// <param name="maxItem">max num per intervallo</param>
/// <returns></returns>
public async Task FluxLogDataRedux(string idxMaccSel, List<string> fluxList, DtUtils.Periodo currPeriodo, Enums.ValSelection valMode, Enums.DataInterval intReq, int maxItem)
{
using var activity = ActivitySource.StartActivity("FluxLogDataRedux");
string source = "DB+REDIS";
List<StatDedupDTO> procStats = await dbController.FluxLogDataRedux(idxMaccSel, fluxList, currPeriodo, valMode, intReq, maxItem);
// effettuo merge statistiche...
ProcDedupStatMerge(procStats);
// svuoto cache
await FlushCacheFluxLog();
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"FluxLogDataRedux | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
}
public List<FluxLogDTO> FluxLogDtoGetByFlux(string Valore)
{
List<FluxLogDTO> answ = new List<FluxLogDTO>();
DossierFluxLogDTO? result = JsonConvert.DeserializeObject<DossierFluxLogDTO>(Valore);
if (result != null)
{
if (result.ODL != null)
{
answ = result
.ODL
.OrderBy(x => x.CodFlux)
.ToList();
// inizializzo SE necessario
foreach (var item in answ)
{
item.ValoreEdit = String.IsNullOrEmpty(item.ValoreEdit) ? item.Valore : item.ValoreEdit;
}
}
}
return answ;
}
/// <summary>
/// Elenco ultimi n record flux log dato idxMaccSel e flusso (ordinato x data registrazione)
/// </summary>
/// <param name="DtMax">Data massima x eventi</param>
/// <param name="DtMin">Data minima x eventi</param>
/// <param name="IdxMacchina">* = tutte, altrimenti solo x una data idxMaccSel</param>
/// <param name="CodFlux">*=tutti, altrimenti solo selezionato</param>
/// <param name="MaxRec">numero massimo record da restituire</param>
/// <returns></returns>
public async Task<List<FluxLogModel>> FluxLogGetLastFilt(DateTime DtMax, DateTime DtMin, string IdxMacchina, string CodFlux, int MaxRec, double redisCacheSec)
{
using var activity = ActivitySource.StartActivity("FluxLogGetLastFilt");
List<FluxLogModel>? result = new List<FluxLogModel>();
string source = "DB";
string currKey = $"{Utils.redisFluxLogFilt}:{IdxMacchina}:{CodFlux}:{MaxRec}:{DtMax:yyyyMMddHHmm}:{DtMin:yyyyMMddHHmm}";
// cerco in redis dato valore sel idxMaccSel...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<FluxLogModel>>($"{rawData}");
source = "REDIS";
}
else
{
result = await Task.FromResult(dbController.FluxLogGetLastFilt(DtMax, DtMin, IdxMacchina, CodFlux, MaxRec));
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
if (string.IsNullOrEmpty(canCacheParametri))
{
canCacheParametri = await ConfigTryGetAsync("SPEC_ParametriEnableRedisCache");
}
if (canCacheParametri != "false")
{
redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(redisCacheSec));
}
}
if (result == null)
{
result = new List<FluxLogModel>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"FluxLogGetLastFilt | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Elenco Gruppi
/// </summary>
/// <returns></returns>
public async Task<List<ParetoFluxLogDTO>> FluxLogPareto(string idxMacchina, DateTime dtFrom, DateTime dtTo)
{
using var activity = ActivitySource.StartActivity("FluxLogPareto");
string source = "DB";
List<ParetoFluxLogDTO>? result = new List<ParetoFluxLogDTO>();
// cerco in redis...
string redKey = $"{Utils.redisParetoFLKey}:{idxMacchina}:{dtFrom:yyyyMMdd}:{dtTo:yyyyMMdd}";
RedisValue rawData = await redisDb.StringGetAsync(redKey);
if (!string.IsNullOrEmpty($"{rawData}"))
{
result = JsonConvert.DeserializeObject<List<ParetoFluxLogDTO>>($"{rawData}");
source = "REDIS";
}
else
{
result = await Task.FromResult(dbController.FluxLogPareto(idxMacchina, dtFrom, dtTo));
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
await redisDb.StringSetAsync(redKey, rawData, getRandTOut(redisLongTimeCache));
}
if (result == null)
{
result = new List<ParetoFluxLogDTO>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"FluxLogPareto | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Stored manutenzione del DB
/// </summary>
/// <param name="doExec">Esegue realmente il task</param>
/// <param name="doUpdStat">Aggiornamento statistiche</param>
/// <param name="doSave">Salvataggio</param>
/// <param name="minPgCnt">def: 1000</param>
/// <param name="minAvgFrag">def: 10</param>
/// <param name="maxAvgFragReb">def: 50</param>
/// <returns></returns>
public async Task ForceDbMaint(bool doExec = true, bool doUpdStat = true, bool doSave = true, int minPgCnt = 1000, int minAvgFrag = 10, int maxAvgFragReb = 50)
{
using var activity = ActivitySource.StartActivity("ForceDbMaint");
string source = "DB+REDIS";
await dbController.ForceDbMaint(doExec, doUpdStat, doSave, minPgCnt, minAvgFrag, maxAvgFragReb);
// svuoto cache
await FlushCacheFluxLog();
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"ForceDbMaint | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
// registro statistiche esecuzione
RecDbMaintStat(activity?.Duration ?? TimeSpan.FromSeconds(1));
}
/// <summary>
/// Eliminazione di un record macchina dal gruppo
/// </summary>
/// <param name="rec2del"></param>
/// <returns></returns>
public bool Grp2MaccDelete(Gruppi2MaccModel rec2del)
{
using var activity = ActivitySource.StartActivity("Grp2MaccDelete");
bool result = false;
result = dbController.Grp2MaccDelete(rec2del);
// elimino cache redis...
ResetMacGrpCache();
activity?.SetTag("data.source", "DB+REDIS");
activity?.Stop();
LogTrace($"Grp2MaccDelete | CodGruppo {rec2del.CodGruppo} | IdxMacc {rec2del.IdxMacchina} | {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Insert di un record macchina
/// </summary>
/// <param name="upsRec"></param>
/// <returns></returns>
public bool Grp2MaccInsert(Gruppi2MaccModel upsRec)
{
using var activity = ActivitySource.StartActivity("Grp2MaccInsert");
bool result = false;
result = dbController.Grp2MaccInsert(upsRec);
// elimino cache redis...
ResetMacGrpCache();
activity?.SetTag("data.source", "DB+REDIS");
activity?.Stop();
LogTrace($"Grp2MaccInsert | CodGruppo {upsRec.CodGruppo} | IdxMacc {upsRec.IdxMacchina} | {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Eliminazione di un record operatore dal gruppo
/// </summary>
/// <param name="rec2del"></param>
/// <returns></returns>
public bool Grp2OperDelete(Gruppi2OperModel rec2del)
{
using var activity = ActivitySource.StartActivity("Grp2OperDelete");
bool result = false;
result = dbController.Grp2OperDelete(rec2del);
// elimino cache redis...
ResetOprGrpCache();
activity?.SetTag("data.source", "DB+REDIS");
activity?.Stop();
LogTrace($"Grp2OperDelete | CodGruppo {rec2del.CodGruppo} | MatrOpr {rec2del.MatrOpr} | {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Insert di un record operatore
/// </summary>
/// <param name="upsRec"></param>
/// <returns></returns>
public bool Grp2OperInsert(Gruppi2OperModel upsRec)
{
using var activity = ActivitySource.StartActivity("Grp2OperInsert");
bool result = false;
result = dbController.Grp2OperInsert(upsRec);
// elimino cache redis...
ResetOprGrpCache();
activity?.SetTag("data.source", "DB+REDIS");
activity?.Stop();
LogTrace($"Grp2OperInsert | CodGruppo {upsRec.CodGruppo} | MatrOpr {upsRec.MatrOpr} | {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Init ricetta
/// </summary>
/// <param name="confPath"></param>
/// <param name="idxPODL"></param>
/// <param name="CalcArgs"></param>
/// <returns></returns>
public RecipeModel InitRecipe(string confPath, int idxPODL, Dictionary<string, string> CalcArgs)
{
return mongoController.InitRecipe(confPath, idxPODL, CalcArgs);
}
/// <summary>
/// Recupero info IOB x TAB (da info registrate IOB-WIN--&gt; MP-IO)
/// </summary>
/// <param name="IdxMacchina"></param>
/// <returns></returns>
public async Task<IOB_data> IobInfo(string IdxMacchina)
{
using var activity = ActivitySource.StartActivity("IobInfo");
string source = "DB";
IOB_data? result = new IOB_data();
// cerco in redis...
string currKey = redHashMpIO($"hM2IOB:{IdxMacchina}");
RedisValue rawData = await redisDb.StringGetAsync(currKey);
//if (!string.IsNullOrEmpty($"{rawData}"))
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<IOB_data>($"{rawData}");
source = "REDIS";
}
else
{
Log.Error($"Errore: non trovato valore <IOB_data> valido in REDIS | key: {currKey}");
Log.Info($"REDIS | conf: {redisConn.Configuration}");
Log.Info($" --> Valore trovato:{Environment.NewLine}{rawData}");
}
if (result == null)
{
result = new IOB_data();
LogTrace($"Init valore default <IOB_data> | IdxMacchina: {IdxMacchina}");
}
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"IobInfo per {IdxMacchina} | {source} | {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Elimina record + svuotamento cache
/// </summary>
/// <param name="currRecord"></param>
public async Task<bool> IstKitDelete(IstanzeKitModel currRecord)
{
using var activity = ActivitySource.StartActivity("IstKitDelete");
string source = "DB+REDIS";
bool fatto = false;
// salvo
fatto = dbController.IstKitDelete(currRecord);
// svuoto cache
RedisValue pattern = $"{Utils.redisKitInst}:*";
await ExecFlushRedisPatternAsync(pattern);
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"IstKitDelete | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return fatto;
}
/// <summary>
/// Elenco Istanze KIT da ricerca
/// </summary>
/// <param name="keyKit"></param>
/// <param name="keyExtOrd"></param>
/// <returns></returns>
public List<IstanzeKitModel> IstKitFilt(string keyKit, string keyExtOrd)
{
using var activity = ActivitySource.StartActivity("IstKitFilt");
string source = "DB";
List<IstanzeKitModel>? result = new List<IstanzeKitModel>();
// cerco in redis...
string currKey = $"{Utils.redisKitInst}:{keyKit}:{keyExtOrd}";
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<IstanzeKitModel>>($"{rawData}");
source = "REDIS";
}
else
{
result = dbController.IstKitFilt(keyKit, keyExtOrd);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, TimeSpan.FromMinutes(redisLongTimeCache));
}
if (result == null)
{
result = new List<IstanzeKitModel>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"IstKitFilt | {source} | {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Effettua creazione istanza KIT
/// </summary>
/// <param name="CodArtParent">Articolo KIT (fittizio)</param>
/// <param name="KeyFilt">Chiave x filtro conf su tab WKS</param>
public bool IstKitInsertByWKS(string CodArtParent, string KeyFilt)
{
bool fatto = false;
using var activity = ActivitySource.StartActivity("IstKitInsertByWKS");
string source = "DB+REDIS";
// salvo
fatto = dbController.IstKitInsertByWKS(CodArtParent, KeyFilt);
// svuoto cache
ExecFlushRedisPattern($"{Utils.redisKit}:*");
//ExecFlushRedisPattern((RedisValue)$"{Utils.redisKitInst}:*");
//ExecFlushRedisPattern((RedisValue)$"{Utils.redisKitScore}:*");
//ExecFlushRedisPattern((RedisValue)$"{Utils.redisKitTempl}:*");
//ExecFlushRedisPattern((RedisValue)$"{Utils.redisKitWip}:*");
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"IstKitInsertByWKS | {source} | {activity?.Duration.TotalMilliseconds}ms");
return fatto;
}
/// <summary>
/// Esegue salvataggio record + svuotamento cache
/// </summary>
/// <param name="currRecord"></param>
public async Task<bool> IstKitUpsert(IstanzeKitModel currRecord)
{
using var activity = ActivitySource.StartActivity("IstKitUpsert");
string source = "DB+REDIS";
bool fatto = false;
// salvo
fatto = dbController.IstKitUpsert(currRecord);
// svuoto cache
RedisValue pattern = $"{Utils.redisKitInst}:*";
await ExecFlushRedisPatternAsync(pattern);
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"IstKitUpsert | {source} | {activity?.Duration.TotalMilliseconds}ms");
return fatto;
}
/// <summary>
/// </summary>
/// <param name="IdxOdl">id odl da cercare</param>
/// <returns></returns>
public async Task<List<AnagGiacenzeModel>> ListGiacenze(int IdxOdl)
{
using var activity = ActivitySource.StartActivity("ListGiacenze");
List<AnagGiacenzeModel>? result = new List<AnagGiacenzeModel>();
string source = "DB";
string currKey = $"{Utils.redisGiacenzaList}:{IdxOdl}";
// cerco in redis dato valore sel idxMaccSel...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<AnagGiacenzeModel>>($"{rawData}");
source = "REDIS";
}
else
{
result = await Task.FromResult(dbController.ListGiacenze(IdxOdl));
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(redisShortTimeCache));
}
if (result == null)
{
result = new List<AnagGiacenzeModel>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"ListGiacenze | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Recupero elenco PODL filtrati
/// </summary>
/// <param name="CodArticolo"></param>
/// <param name="OnlyAvail">True = aperti (=senza ODL)</param>
/// <returns></returns>
public List<PODLExpModel> ListPODL_ByCodArt(string CodArticolo, bool OnlyAvail)
{
List<PODLExpModel> result = new List<PODLExpModel>();
if (!string.IsNullOrEmpty(CodArticolo))
{
using var activity = ActivitySource.StartActivity("ListPODL_ByCodArt");
string source = "DB";
string avType = OnlyAvail ? "Avail" : "ALL";
string currKey = $"{Utils.redisPOdlByCodArt}:{CodArticolo}:{avType}";
// cerco in redis dato valore sel idxMaccSel...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue && rawData.Length() > 2)
{
var rawResult = JsonConvert.DeserializeObject<List<PODLExpModel>>($"{rawData}");
if (rawResult != null)
{
result = rawResult;
source = "REDIS";
}
}
else
{
result = dbController.ListPODL_ByCodArt(CodArticolo, OnlyAvail);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
}
if (result == null)
{
result = new List<PODLExpModel>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
Log.Trace($"ListPODL_ByCodArt | {source} | {activity?.Duration.TotalMilliseconds}ms");
}
else
{
Log.Debug("Errore CodArt vuoto");
}
return result;
}
/// <summary>
/// Elenco di tutte le macchine filtrate x gruppo
/// </summary>
/// <param name="codGruppo"></param>
/// <returns></returns>
public List<MacchineModel> MacchineGetFilt(string codGruppo)
{
using var activity = ActivitySource.StartActivity("MacchineGetFilt");
List<MacchineModel>? result = new List<MacchineModel>();
string source = "DB";
string keyGrp = codGruppo != "*" ? codGruppo : "ALL";
string currKey = $"{Utils.redisMacList}:{keyGrp}";
// cerco in redis dato valore sel idxMaccSel...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<MacchineModel>>($"{rawData}");
source = "REDIS";
}
else
{
result = dbController.MacchineGetFilt(codGruppo);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
}
if (result == null)
{
result = new List<MacchineModel>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", 1);
activity?.Stop();
LogTrace($"MacchineGetAll | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Verifica se la idxMaccSel abbia un codice PATH ricette associato
/// </summary>
/// <param name="idxMacchina"></param>
/// <returns></returns>
public string MacchineRecipeArchive(string idxMacchina)
{
using var activity = ActivitySource.StartActivity("MacchineRecipeArchive");
string? result = "";
string source = "DB";
string currKey = $"{Utils.redisMacRecipePath}:{idxMacchina}";
// cerco in redis dato valore sel idxMaccSel...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<string>($"{rawData}");
source = "REDIS";
}
else
{
//recupero elenco macchine...
var machineList = MacchineGetFilt("*");
var currMach = machineList.Where(x => x.IdxMacchina == idxMacchina).FirstOrDefault();
result = currMach != null ? currMach.RecipeArchivePath : null;
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", 1);
activity?.Stop();
LogTrace($"MacchineRecipeArchive | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return result ?? "";
}
/// <summary>
/// Verifica se la idxMaccSel abbia un codice CONF ricetta associato
/// </summary>
/// <param name="idxMacchina"></param>
/// <returns></returns>
public string MacchineRecipeConf(string idxMacchina)
{
using var activity = ActivitySource.StartActivity("MacchineRecipeConf");
string? result = "";
string source = "DB";
string currKey = $"{Utils.redisMacRecipeConf}:{idxMacchina}";
// cerco in redis dato valore sel idxMaccSel...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<string>($"{rawData}");
source = "REDIS";
}
else
{
//recupero elenco macchine...
var machineList = MacchineGetFilt("*");
var currMach = machineList.Where(x => x.IdxMacchina == idxMacchina).FirstOrDefault();
result = currMach != null ? currMach.RecipePath : null;
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", 1);
activity?.Stop();
LogTrace($"MacchineRecipeConf | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return result ?? "";
}
/// <summary>
/// Elenco id Macchine che abbiano dati FLuxLog, nel periodo indicato
/// </summary>
/// <param name="dtStart"></param>
/// <param name="dtEnd"></param>
/// <returns></returns>
public async Task<List<string>> MacchineWithFlux(DateTime dtStart, DateTime dtEnd)
{
using var activity = ActivitySource.StartActivity("MacchineWithFlux");
List<string>? result = new List<string>();
string source = "DB";
string currKey = $"{Utils.redisMacByFlux}:{dtStart:yyyyMMddHHmm}:{dtEnd:yyyyMMddHHmm}";
// cerco in redis dato valore sel idxMaccSel...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<string>>($"{rawData}");
source = "REDIS";
}
else
{
result = await dbController.MacchineWithFlux(dtStart, dtEnd);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
}
if (result == null)
{
result = new List<string>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"MacchineWithFlux | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Recupero info Machine-IOB x TAB (da info registrate IOB-WIN --&gt; MP-IO)
/// </summary>
/// <param name="IdxMacchina"></param>
/// <returns></returns>
public Dictionary<string, string> MachIobConf(string IdxMacchina)
{
using var activity = ActivitySource.StartActivity("MachIobConf");
string source = "DB";
Dictionary<string, string> result = new Dictionary<string, string>();
// cerco in redis...
string currKey = redHashMpIO($"IOB:{IdxMacchina}:MachIobConf");
try
{
result = redisDb
.HashGetAll(currKey)
.ToDictionary(x => $"{x.Name}", x => $"{x.Value}");
source = "REDIS";
}
catch (Exception exc)
{
Log.Error($"Errore in MachIobConf{Environment.NewLine}{exc}");
}
if (result == null)
{
result = new Dictionary<string, string>();
LogTrace($"Init valore default MachIobConf | IdxMacchina: {IdxMacchina}");
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"MachIobConf per {IdxMacchina} | {source} | {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Recupero singolo recordo info Machine-IOB x TAB (da info registrate IOB-WIN --&gt; MP-IO)
/// </summary>
/// <param name="IdxMacchina"></param>
/// <returns></returns>
public string MachIobConfVal(string IdxMacchina, string Key)
{
string answ = "";
var currList = MachIobConf(IdxMacchina);
if (currList.ContainsKey(Key))
{
answ = currList[Key];
}
return answ;
}
/// <summary>
/// Elenco MSE stato amcchine
/// </summary>
/// <param name="forceDb"></param>
/// <returns></returns>
public async Task<List<MappaStatoExplModel>> MseGetAll(bool forceDb = false)
{
using var activity = ActivitySource.StartActivity("MseGetAllAsync");
string source = "DB";
List<MappaStatoExplModel>? result = new List<MappaStatoExplModel>();
// cerco in redisConn...
RedisValue rawData = redisDb.StringGet(Constants.redisMseKey);
if (rawData.HasValue && !forceDb)
{
result = JsonConvert.DeserializeObject<List<MappaStatoExplModel>>($"{rawData}");
source = "REDIS";
}
else
{
result = await Task.FromResult(dbController.MseGetAll(2000));
// serializzp e salvo...
rawData = JsonConvert.SerializeObject(result);
await redisDb.StringSetAsync(Constants.redisMseKey, rawData, TimeSpan.FromSeconds(1));
}
if (result == null)
{
result = new List<MappaStatoExplModel>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"MseGetAllAsync | {source} | {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Invio notifica rilettura (con parametro)
/// </summary>
/// <param name="message"></param>
public void NotifyReloadRequest(string message)
{
if (ReloadRequest != null)
{
// messaggio
ReloadEventArgs rea = new ReloadEventArgs(message);
ReloadRequest.Invoke(this, rea);
}
}
/// <summary>
/// Elenco ODL dato batch selezionato
/// </summary>
/// <param name="BatchSel">Batch richiesto</param>
/// <returns></returns>
public async Task<List<int>> OdlByBatch(string BatchSel)
{
using var activity = ActivitySource.StartActivity("OdlByBatch");
List<int>? result = new List<int>();
string source = "DB";
string currKey = Utils.redisOdlByBatch;
// cerco in redis dato valore sel idxMaccSel...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<int>>($"{rawData}");
source = "REDIS";
}
else
{
result = await Task.FromResult(dbController.OdlByBatch(BatchSel));
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
}
if (result == null)
{
result = new List<int>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"OdlByBatch | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// ODL da chiave
/// </summary>
/// <param name="IdxOdl"></param>
/// <returns></returns>
public ODLExpModel OdlByKey(int IdxOdl)
{
using var activity = ActivitySource.StartActivity("OdlByKey");
ODLExpModel? result = new ODLExpModel();
string source = "DB";
result = dbController.OdlByKey(IdxOdl);
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"OdlByKey | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Effettua chiusura dell'ODL indicato, andand
/// </summary>
/// <param name="idxOdl">idx odl da chiudere</param>
/// <param name="idxMacchina">idx idxMaccSel</param>
/// <param name="matrOpr">matricola operatore</param>
/// <param name="confPezzi">indica se confermare i pezzi priam di chiudere ODL</param>
public async Task<bool> ODLClose(int idxOdl, string idxMacchina, int matrOpr, bool confPezzi)
{
using var activity = ActivitySource.StartActivity("ODLClose");
string source = "DB";
bool fatto = false;
// recupero dati x conf modalità conferma
var configData = await ConfigGetAllAsync();
if (configData != null)
{
bool confRett = false;
var currRec = configData.FirstOrDefault(x => x.Chiave == "confRett");
if (currRec != null)
{
bool.TryParse(currRec.Valore, out confRett);
}
int modoConfProd = 0;
currRec = configData.FirstOrDefault(x => x.Chiave == "modoConfProd");
if (currRec != null)
{
int.TryParse(currRec.Valore, out modoConfProd);
}
// chiamo metodo conferma!
fatto = await dbController.ODLClose(idxOdl, idxMacchina, matrOpr, confPezzi, confRett, modoConfProd);
}
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"ODLClose | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return fatto;
}
/// <summary>
/// Record ODL da chaive
/// </summary>
/// <returns></returns>
public async Task<ODLModel> OdlGetByKey(int IdxOdl)
{
using var activity = ActivitySource.StartActivity("OdlGetByKey");
string source = "DB";
var dbResult = await dbController.OdlGetByKey(IdxOdl);
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"OdlGetByKey | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return dbResult;
}
/// <summary>
/// ODL correnti (tutti)
/// </summary>
/// <param name="idxMacchina"></param>
/// <returns></returns>
public List<string> OdlGetCurrent()
{
using var activity = ActivitySource.StartActivity("OdlGetCurrent");
List<string>? dbResult = new List<string>();
string source = "DB";
string currKey = $"{Utils.redisOdlCurrByMac}";
// cerco in redis dato valore sel idxMaccSel...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
dbResult = JsonConvert.DeserializeObject<List<string>>($"{rawData}");
source = "REDIS";
}
else
{
dbResult = dbController.OdlGetCurrent().Select(x => x.IdxMacchina).Distinct().ToList();
rawData = JsonConvert.SerializeObject(dbResult);
redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(3));
}
if (dbResult == null)
{
dbResult = new List<string>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", dbResult.Count);
activity?.Stop();
LogTrace($"OdlGetCurrent | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return dbResult;
}
/// <summary>
/// elenco TUTTI gli ODL
/// </summary>
/// <param name="IdxOdl"></param>
/// <returns></returns>
public List<ODLModel> OdlListAll()
{
using var activity = ActivitySource.StartActivity("OdlListAll");
List<ODLModel>? result = new List<ODLModel>();
string source = "DB";
result = dbController.OdlListAll();
activity?.SetTag("data.source", "DB");
activity?.Stop();
LogTrace($"OdlListAll | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Elenco ODL filtrati x stato, articolo, KeyRich (che contiene stato)
/// </summary>
/// <param name="inCorso">Stato ODL: true=in corso/completato</param>
/// <param name="codArt">Cod articolo</param>
/// <param name="keyRichPart">KeyRich (parziale) da cercare (es cod stato x yacht)</param>
/// <param name="Reparto">Reparto selezionato</param>
/// <param name="IdxMacchina">Macchina selezionata</param>
/// <param name="startDate">Data inizio</param>
/// <param name="endDate">Data fine</param>
/// <returns></returns>
public async Task<List<ODLExpModel>> OdlListGetFilt(bool inCorso, string codArt, string keyRichPart, string Reparto, string IdxMacchina, DateTime startDate, DateTime endDate)
{
using var activity = ActivitySource.StartActivity("OdlListGetFilt");
List<ODLExpModel>? result = new List<ODLExpModel>();
string source = "DB";
string currKey = $"{Utils.redisOdlList}:{inCorso}:{codArt}:{keyRichPart}:{Reparto}:{IdxMacchina}:{startDate:yyyyMMdd_HHmmss}:{endDate:yyyyMMdd_HHmmss}";
// cerco in redis dato valore sel idxMaccSel...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<ODLExpModel>>($"{rawData}");
source = "REDIS";
}
else
{
result = await Task.FromResult(dbController.ListODLFilt(inCorso, codArt, keyRichPart, Reparto, IdxMacchina, startDate, endDate));
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(redisShortTimeCache));
}
if (result == null)
{
result = new List<ODLExpModel>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"OdlListGetFilt | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Elenco operatori filtrati x gruppo
/// </summary>
/// <param name="codGruppo"></param>
/// <returns></returns>
public List<AnagOperatoriModel> OperatoriGetFilt(string codGruppo)
{
using var activity = ActivitySource.StartActivity("OperatoriGetFilt");
List<AnagOperatoriModel>? result = new List<AnagOperatoriModel>();
string source = "DB";
string keyGrp = codGruppo != "*" ? codGruppo : "ALL";
string currKey = $"{Utils.redisOprList}:{keyGrp}";
// cerco in redis dato valore sel idxMaccSel...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<AnagOperatoriModel>>($"{rawData}");
source = "REDIS";
}
else
{
result = dbController.OperatoriGetFilt(codGruppo);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
}
if (result == null)
{
result = new List<AnagOperatoriModel>();
}
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"OperatoriGetFilt | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); activity?.SetTag("data.source", source);
return result;
}
/// <summary>
/// Elenco di tutti i parametri filtrati x idxMaccSel
/// </summary>
/// <param name="IdxMacchina">* = tutte, altrimenti solo x una data idxMaccSel</param>
/// <returns></returns>
public async Task<List<string>> ParametriGetFilt(string IdxMacchina)
{
using var activity = ActivitySource.StartActivity("ParametriGetFilt");
List<string>? result = new List<string>();
string source = "DB";
string currKey = $"{Utils.redisFluxByMac}:{IdxMacchina}";
// cerco in redis dato valore sel idxMaccSel...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<string>>($"{rawData}");
source = "REDIS";
}
else
{
result = await Task.FromResult(dbController.ParametriGetFilt(IdxMacchina));
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
}
if (result == null)
{
result = new List<string>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"ParametriGetFilt | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Eliminazione record selezionato
/// </summary>
/// <param name="currRec"></param>
/// <returns></returns>
public async Task<bool> POdlDeleteRecord(PODLExpModel currRec)
{
using var activity = ActivitySource.StartActivity("POdlDeleteRecord");
string source = "DB+REDIS";
var dbResult = await dbController.PODLDeleteRecord(currRec);
// elimino cache redis...
await POdlFlushCache();
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"POdlDeleteRecord | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return dbResult;
}
/// <summary>
/// Avvio fase setup per il record selezionato
/// </summary>
/// <param name="currRec"></param>
/// <returns></returns>
public async Task<bool> POdlDoSetup(PODLExpModel currRec)
{
using var activity = ActivitySource.StartActivity("POdlDoSetup");
string source = "DB+REDIS";
var dbResult = await dbController.PODL_startSetup(currRec, 0, 1, 1, "", DateTime.Now);
// elimino cache redis...
await POdlFlushCache();
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"POdlDoSetup | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return dbResult;
}
/// <summary>
/// Recupero PODL da chiave
/// </summary>
/// <param name="idxPODL"></param>
/// <returns></returns>
public async Task<PODLModel> POdlGetByKey(int idxPODL)
{
PODLModel result = new PODLModel();
if (idxPODL != 0)
{
using var activity = ActivitySource.StartActivity("POdlGetByKey");
string source = "DB";
string currKey = $"{Utils.redisPOdlByPOdl}:{idxPODL}";
// cerco in redis dato valore sel idxMaccSel...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
var rawResult = JsonConvert.DeserializeObject<PODLModel>($"{rawData}");
if (rawResult != null)
{
result = rawResult;
source = "REDIS";
}
}
else
{
result = await dbController.PODL_getByKey(idxPODL);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
}
if (result == null)
{
result = new PODLModel();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", 1);
activity?.Stop();
Log.Trace($"POdlGetByKey | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
}
else
{
Log.Debug("Errore IdxPODL = 0");
}
return result;
}
/// <summary>
/// Recupero PODL da IdxODL
/// </summary>
/// <param name="idxODL"></param>
/// <returns></returns>
public PODLModel POdlGetByOdl(int idxODL)
{
PODLModel result = new PODLModel();
if (idxODL != 0)
{
using var activity = ActivitySource.StartActivity("POdlGetByOdl");
string source = "DB";
string currKey = $"{Utils.redisPOdlByOdl}:{idxODL}";
// cerco in redis dato valore sel idxMaccSel...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
var rawResult = JsonConvert.DeserializeObject<PODLModel>($"{rawData}");
if (rawResult != null)
{
result = rawResult;
}
source = "REDIS";
}
else
{
result = dbController.PODL_getByOdl(idxODL);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
}
if (result == null)
{
result = new PODLModel();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", 1);
activity?.Stop();
Log.Trace($"POdlGetByOdl | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
}
else
{
Log.Debug("Errore IdxODL = 0");
}
return result;
}
/// <summary>
/// Effettua il task di eliminazione PODL KIT + istanze + riattivazione PODL originali disattivate tramite stored
/// </summary>
/// <param name="IdxPODL">IdxPODL parent</param>
public bool PodlIstKitDelete(int IdxPODL)
{
using var activity = ActivitySource.StartActivity("PodlIstKitDelete");
bool fatto = false;
// salvo
fatto = dbController.PodlIstKitDelete(IdxPODL);
// svuoto cache
string pattern = $"{Utils.redisKit}:*";
if (!string.IsNullOrEmpty(pattern))
{
ExecFlushRedisPattern(pattern);
}
activity?.SetTag("data.source", "DB+REDIS");
return fatto;
}
/// <summary>
/// Elenco PODL in un istanza KIT dall'ID del parent
/// </summary>
/// <param name="IdxPodlParent">IDX PODL parent</param>
/// <returns></returns>
public List<PODLExpModel> POdlListByKitParent(int IdxPodlParent)
{
using var activity = ActivitySource.StartActivity("POdlListByKitParent");
List<PODLExpModel>? result = new List<PODLExpModel>();
string source = "DB";
string currKey = $"{Utils.redisPOdlList}_kit:ByParent:{IdxPodlParent}";
// cerco in redis dato valore sel idxMaccSel...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<PODLExpModel>>($"{rawData}");
source = "REDIS";
}
else
{
result = dbController.ListPODL_ByKitParent(IdxPodlParent);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(redisShortTimeCache));
}
if (result == null)
{
result = new List<PODLExpModel>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"POdlListByKitParent | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Elenco PODL non avviati filtrati x articolo, KeyRich (che contiene stato)
/// </summary>
/// <param name="lanciato">Solo lanciati (1) o ancora disponibili (0)</param>
/// <param name="keyRichPart">KeyRich (parziale) da cercare (es cod stato x yacht)</param>
/// <param name="idxMacchina">Macchina</param>
/// <param name="codGruppo">Gruppo</param>
/// <param name="startDate">Data inizio</param>
/// <param name="endDate">Data fine</param>
/// <returns></returns>
public List<PODLExpModel> POdlListGetFilt(bool lanciato, string keyRichPart, string idxMacchina, string codGruppo, DateTime startDate, DateTime endDate)
{
using var activity = ActivitySource.StartActivity("POdlListGetFiltAsync");
List<PODLExpModel>? result = new List<PODLExpModel>();
string source = "DB";
string currKey = $"{Utils.redisPOdlList}:{codGruppo}:{idxMacchina}:{keyRichPart}:{lanciato}:{startDate:yyyyMMdd_HHmmss}:{endDate:yyyyMMdd_HHmmss}";
// cerco in redis dato valore sel idxMaccSel...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<PODLExpModel>>($"{rawData}");
source = "REDIS";
}
else
{
result = dbController.ListPODLFilt(lanciato, keyRichPart, idxMacchina, codGruppo, startDate, endDate);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(redisShortTimeCache));
}
if (result == null)
{
result = new List<PODLExpModel>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"POdlListGetFilt | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Elenco PODL (Async) non avviati filtrati x articolo, KeyRich (che contiene stato)
/// </summary>
/// <param name="lanciato">Solo lanciati (1) o ancora disponibili (0)</param>
/// <param name="keyRichPart">KeyRich (parziale) da cercare (es cod stato x yacht)</param>
/// <param name="idxMacchina">Macchina</param>
/// <param name="codGruppo">Gruppo</param>
/// <param name="startDate">Data inizio</param>
/// <param name="endDate">Data fine</param>
/// <returns></returns>
public async Task<List<PODLExpModel>> POdlListGetFiltAsync(bool lanciato, string keyRichPart, string idxMacchina, string codGruppo, DateTime startDate, DateTime endDate)
{
using var activity = ActivitySource.StartActivity("POdlListGetFiltAsync");
List<PODLExpModel>? result = new List<PODLExpModel>();
string source = "DB";
string currKey = $"{Utils.redisPOdlList}:{codGruppo}:{idxMacchina}:{keyRichPart}:{lanciato}:{startDate:yyyyMMdd_HHmmss}:{endDate:yyyyMMdd_HHmmss}";
// cerco in redis dato valore sel idxMaccSel...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<PODLExpModel>>($"{rawData}");
source = "REDIS";
}
else
{
result = await Task.FromResult(dbController.ListPODLFilt(lanciato, keyRichPart, idxMacchina, codGruppo, startDate, endDate));
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(redisShortTimeCache));
}
if (result == null)
{
result = new List<PODLExpModel>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"POdlListGetFiltAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Elenco PODL per composizione KIT (Async) non avviati filtrati x articolo, KeyRich (che contiene stato)
/// </summary>
/// <param name="lanciato">Solo lanciati (1) o ancora disponibili (0)</param>
/// <param name="keyRichPart">KeyRich (parziale) da cercare (es cod stato x yacht)</param>
/// <param name="idxMacchina">Macchina</param>
/// <param name="codGruppo">Gruppo</param>
/// <param name="startDate">Data inizio</param>
/// <param name="endDate">Data fine</param>
/// <returns></returns>
public async Task<List<PODLExpModel>> POdlToKitListGetFiltAsync(bool lanciato, string keyRichPart, string idxMacchina, string codGruppo, DateTime startDate, DateTime endDate)
{
using var activity = ActivitySource.StartActivity("POdlToKitListGetFiltAsync");
List<PODLExpModel>? result = new List<PODLExpModel>();
string source = "DB";
string currKey = $"{Utils.redisPOdlList}_kit:{codGruppo}:{idxMacchina}:{keyRichPart}:{lanciato}:{startDate:yyyyMMdd_HHmmss}:{endDate:yyyyMMdd_HHmmss}";
// cerco in redis dato valore sel idxMaccSel...
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<PODLExpModel>>($"{rawData}");
source = "REDIS";
}
else
{
result = await Task.FromResult(dbController.ListPODL_KitFilt(lanciato, keyRichPart, idxMacchina, codGruppo, startDate, endDate));
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(redisShortTimeCache));
}
if (result == null)
{
result = new List<PODLExpModel>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"POdlToKitListGetFiltAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Chiamata salvataggio ricetta + refresh REDIS
/// </summary>
/// <param name="idxPODL"></param>
/// <param name="recipeName"></param>
/// <returns></returns>
public async Task<bool> POdlUpdateRecipe(int idxPODL, string recipeName)
{
using var activity = ActivitySource.StartActivity("POdlUpdateRecipe");
string source = "DB+REDIS";
bool answ = false;
answ = await dbController.PODL_updateRecipe(idxPODL, recipeName);
// reset redis...
if (answ)
{
await POdlFlushCache();
}
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"POdlUpdateRecipe | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return answ;
}
/// <summary>
/// Aggiornamento record selezionato
/// </summary>
/// <param name="currRec"></param>
/// <returns></returns>
public async Task<bool> POdlUpdateRecord(PODLModel currRec)
{
using var activity = ActivitySource.StartActivity("POdlUpdateRecord");
string source = "DB+REDIS";
var dbResult = await dbController.PODLUpdateRecord(currRec);
// elimino cache redis...
await POdlFlushCache();
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"POdlUpdateRecord | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return dbResult;
}
/// <summary>
/// Restituisce le statistiche di processo correnti x depluplica FluxLog
/// </summary>
/// <returns></returns>
public List<StatDedupDTO> ProcFLStats()
{
using var activity = ActivitySource.StartActivity("ProcFLStats");
string source = "REDIS";
List<StatDedupDTO> actStats = new List<StatDedupDTO>();
string currKey = $"{Utils.redisStatsProcFL}";
// recupero i record statistiche correnti
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
var rawStats = JsonConvert.DeserializeObject<List<StatDedupDTO>>($"{rawData}");
if (rawStats != null)
{
actStats = rawStats;
}
}
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"ProcFLStats | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return actStats;
}
/// <summary>
/// Ricerca ricetta su MongoDB dato PODL
/// </summary>
/// <param name="idxPODL"></param>
/// <returns></returns>
public async Task<RecipeModel?> RecipeGetByPODL(int idxPODL)
{
RecipeModel? result = null;
using var activity = ActivitySource.StartActivity("RecipeGetByPODL");
string source = "MongoDB";
result = await mongoController.RecipeGetByPODL(idxPODL);
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"RecipeGetByPODL | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Salva ricetta su MongoDB
/// </summary>
/// <param name="currRecord"></param>
/// <returns></returns>
public async Task<bool> RecipeSetByPODL(RecipeModel currRecord)
{
using var activity = ActivitySource.StartActivity("RecipeSetByPODL");
string source = "DB+REDIS";
bool answ = false;
answ = await mongoController.RecipeSetByPODL(currRecord);
if (answ)
{
await POdlFlushCache();
}
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"RecipeSetByPODL | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return answ;
}
/// <summary>
/// Effettua conteggio chaivi REDIS dato pat2Flush ricerca
/// </summary>
/// <param name="keyPattern"></param>
/// <returns></returns>
public int RedisCountKey(string keyPattern)
{
using var activity = ActivitySource.StartActivity("RedisCountKey");
string source = "REDIS";
int num = 0;
keyPattern = (string.IsNullOrEmpty(keyPattern) ? "**" : keyPattern);
try
{
var listEndpoints = redisConnAdmin.GetEndPoints();
foreach (var endPoint in listEndpoints)
{
var server = redisConnAdmin.GetServer(endPoint);
foreach (RedisKey item in server.Keys(pattern: keyPattern, database: redisDb.Database, pageSize: 250, cursor: 0L))
{
num++;
}
}
}
catch (Exception arg)
{
Log.Error($"Eccezione in RedisCountKey{Environment.NewLine}{arg}");
}
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"RedisCountKey | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return num;
}
/// <summary>
/// Esegue eliminazione memoria redis keyVal
/// </summary>
/// <param name="keyVal"></param>
/// <returns></returns>
public bool RedisDelKey(string keyVal)
{
using var activity = ActivitySource.StartActivity("RedisDelKey");
string source = "REDIS";
bool answ = false;
var listEndpoints = redisConnAdmin.GetEndPoints();
foreach (var endPoint in listEndpoints)
{
var server = redisConnAdmin.GetServer(endPoint);
if (server != null)
{
redisDb.KeyDelete((RedisKey)keyVal);
answ = true;
}
}
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"RedisDelKey | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return answ;
}
/// <summary>
/// Reset della cache IO post operazioni come setup ODL...
/// </summary>
/// <param name="baseMem">Indirizzo base da cui rimuovere memoria cache</param>
/// <returns></returns>
public async Task<bool> ResetIoCache(string baseMem)
{
using var activity = ActivitySource.StartActivity("ResetIoCache");
string source = "REDIS";
// patterna a partire da cache IO...
RedisValue pattern = new RedisValue($"{MpIoNS}:*");
if (!string.IsNullOrEmpty(baseMem))
{
pattern = new RedisValue($"{MpIoNS}:{baseMem}:*");
}
bool answ = await ExecFlushRedisPatternAsync(pattern);
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"ResetIoCache | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return answ;
}
/// <summary>
/// Effettua reset microstato macchina
/// </summary>
/// <param name="idxMacchina"></param>
public async Task ResetMicrostatoMacchina(string idxMacchina)
{
using var activity = ActivitySource.StartActivity("ResetMicrostatoMacchina");
string source = "DB";
// salvo microstato 0...
MicroStatoMacchinaModel newRecMS = new MicroStatoMacchinaModel()
{
IdxMacchina = idxMacchina,
InizioStato = DateTime.Now,
IdxMicroStato = 0,
Value = "FER"
};
var result = await dbController.MicroStatoMacchinaUpsert(newRecMS);
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"ResetMicrostatoMacchina | Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
}
/// <summary>
/// Stato macchina
/// </summary>
/// <param name="idxMacchina"></param>
/// <returns></returns>
public StatoMacchineModel StatoMacchina(string idxMacchina)
{
using var activity = ActivitySource.StartActivity("StatoMacchina");
// setup parametri costanti
string source = "DB";
StatoMacchineModel? result = new StatoMacchineModel();
// cerco in redisConn...
string currKey = $"{Utils.redisStatoMacch}:{idxMacchina}";
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<StatoMacchineModel>($"{rawData}");
source = "REDIS";
}
else
{
result = dbController.StatoMacchina(idxMacchina);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(1));
}
if (result == null)
{
result = new StatoMacchineModel();
}
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"StatoMacchina | {source} | {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Statistiche ODL calcolate (da stored stp_STAT_ODL)
/// </summary>
/// <returns></returns>
public Task<List<StatODLModel>> StatOdl(int IdxOdl)
{
using var activity = ActivitySource.StartActivity("StatOdl");
string source = "DB";
var result = dbController.OdlStart(IdxOdl);
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"StatOdl | {source} | {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Restituisce il valore da REDIS associato al tag richiesto
/// </summary>
/// <param name="redKey">Chiave in cui cercare il valore</param>
/// <returns></returns>
public string TagConfGetKey(string redKey)
{
string outVal = "";
using var activity = ActivitySource.StartActivity("TagConfGetKey");
string source = "REDIS";
// cerco in REDIS la conf x l'IOB
var rawData = redisDb.StringGet(redKey);
if (!string.IsNullOrEmpty(rawData))
{
outVal = $"{rawData}";
}
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"TagConfGetKey | {source} | {activity?.Duration.TotalMilliseconds}ms");
return outVal;
}
/// <summary>
/// Elenco setup dei tag conf correnti
/// </summary>
/// <returns></returns>
public Dictionary<string, List<TagData>> TagsGetAll()
{
return currTagConf;
}
/// <summary>
/// Elimina record + svuotamento cache
/// </summary>
/// <param name="currRecord"></param>
public async Task<bool> TemplateKitDelete(TemplateKitModel currRecord)
{
using var activity = ActivitySource.StartActivity("TemplateKitDelete");
string source = "DB+REDIS";
bool fatto = false;
// salvo
fatto = dbController.TemplateKitDelete(currRecord);
// svuoto cache
RedisValue pattern = $"{Utils.redisKitTempl}:*";
await ExecFlushRedisPatternAsync(pattern);
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"TemplateKitDelete | {source} | {activity?.Duration.TotalMilliseconds}ms");
return fatto;
}
/// <summary>
/// Elenco Template KIT da ricerca
/// </summary>
/// <param name="codParent"></param>
/// <param name="codChild"></param>
/// <returns></returns>
public List<TemplateKitModel> TemplateKitFilt(string codParent, string codChild)
{
using var activity = ActivitySource.StartActivity("TemplateKitFilt");
string source = "DB";
List<TemplateKitModel>? result = new List<TemplateKitModel>();
// cerco in redis...
string currKey = $"{Utils.redisKitTempl}:{codParent}:{codChild}";
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<TemplateKitModel>>($"{rawData}");
source = "REDIS";
}
else
{
result = dbController.TemplateKitFilt(codParent, codChild);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, TimeSpan.FromMinutes(redisLongTimeCache));
}
if (result == null)
{
result = new List<TemplateKitModel>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"TemplateKitFilt | {source} | {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Esegue salvataggio record + svuotamento cache
/// </summary>
/// <param name="currRecord"></param>
/// <param name="codAzienda"></param>
public async Task<bool> TemplateKitUpsert(TemplateKitModel currRecord, string codAzienda)
{
using var activity = ActivitySource.StartActivity("TemplateKitUpsert");
string source = "DB+REDIS";
bool fatto = false;
// salvo
fatto = dbController.TemplateKitUpsert(currRecord, codAzienda);
// svuoto cache
RedisValue pattern = $"{Utils.redisKitTempl}:*";
await ExecFlushRedisPatternAsync(pattern);
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"TemplateKitUpsert | {source} | {activity?.Duration.TotalMilliseconds}ms");
return fatto;
}
/// <summary>
/// Punteggio compatibilità KIT per KeyFilt indicato
/// </summary>
/// <param name="KeyFilt"></param>
/// <param name="MaxResult"></param>
/// <param name="ForceDb"></param>
/// <returns></returns>
public List<TksScoreModel> TksScore(string KeyFilt, int MaxResult, bool ForceDb)
{
using var activity = ActivitySource.StartActivity("TksScore");
string source = "DB";
List<TksScoreModel>? result = new List<TksScoreModel>();
// cerco in redis...
string currKey = $"{Utils.redisKitScore}:{KeyFilt}:{MaxResult}";
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue && !ForceDb)
{
result = JsonConvert.DeserializeObject<List<TksScoreModel>>($"{rawData}");
source = "REDIS";
}
else
{
result = dbController.TksScore(KeyFilt, MaxResult);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, TimeSpan.FromMinutes(redisLongTimeCache));
}
if (result == null)
{
result = new List<TksScoreModel>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"TksScore | {source} | {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Esegue traduzione dato vocabolario da Lingua + Lemma
/// </summary>
/// <param name="lemma"></param>
/// <param name="lingua"></param>
/// <returns></returns>
public string Traduci(string lemma, string lingua)
{
string answ = $"[{lemma}]";
// verifico se ho qualcosa nell'obj vocabolario...
if (ObjVocabolario == null || ObjVocabolario.Count == 0)
{
// inizializzo il vocabolario...
ObjVocabolario = VocabolarioGetAll();
}
var record = ObjVocabolario.Where(x => x.Lingua == lingua && x.Lemma == lemma).FirstOrDefault();
if (record != null)
{
answ = record.Traduzione;
}
return answ;
}
/// <summary>
/// Update valore Dossier
/// </summary>
/// <param name="currDoss"></param>
/// <param name="editFL"></param>
/// <returns></returns>
public async Task<bool> updateDossierValue(DossierModel currDoss, FluxLogDTO editFL)
{
using var activity = ActivitySource.StartActivity("updateDossierValue");
string source = "DB";
bool answ = false;
// recupero intero set valori dossier deserializzando...
var fluxLogList = FluxLogDtoGetByFlux(currDoss.Valore);
// se tutto ok
if (fluxLogList != null)
{
// da provare...!!!!
// elimino vecchio record
var currRec = fluxLogList.FirstOrDefault(x => x.CodFlux == editFL.CodFlux && x.dtEvento == editFL.dtEvento);
if (currRec != null)
{
fluxLogList.Remove(currRec);
// aggiungo nuovo
fluxLogList.Add(editFL);
}
// serializzo nuovamente valore
DossierFluxLogDTO? result = new DossierFluxLogDTO();
var ODLflux = result.ODL.ToList();
foreach (var item in fluxLogList)
{
ODLflux.Add(item);
}
DossierFluxLogDTO updatedResult = new DossierFluxLogDTO() { ODL = ODLflux };
string rawVal = JsonConvert.SerializeObject(updatedResult);
currDoss.Valore = rawVal;
// aggiorno record sul DB
await dbController.DossiersUpdateValore(currDoss);
}
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"updateDossierValue | {source} | {activity?.Duration.TotalMilliseconds}ms");
return answ;
}
/// <summary>
/// Elenco completo tabella Vocabolario
/// </summary>
/// <returns></returns>
public List<VocabolarioModel> VocabolarioGetAll()
{
List<VocabolarioModel>? result = new List<VocabolarioModel>();
using var activity = ActivitySource.StartActivity("VocabolarioGetAll");
string source = "REDIS";
// cerco in redis...
RedisValue rawData = redisDb.StringGet(Utils.redisVocabolario);
if (!string.IsNullOrEmpty($"{rawData}"))
{
result = JsonConvert.DeserializeObject<List<VocabolarioModel>>($"{rawData}");
}
else
{
result = dbController.VocabolarioGetAll();
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(Utils.redisVocabolario, rawData, getRandTOut(redisLongTimeCache / 5));
source = "DB";
}
if (result == null)
{
result = new List<VocabolarioModel>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"VocabolarioGetAll Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Elimina record + svuotamento cache
/// </summary>
/// <param name="currRecord"></param>
public bool WipKitDelete(WipSetupKitModel currRecord)
{
using var activity = ActivitySource.StartActivity("WipKitDelete");
string source = "DB";
bool fatto = false;
// salvo
fatto = dbController.WipKitDelete(currRecord);
// svuoto cache
EmptyWipCache();
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"WipKitDelete Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return fatto;
}
/// <summary>
/// Elimina i record associati al keyFilt indicato
/// </summary>
/// <param name="KeyFilt"></param>
public bool WipKitDeleteGroup(string KeyFilt)
{
using var activity = ActivitySource.StartActivity("WipKitDeleteGroup");
string source = "DB";
bool fatto = false;
// salvo
fatto = dbController.WipKitDeleteGroup(KeyFilt);
// svuoto cache
EmptyWipCache();
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"WipKitDeleteGroup Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return fatto;
}
/// <summary>
/// Elimina i record più vecchi della data-ora indicata
/// </summary>
/// <param name="DateLimit"></param>
public bool WipKitDeleteOlder(DateTime DateLimit)
{
using var activity = ActivitySource.StartActivity("WipKitDeleteOlder");
string source = "DB";
bool fatto = false;
// salvo
fatto = dbController.WipKitDeleteOlder(DateLimit);
// svuoto cache
EmptyWipCache();
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"WipKitDeleteOlder Read from {source}: {activity?.Duration.TotalMilliseconds}ms");
return fatto;
}
/// <summary>
/// Elenco Template KIT da ricerca
/// </summary>
/// <param name="KeyFilt"></param>
/// <returns></returns>
public List<WipSetupKitModel> WipKitFilt(string KeyFilt)
{
using var activity = ActivitySource.StartActivity("WipKitFilt");
string source = "DB";
List<WipSetupKitModel>? result = new List<WipSetupKitModel>();
// cerco in redis...
string currKey = $"{Utils.redisKitWip}:{KeyFilt}";
RedisValue rawData = redisDb.StringGet(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<WipSetupKitModel>>($"{rawData}");
source = "REDIS";
}
else
{
result = dbController.WipKitFilt(KeyFilt);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
redisDb.StringSet(currKey, rawData, TimeSpan.FromMinutes(redisLongTimeCache));
}
if (result == null)
{
result = new List<WipSetupKitModel>();
}
activity?.SetTag("data.source", source);
activity?.SetTag("result.count", result.Count);
activity?.Stop();
LogTrace($"WipKitFilt | {source} | {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Esegue salvataggio record + svuotamento cache
/// </summary>
/// <param name="currRecord"></param>
public bool WipKitUpsert(WipSetupKitModel currRecord)
{
using var activity = ActivitySource.StartActivity("WipKitUpsert");
string source = "DB";
bool fatto = false;
// salvo
fatto = dbController.WipKitUpsert(currRecord);
// svuoto cache KitWip
EmptyWipCache();
activity?.SetTag("data.source", source);
activity?.Stop();
LogTrace($"WipKitUpsert | {source} | {activity?.Duration.TotalMilliseconds}ms");
return fatto;
}
#endregion Public Methods
#region Protected Fields
protected Random rand = new Random();
#endregion Protected Fields
#region Protected Properties
protected string canCacheParametri { get; set; } = "";
#endregion Protected Properties
#region Protected Methods
/// <summary>
/// Restituisce un timeout dai minuti richiesti + tempo random -15..+15 sec
/// </summary>
/// <param name="stdMinutes"></param>
/// <returns></returns>
protected TimeSpan getRandTOut(double stdMinutes)
{
double rndValue = stdMinutes + (double)rand.Next(-15, 15) / 60;
return TimeSpan.FromMinutes(rndValue);
}
/// <summary>
/// Merge statistiche Dedup
/// </summary>
/// <param name="procStats"></param>
/// <returns></returns>
protected bool ProcDedupStatMerge(List<StatDedupDTO> procStats)
{
bool answ = false;
List<StatDedupDTO> actStats = ProcFLStats();
// se fosse vuoto --> add diretto
if (actStats.Count == 0)
{
actStats.AddRange(procStats);
}
else
{
// aggiorno su redis i record statistiche 1:1...
foreach (var recStat in procStats)
{
// cerco se ci fosse x aggiornare
var currRec = actStats.Where(x => x.IdxMacchina == recStat.IdxMacchina
&& x.CodFlux == recStat.CodFlux
&& x.Interval == recStat.Interval
&& x.Num4Int == recStat.Num4Int).FirstOrDefault();
// se trovato aggiorno
if (currRec != null)
{
currRec.ProcTime += recStat.ProcTime;
currRec.NumRec += recStat.NumRec;
}
// altrimenti aggiungo
else
{
actStats.Add(recStat);
}
}
}
// salvo record statistiche
var rawData = JsonConvert.SerializeObject(actStats);
string currKey = $"{Utils.redisStatsProcFL}";
redisDb.StringSet(currKey, rawData);
return answ;
}
/// <summary>
/// Merge statistiche DB Maintenance
/// </summary>
/// <param name="procStats"></param>
/// <returns></returns>
protected bool RecDbMaintStat(TimeSpan duration)
{
bool answ = false;
Dictionary<DateTime, double> actStats = DbDedupStats();
// aggiungo record!
actStats.Add(DateTime.Now, duration.TotalSeconds);
// salvo NUOVO record statistiche
string currKey = $"{Utils.redisStatsDbMaint}";
var rawData = JsonConvert.SerializeObject(actStats);
redisDb.StringSet(currKey, rawData);
return answ;
}
#endregion Protected Methods
#region Private Fields
/// <summary>
/// Oggetto per collezione dati Activity (span in Uptrace)
/// </summary>
private static readonly ActivitySource ActivitySource = new ActivitySource("MP.DATA.Tracer");
private static IConfiguration _configuration = null!;
private static Logger Log = LogManager.GetCurrentClassLogger();
private string MpIoNS = "";
/// <summary>
/// Oggetto vocabolario x uso continuo traduzione
/// </summary>
private List<VocabolarioModel> ObjVocabolario = new List<VocabolarioModel>();
/// <summary>
/// Oggetto per connessione a REDIS
/// </summary>
private ConnectionMultiplexer redisConn = null!;
/// <summary>
/// Oggetto per connessione a REDIS modalità admin (ex flux dati)
/// </summary>
private ConnectionMultiplexer redisConnAdmin = null!;
/// <summary>
/// Oggetto DB redis da impiegare x chiamate R/W
/// </summary>
private IDatabase redisDb = null!;
private int redisLongTimeCache = 5;
private int redisShortTimeCache = 2;
#endregion Private Fields
#region Private Properties
/// <summary>
/// Cache dati config
/// </summary>
private List<ConfigModel> configData { get; set; } = new List<ConfigModel>();
#endregion Private Properties
#region Private Methods
/// <summary>
/// Svuota cache creazione KIT
/// </summary>
private void EmptyWipCache()
{
string pattern = $"{Utils.redisKitWip}:*";
if (!string.IsNullOrEmpty(pattern))
{
ExecFlushRedisPattern(pattern);
}
}
private async Task<bool> POdlFlushCache()
{
using var activity = ActivitySource.StartActivity("POdlFlushCache");
bool answ = false;
RedisValue pattern = new RedisValue($"{Utils.redisXdlData}:*");
answ = await ExecFlushRedisPatternAsync(pattern);
pattern = new RedisValue($"{Utils.redisPOdlByOdl}:*");
answ = await ExecFlushRedisPatternAsync(pattern);
pattern = new RedisValue($"{Utils.redisPOdlByPOdl}:*");
answ = await ExecFlushRedisPatternAsync(pattern);
pattern = new RedisValue($"{Utils.redisPOdlList}:*");
answ = await ExecFlushRedisPatternAsync(pattern);
activity?.SetTag("data.source", "REDIS");
return answ;
}
private string redHashMpIO(string keyName)
{
string result = keyName;
try
{
result = $"{MpIoNS}:{keyName}".Replace("\\", "_");
}
catch (Exception exc)
{
Log.Error($"Errore in redHashMpIO{Environment.NewLine}{exc}");
}
return result;
}
private async Task resetCacheArticoli()
{
using var activity = ActivitySource.StartActivity("resetCacheArticoli");
RedisValue pattern = new RedisValue($"{Utils.redisArtByDossier}:*");
await ExecFlushRedisPatternAsync(pattern);
pattern = new RedisValue($"{Utils.redisArtList}:*");
await ExecFlushRedisPatternAsync(pattern);
activity?.SetTag("data.source", "REDIS");
}
/// <summary>
/// Reset macchine e gruppi
/// </summary>
private void ResetMacGrpCache()
{
ExecFlushRedisPattern($"{Utils.redisAnagGruppi}:*");
ExecFlushRedisPattern($"{Utils.redisMacList}:*");
}
/// <summary>
/// Reset cache operatori e gruppi
/// </summary>
private void ResetOprGrpCache()
{
ExecFlushRedisPattern($"{Utils.redisAnagGruppi}:*");
ExecFlushRedisPattern($"{Utils.redisOprList}:*");
}
#endregion Private Methods
}
}