using EgwCoreLib.Lux.Core.RestPayload; using EgwCoreLib.Lux.Data; using EgwCoreLib.Lux.Data.Services; using EgwMultiEngineManager.Data; using Newtonsoft.Json; using NLog; using StackExchange.Redis; using System.Diagnostics; namespace Lux.API.Services { public class ExternalMessageProcessor { #region Public Constructors /// /// Init classe message processor con accesso REDIS e DB /// /// /// public ExternalMessageProcessor(ImageCacheService imgService, DataLayerServices dlService) { cacheService = imgService; dbService = dlService; } #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(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 } /// /// Rilettura della risposta in formato RawData x Debug /// /// /// public async Task LoadRawData(string UID, Constants.EXECENVIRONMENTS envir) { // rileggo string rawData = await cacheService.LoadDebug(UID, envir); return rawData; } /// /// Processing di una risposta AnswerDTO /// /// /// public async Task 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"]; // 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, 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? machineEstimList = new List(); // deserializzo try { #if false machineEstimList = JsonConvert.DeserializeObject>(rawAnsw); #endif 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.SaveEstimationAsync(UID, retData.ExecEnvironment, rawAnsw); 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("ProfileList")) { // recupero UID e elenco profili validi string profList = retData.Args["ProfileList"]; // salvo ProfileList ricevuta await cacheService.SaveProfileListAsync(UID, retData.ExecEnvironment, profList); await dbService.SaveProfileListAsync(UID, retData.ExecEnvironment, profList); saved = true; } } } return saved; } /// /// Salvataggio della risposta in formato RawData x Debug /// /// /// 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 ImageCacheService cacheService; private readonly DataLayerServices dbService; private string redisBaseKey = "Lux:Cache"; #endregion Private Fields } }