Files
lux/Lux.API/Services/ExternalMessageProcessor.cs
Samuele Locatelli 678c01a668 Ancora fix API
2026-03-25 08:33:53 +01:00

306 lines
14 KiB
C#

using EgwCoreLib.Lux.Core.RestPayload;
using static Egw.Window.Data.Enums;
using static EgwCoreLib.Lux.Core.Enums;
namespace Lux.API.Services
{
public class ExternalMessageProcessor
{
#region Public Constructors
/// <summary>
/// Init classe message processor con accesso REDIS e DB
/// </summary>
/// <param name="imgService"></param>
/// <param name="dlService"></param>
/// <param name="crService"></param>
/// <param name="prodService"></param>
public ExternalMessageProcessor(IImageCacheService imgService, IDataLayerServices dlService, ICalcRuidService crService, IProdService prodService)
{
cacheService = imgService;
dbService = dlService;
_calcRuidService = crService;
_prodService = prodService;
}
#endregion Public Constructors
#region Public Methods
public async Task HandleResultMessageAsync(string channel, string message)
{
Log.Info($"Processing message from {channel} | {message.Length}");
Stopwatch sw = new Stopwatch();
sw.Start();
string rawData = $"{message}";
if (!string.IsNullOrEmpty(rawData) && rawData.Length > 2)
{
try
{
AnswerDTO? retData = JsonConvert.DeserializeObject<AnswerDTO>(rawData);
bool saved = await ProcessAnswer(retData);
#if DEBUG
// se in debug forzo save dell'ultima chiamata comunque...
saved = false;
#endif
// se non avessi salvato e non sapessi cosa fosse --> salvo comunque x debug...
if (!saved && retData != null)
{
string UID = retData.Args["UID"];
var envir = retData.ExecEnvironment;
// salvo in area generica...
await SaveRawData(UID, retData.ExecEnvironment, rawData);
}
}
catch (Exception exc)
{
Log.Error($"Errore in fase decodifica messaggio da REDIS Channel{Environment.NewLine}{exc}");
}
}
sw.Stop();
Log.Info($"HandleResultMessageAsync | {sw.Elapsed.TotalMilliseconds:N3} ms");
#if false
// Process message (parse, validate, act)
var payload = message; // or JSON-deserialize, etc.
await _redisService.SetAsync("last:result", payload);
#endif
}
/// <summary>
/// Rilettura della risposta in formato RawData x Debug
/// </summary>
/// <param name="rawData"></param>
/// <returns></returns>
public async Task<string> LoadRawData(string UID, Constants.EXECENVIRONMENTS envir)
{
// rileggo
string rawData = await cacheService.LoadDebug(UID, envir);
return rawData;
}
/// <summary>
/// Processing di una risposta AnswerDTO
/// </summary>
/// <param name="retData"></param>
/// <returns></returns>
public async Task<bool> ProcessAnswer(AnswerDTO? retData)
{
bool saved = false;
if (retData != null)
{
if (retData.Args != null && retData.Args.Count > 0)
{
/*------------------------------------------
* Richieste "continue" di stato/update
* ----------------------------------------*/
string UID = retData.Args["UID"];
string RUID = "";
Egw.Window.Data.Enums.QuestionModes cMode = QuestionModes.NULL;
if (retData.Args.ContainsKey("Mode"))
{
string sMode = retData.Args["Mode"];
if (int.TryParse(sMode, out int iMode))
{
bool modeValido = Enum.IsDefined(typeof(QuestionModes), iMode);
if (modeValido)
{
cMode = (QuestionModes)iMode;
}
}
}
// gestione RUID
if (retData.Args.ContainsKey("RUID"))
{
RUID = retData.Args["RUID"];
// salvo SUBITO chiusura statistiche...
string hKey = await _calcRuidService.CompleteRequestAsync(RUID);
// verifico eventuali spostamenti code calcolo
await _prodService.UpdateQueueAsync(retData.ExecEnvironment, hKey);
}
// gestione ritorno preview SVG
if (retData.Args.ContainsKey("Svg"))
{
// recupero UID ed SVG
string newSvg = retData.Args["Svg"];
// reinvio in redis (cache + channel)
await cacheService.SaveSvgAsync(UID, retData.ExecEnvironment, newSvg);
saved = true;
}
// gestione ritorno preview PNG
if (retData.Args.ContainsKey("Png"))
{
// recupero UID ed SVG
string newPng = retData.Args["Png"];
// reinvio in redis (cache + channel)
await cacheService.SavePngAsync(UID, retData.ExecEnvironment, newPng);
saved = true;
}
// gesitone ritorno BOM
if (retData.Args.ContainsKey("BOM"))
{
// recupero UID e BOM
string newBom = retData.Args["BOM"];
// salvo BOM ricevuta RAW in redis (cache)
await cacheService.SaveBomAsync(UID, retData.ExecEnvironment, newBom);
// salvo la BOM completa con i dati recuperati dal DB
await dbService.SaveBomAsync(UID, cMode, retData.ExecEnvironment, newBom);
// reset cache redis...
await cacheService.ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:Offers:*");
await cacheService.ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:OfferRows:*");
// pubblico refresh info così da segnalare richiesta di update conseguente
await cacheService.PublishUpdateAsync(UID, retData.ExecEnvironment);
saved = true;
}
// gestione ritorno tipo Shape
if (retData.Args.ContainsKey("SashShape"))
{
// recupero UID ed SVG
string newShape = retData.Args["SashShape"];
// reinvio in redis (cache + channel)
await cacheService.SaveShapeAsync(UID, retData.ExecEnvironment, newShape);
saved = true;
}
// gestione ritorno tipo Stima Tempi e lavorabilità (x carico macchine/schedulazione)
if (retData.Args.ContainsKey("Estimate"))
{
// recupero lista risultati calcolo...
string rawAnsw = retData.Args["Estimate"];
List<MachineCalcResultDTO>? machineEstimList = new List<MachineCalcResultDTO>();
// deserializzo
try
{
await dbService.SaveProdEstimateAsync(UID, retData.ExecEnvironment, rawAnsw);
}
catch (Exception exc)
{
Log.Error($"Eccezione in gestione Estimate{Environment.NewLine}{exc}");
}
// reinvio in redis (cache + channel)
await cacheService.SaveProdEstimateAsync(UID, retData.ExecEnvironment, rawAnsw);
saved = true;
}
// gestione ritorno tipo Balance dei gruppi di lavorazione (x carico macchine/schedulazione)
if (retData.Args.ContainsKey("Balance"))
{
// ATTENZIONE! qui oltre al valore UID deve leggere ANCHE il gruppo cui è riferito (es: Group: 1)
// recupero lista risultati calcolo...
string refGroup = retData.Args["Group"];
string rawBalance = retData.Args["Balance"];
List<MachineCalcResultDTO>? machineEstimList = new List<MachineCalcResultDTO>();
// deserializzo
try
{
await dbService.SaveProdBalanceAsync(UID, refGroup, retData.ExecEnvironment, rawBalance);
}
catch (Exception exc)
{
Log.Error($"Eccezione in gestione Balance{Environment.NewLine}{exc}");
}
// sistemo code, definendo nuova key...
string qKey = $"{QuestionModes.ORDER}:{QuestionOrderSubModes.BALANCE}:{UID}.{refGroup}";
await _prodService.SetDoneAsync(retData.ExecEnvironment, qKey, ProdQueueType.running);
// reinvio in redis (cache + channel)
await cacheService.SaveProdBalanceAsync(UID, retData.ExecEnvironment, rawBalance);
saved = true;
}
// gestione ritorno opzioni HW
if (retData.Args.ContainsKey("HardwareOptions"))
{
// recupero UID ed SVG
string newHwOpt = retData.Args["HardwareOptions"];
// reinvio in redis (cache + channel)
await cacheService.SaveHwOptAsync(UID, retData.ExecEnvironment, newHwOpt);
saved = true;
}
/*------------------------------------------
* Richieste "one shot" di configurazione
* - fare 1/gg o su richiesta utente
* ----------------------------------------*/
// Gestione ritorno lista preferiti HW (ammissibili)
if (retData.Args.ContainsKey("HardwareModelList"))
{
// recupero UID e lista preferiti HW
string newHml = retData.Args["HardwareModelList"];
// salvo HardwareList ricevuta
await cacheService.SaveHmlAsync(UID, retData.ExecEnvironment, newHml);
await dbService.SaveHmlAsync(UID, retData.ExecEnvironment, newHml);
saved = true;
}
// gestione ritorno lista profili VALIDI per JWD
if (retData.Args.ContainsKey("ProfileListAsync"))
{
// recupero UID e elenco profili validi
string profList = retData.Args["ProfileListAsync"];
// salvo ProfileListAsync ricevuta
await cacheService.SaveProfileListAsync(UID, retData.ExecEnvironment, profList);
await dbService.SaveProfileListAsync(UID, retData.ExecEnvironment, profList);
saved = true;
}
// gestione ritorno lista AreaProfiles per live JWD
if (retData.Args.ContainsKey("AreaProfiles"))
{
// recupero UID e elenco profili validi
string areaProfList = retData.Args["AreaProfiles"];
// salvo ProfileListAsync ricevuta
await cacheService.SaveProfileElemAsync(UID, retData.ExecEnvironment, areaProfList);
saved = true;
}
// gestione ritorno dati Threshold x profilo VALIDI per JWD
if (retData.Args.ContainsKey("ThresholdList"))
{
// recupero UID e elenco profili validi
string threshList = retData.Args["ThresholdList"];
// recuperro anche i profile data
string profData = retData.Args["ProfileData"];
// salvo ProfileListAsync ricevuta
await cacheService.SaveProfileThreshAsync(UID, retData.ExecEnvironment, threshList, profData);
await dbService.SaveProfileThreshAsync(UID, retData.ExecEnvironment, threshList, profData);
saved = true;
}
}
}
return saved;
}
/// <summary>
/// Salvataggio della risposta in formato RawData x Debug
/// </summary>
/// <param name="rawData"></param>
/// <returns></returns>
public async Task SaveRawData(string UID, Constants.EXECENVIRONMENTS envir, string rawData)
{
// salvo in area generica...
await cacheService.SaveDebug(UID, envir, rawData);
}
#endregion Public Methods
#region Private Fields
private static Logger Log = LogManager.GetCurrentClassLogger();
private readonly ICalcRuidService _calcRuidService;
private readonly IProdService _prodService;
private readonly IImageCacheService cacheService;
private readonly IDataLayerServices dbService;
private string redisBaseKey = "Lux:Cache";
#endregion Private Fields
}
}