e71b873a4c
- pulizia codice da warning
387 lines
14 KiB
C#
387 lines
14 KiB
C#
using Microsoft.AspNetCore.Localization;
|
|
using Microsoft.Extensions.Configuration;
|
|
using MP.MONO.Core;
|
|
using MP.MONO.Data;
|
|
using MP.MONO.Data.Controllers;
|
|
using MP.MONO.Data.DbModels;
|
|
using Newtonsoft.Json;
|
|
using NLog;
|
|
using StackExchange.Redis;
|
|
using System.Collections.Concurrent;
|
|
|
|
namespace MP.MONO.DECODER
|
|
{
|
|
public class AlarmsBlinkManager
|
|
{
|
|
#region Public Constructors
|
|
|
|
public AlarmsBlinkManager()
|
|
{
|
|
var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
|
|
var builder = new ConfigurationBuilder()
|
|
.AddJsonFile($"appsettings.json", true, true)
|
|
.AddJsonFile($"appsettings.{env}.json", true, true)
|
|
.AddEnvironmentVariables();
|
|
var config = builder.Build();
|
|
|
|
redisConn = ConnectionMultiplexer.Connect(config.GetConnectionString("Redis"));
|
|
redisDb = redisConn.GetDatabase();
|
|
Log.Info("ABM: Redis OK!");
|
|
|
|
// altri parametri per check vari
|
|
string connStringDB = DbConfig.CONNECTION_STRING;
|
|
if (string.IsNullOrEmpty(connStringDB))
|
|
{
|
|
Log.Error("ABM: ConnString empty!");
|
|
}
|
|
else
|
|
{
|
|
dbController = new MpDbController(config);
|
|
Log.Info("ABM: DbController OK");
|
|
Console.WriteLine("ABM: DbController OK");
|
|
}
|
|
|
|
setupAlarmState();
|
|
|
|
Log.Info("AlarmsBlinkManager OK");
|
|
Console.WriteLine("AlarmsBlinkManager OK");
|
|
}
|
|
|
|
#endregion Public Constructors
|
|
|
|
#region Public Properties
|
|
|
|
/// <summary>
|
|
/// Elenco allarmi attivi e acknowled ad es: subito i nuovi, con ritardo i cessati
|
|
/// </summary>
|
|
public static List<string> alarmsActAck
|
|
{
|
|
get => getAlarms($"{redisDb.StringGet(Constants.ALARM_CURR_KEY)}");
|
|
set => setAlarms(Constants.ALARM_CURR_KEY, value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Elenco ultimo set allarmi ricevuti
|
|
/// </summary>
|
|
public static List<string> alarmsLastRec
|
|
{
|
|
get => getAlarms($"{redisDb.StringGet(Constants.ALARM_RECEIV_KEY)}");
|
|
set => setAlarms(Constants.ALARM_RECEIV_KEY, value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ultima Stringa LOG allarmi salvata
|
|
/// </summary>
|
|
public static string alarmsLogSaved
|
|
{
|
|
get => $"{redisDb.StringGet(Constants.ALARM_LOG_SAVED)}";
|
|
set => redisDb.StringSet(Constants.ALARM_LOG_SAVED, value);
|
|
}
|
|
|
|
public static List<string> alarmsPendingClose
|
|
{
|
|
get
|
|
{
|
|
// rileggo da REDIS SE ci sono allarmi che sono pending close... in un area che dura poco (2 sec)
|
|
List<string> lista = new List<string>();
|
|
// in base al tipo leggo una chiave redis o l'altra...
|
|
var rawData = redisDb.StringGet(Constants.ALARM_PEND_KEY);
|
|
if (!string.IsNullOrEmpty(rawData))
|
|
{
|
|
var desList = JsonConvert.DeserializeObject<List<string>>($"{rawData}");
|
|
if (desList != null)
|
|
{
|
|
lista = desList;
|
|
}
|
|
}
|
|
return lista;
|
|
}
|
|
set
|
|
{
|
|
string rawData = JsonConvert.SerializeObject(value);
|
|
redisDb.StringSet(Constants.ALARM_PEND_KEY, rawData, TimeSpan.FromMilliseconds(3000));
|
|
}
|
|
}
|
|
|
|
#endregion Public Properties
|
|
|
|
#region Public Methods
|
|
|
|
public static bool isProcessing { get; set; } = false;
|
|
public static bool isRemoving { get; set; } = false;
|
|
private static int ticketNum { get; set; } = 0;
|
|
|
|
private static ConcurrentQueue<int> reqList { get; set; } = new ConcurrentQueue<int>();
|
|
|
|
/// <summary>
|
|
/// Recupera un ticket di esecuzione x eseguire in ordine corretto gli insert...
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static int getTicket()
|
|
{
|
|
// incremento contatore
|
|
ticketNum++;
|
|
// faccio coda 0...9999
|
|
ticketNum = ticketNum > 9999 ? 1 : ticketNum;
|
|
// accodo...
|
|
reqList.Enqueue(ticketNum);
|
|
// rendo ticket
|
|
return ticketNum;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Indica il ticket attualmente in esecuzione
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static int currTicket
|
|
{
|
|
get
|
|
{
|
|
int answ = -1;
|
|
reqList.TryPeek(out answ);
|
|
return answ;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Verifico se il mio ticket sia quello corretto/prossimo
|
|
/// </summary>
|
|
/// <param name="ticket"></param>
|
|
/// <returns></returns>
|
|
public static bool checkTicket(int ticket)
|
|
{
|
|
bool fatto = false;
|
|
if (!isProcessing)
|
|
{
|
|
// verifico se quello richiesto sia il ticket giusto
|
|
if (ticket == currTicket)
|
|
{
|
|
isProcessing = true;
|
|
int usedTicket = 0;
|
|
fatto = reqList.TryDequeue(out usedTicket);
|
|
}
|
|
}
|
|
return fatto;
|
|
}
|
|
|
|
/// <summary>
|
|
/// restituisce elenco allarmi muted, eventualmente da cache redis ( 5 sec)
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private static List<string> alarmMutedList
|
|
{
|
|
get
|
|
{
|
|
List<string> mutedAlarm = new List<string>();
|
|
// cerco in redis...
|
|
var rawData = redisDb.StringGet(Constants.ALARMS_SETT_MUTED_KEY);
|
|
if (!string.IsNullOrEmpty(rawData))
|
|
{
|
|
var rawAlarm = JsonConvert.DeserializeObject<List<string>>($"{rawData}");
|
|
if (rawAlarm != null)
|
|
{
|
|
mutedAlarm = rawAlarm;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// altrimenti da conf/DB... gestione allarmi muted
|
|
List<AlarmListModel>? alarmListSetup = new List<AlarmListModel>();
|
|
rawData = redisDb.StringGet(Constants.ALARMS_SETT_RLIST_KEY);
|
|
if (!string.IsNullOrEmpty(rawData))
|
|
{
|
|
alarmListSetup = JsonConvert.DeserializeObject<List<AlarmListModel>>($"{rawData}");
|
|
}
|
|
if (alarmListSetup == null)
|
|
{
|
|
alarmListSetup = dbController.AlarmListGetAll();
|
|
}
|
|
// calcolo come lista string...
|
|
if (alarmListSetup != null && alarmListSetup.Count > 0)
|
|
{
|
|
mutedAlarm = alarmListSetup.Where(x => x.Muted).Select(x => x.FullValue).ToList();
|
|
}
|
|
// salvo cache in redis x 1 minuto...
|
|
rawData = JsonConvert.SerializeObject(mutedAlarm);
|
|
redisDb.StringSet(Constants.ALARMS_SETT_MUTED_KEY, rawData, TimeSpan.FromSeconds(60));
|
|
}
|
|
return mutedAlarm;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Effettua cleanup preliminare allarmi data condizione regext pre/post
|
|
/// </summary>
|
|
/// <param name="AlarmCleanPre"></param>
|
|
/// <param name="AlarmCleanPost"></param>
|
|
/// <param name="alarmListRaw"></param>
|
|
/// <returns></returns>
|
|
public static List<string> cleanAlarms(string AlarmCleanPre, string AlarmCleanPost, List<string> alarmListRaw)
|
|
{
|
|
List<string> alarmList = new List<string>();
|
|
// effettuo cleanup degli allarmi con procedura ricerca regexp
|
|
foreach (var item in alarmListRaw)
|
|
{
|
|
string currData = item;
|
|
// se ho valori trim pre/post li applica...
|
|
if (!string.IsNullOrEmpty(AlarmCleanPre))
|
|
{
|
|
currData = item.Replace(AlarmCleanPre, "");
|
|
}
|
|
if (!string.IsNullOrEmpty(AlarmCleanPost))
|
|
{
|
|
currData = currData.Replace(AlarmCleanPost, "");
|
|
}
|
|
// aggiungo
|
|
alarmList.Add(currData);
|
|
}
|
|
// Restituisco
|
|
return alarmList;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Funzione chiamata x verifica allarmi:
|
|
/// - fornisce elenco allarmi correnti aggiornati
|
|
/// - fornisce elenco dei NUOVI come ref
|
|
/// - fornisce elenco dei CESSATI come ref
|
|
/// </summary>
|
|
/// <param name="alarmListReceived"></param>
|
|
/// <param name="alarmListCurrent"></param>
|
|
/// <param name="alarmListAdded"></param>
|
|
/// <param name="alarmListCeased"></param>
|
|
/// <returns>Boolean che indica se ci siano state variazioni</returns>
|
|
public static bool processData(List<string> alarmListReceived, ref List<string> alarmListCurrent, ref List<string> alarmListAdded, ref List<string> alarmListCeased)
|
|
{
|
|
bool answ = false;
|
|
// primo step: verifico gli allarmi ricevuti siano > 0 e NON contengano duplicati...
|
|
List<string> alarmListReceivedOk = new List<string>();
|
|
if (alarmListReceived.Count > 0)
|
|
{
|
|
alarmListReceivedOk = alarmListReceived
|
|
.GroupBy(x => x)
|
|
.Select(grp => grp.First())
|
|
.OrderBy(x => x)
|
|
.ToList();
|
|
Log.Debug($"Ricezione update allarmi | {alarmListReceived.Count} --> {alarmListReceivedOk.Count} distinct");
|
|
}
|
|
else
|
|
{
|
|
Log.Debug($"Ricezione ZERO allarmi | {alarmListReceived.Count}");
|
|
}
|
|
|
|
// elimino muted da allarmi
|
|
List<string> listMuted = new List<string>(alarmMutedList);
|
|
if (listMuted.Count > 0)
|
|
{
|
|
foreach (var item in listMuted)
|
|
{
|
|
alarmListReceivedOk.Remove(item);
|
|
}
|
|
}
|
|
|
|
// salvo set allarmi ricevuti...
|
|
alarmsLastRec = alarmListReceivedOk;
|
|
Log.Debug($"Salvataggio LastReceived | count {alarmListReceivedOk.Count}");
|
|
|
|
// elenco allarmi confermati
|
|
var alarmListConf = alarmListCurrent.Intersect(alarmListReceivedOk);
|
|
|
|
// copio oggetti x allarmi NUOVI e cessati
|
|
alarmListAdded = new List<string>(alarmListReceivedOk);
|
|
alarmListCeased = new List<string>(alarmListCurrent);
|
|
foreach (var item in alarmListConf)
|
|
{
|
|
// calcolo allarmi nuovi/cessati eliminando eventuali elementi comuni
|
|
alarmListAdded.Remove(item);
|
|
alarmListCeased.Remove(item);
|
|
}
|
|
|
|
// aggiungo i nuovi a current
|
|
alarmListCurrent.AddRange(alarmListAdded);
|
|
// riordino
|
|
alarmListCurrent = alarmListCurrent.OrderBy(x => x).ToList();
|
|
#if false
|
|
// ...e salvo subito
|
|
alarmsActAck = alarmListCurrent;
|
|
|
|
#endif
|
|
// loggo controllo
|
|
Log.Debug($"Esito controllo | {alarmListReceivedOk.Count} ricevuti | {alarmListAdded.Count} aggiunti | {alarmListCeased.Count} cessati");
|
|
|
|
// restituisco esito = allarmi ricevuti da registrare
|
|
answ = (alarmListAdded.Count > 0);
|
|
return answ;
|
|
}
|
|
|
|
#endregion Public Methods
|
|
|
|
#region Protected Fields
|
|
|
|
protected static Logger Log = LogManager.GetCurrentClassLogger();
|
|
|
|
#endregion Protected Fields
|
|
|
|
#region Private Fields
|
|
|
|
private static ConnectionMultiplexer? redisConn = null;
|
|
|
|
private static IDatabase redisDb = null!;
|
|
|
|
private static MpDbController dbController = null!;
|
|
|
|
#endregion Private Fields
|
|
|
|
#region Private Properties
|
|
|
|
|
|
#endregion Private Properties
|
|
|
|
#region Private Methods
|
|
|
|
/// <summary>
|
|
/// Converto deserializzando lista allarmi
|
|
/// </summary>
|
|
private static List<string> getAlarms(string rawData)
|
|
{
|
|
List<string> lastAlarms = new List<string>();
|
|
// se trovati uso questi...
|
|
if (!string.IsNullOrEmpty(rawData))
|
|
{
|
|
var rawLastAlarms = JsonConvert.DeserializeObject<List<string>>(rawData);
|
|
lastAlarms = rawLastAlarms != null ? rawLastAlarms : new List<string>();
|
|
}
|
|
return lastAlarms;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salvo in redis gli allarmi datala key
|
|
/// </summary>
|
|
/// <param name="keyName"></param>
|
|
/// <param name="listAlarm"></param>
|
|
/// <returns></returns>
|
|
private static bool setAlarms(string keyName, List<string> listAlarm)
|
|
{
|
|
bool fatto = false;
|
|
string rawData = JsonConvert.SerializeObject(listAlarm);
|
|
fatto = redisDb.StringSet(keyName, rawData);
|
|
Log.Debug($"Scrittura allarmi | key: {keyName} | num: {listAlarm.Count}");
|
|
return fatto;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Setup iniziale allarmi
|
|
/// </summary>
|
|
private void setupAlarmState()
|
|
{
|
|
// setup preliminare allarmi da DB
|
|
var currActive = dbController.AlarmRecGetActive();
|
|
alarmsActAck = currActive
|
|
.Select(x => x.AlarmListNav.FullValue)
|
|
.Distinct()
|
|
.ToList();
|
|
alarmsLastRec = new List<string>();
|
|
alarmsPendingClose = new List<string>();
|
|
Log.Debug($"Setup Stato allarmi | act: {alarmsActAck.Count}");
|
|
}
|
|
|
|
#endregion Private Methods
|
|
}
|
|
} |