using EgwCoreLib.Lux.Core.RestPayload; using EgwCoreLib.Lux.Data.Services; using EgwMultiEngineManager.Data; using Lux.API.Services; using Microsoft.AspNetCore.Cors.Infrastructure; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.SignalR; using Newtonsoft.Json; using NLog; using StackExchange.Redis; using System.Diagnostics; using static EgwCoreLib.Lux.Data.Services.ProdService; namespace Lux.API.Controllers { [Route("api/[controller]")] [ApiController] public class ProdController : ControllerBase { #region Public Constructors /// /// Costruttore metodo /// /// /// /// public ProdController(ProdService prodService, ExternalMessageProcessor extMessProc, CalcRuidService crService) { PService = prodService; EMProc = extMessProc; _calcRuidService = crService; } #endregion Public Constructors #region Public Methods /// /// Chiamata GET: test status alive /// GET: api/Prod/alive /// /// uid oggetto /// [HttpGet("alive")] public async Task Alive() { Stopwatch sw = new Stopwatch(); sw.Start(); await Task.Delay(1); sw.Stop(); Log.Info($"Alive | {sw.Elapsed.TotalMilliseconds:N3} ms"); return Ok("OK"); } /// /// Chiamata GET: /// - fornisce il job da eseguire dalla coda (SE presente) /// GET: api/Prod/getjob/ABC012345 /// /// [HttpGet("getjob/{uid}")] public async Task> GetJob(string uid) { var result = await PService.GetJob(uid); QuestionDTO? deserRes = JsonConvert.DeserializeObject(result); if (deserRes != null) { // verifico RUID code x rigenerarlo... if (deserRes.Args != null) { // elimino vecchio RUID se esistesse... if (deserRes.Args.ContainsKey("RUID")) { deserRes.Args.Remove("RUID"); } // lo aggiungo! string envir = $"{deserRes.ExecEnvironment}"; var mode = deserRes.Args["Mode"]; var sub = deserRes.Args["SubMode"]; string type = string.IsNullOrEmpty(sub) ? mode : $"{mode}-{sub}"; // creo registrazione richiesta... var ruid = await _calcRuidService.AddRequestAsync(envir, type, uid); // aggiungo RUID effettivo deserRes.Args.Add("RUID", ruid); } return Ok(deserRes); } else { return NotFound("No Data Found"); } } private readonly CalcRuidService _calcRuidService; /// /// Chiamata GET: /// - fornisce il primo job da eseguire dalla coda (SE presente) /// - viene registrato come "in corso" e spostato dalla coda richiesta /// GET: api/Prod/getnext /// /// [HttpGet("getnext")] public async Task> GetNext() { var result = await PService.GetNext(); QuestionDTO? deserRes = JsonConvert.DeserializeObject(result); if (deserRes != null) { // verifico RUID code x rigenerarlo... if (deserRes.Args != null) { // elimino vecchio RUID se esistesse... if (deserRes.Args.ContainsKey("RUID")) { deserRes.Args.Remove("RUID"); } // lo aggiungo! string envir = $"{deserRes.ExecEnvironment}"; var mode = deserRes.Args["Mode"]; var sub = deserRes.Args["SubMode"]; var uid = deserRes.Args["UID"]; string type = string.IsNullOrEmpty(sub) ? mode : $"{mode}-{sub}"; // creo registrazione richiesta... var ruid = await _calcRuidService.AddRequestAsync(envir, type, uid); // aggiungo RUID effettivo deserRes.Args.Add("RUID", ruid); } return Ok(deserRes); } else { return NotFound("No Data Available"); } } /// /// Ritorno calcolo /// /// Chiave auth valida (da implementare) /// /// [HttpPost("jobreturn")] public async Task JobReturn([FromBody] AnswerDTO retData) { bool saved = false; // se risposta valida --> processo! if (retData != null) { saved = await EMProc.ProcessAnswer(retData); // se in debug forzo save dell'ultima chiamata comunque... saved = false; // 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... string rawData = JsonConvert.SerializeObject(retData); await EMProc.SaveRawData(UID, retData.ExecEnvironment, rawData); } } // ritorno return saved; } /// /// Chiamata GET: /// - fornisce il job da eseguire dalla coda (SE presente) /// GET: api/Prod/rep-answer/ABC012345 /// /// [HttpGet("rep-answer/{uid}")] public async Task> ReplayAnswer(string uid, int env) { Constants.EXECENVIRONMENTS envir = (Constants.EXECENVIRONMENTS)env; string rawData = await EMProc.LoadRawData(uid, envir); bool saved = false; // provo a riprcessare... var retData = JsonConvert.DeserializeObject(rawData); if (retData != null) { saved = await EMProc.ProcessAnswer(retData); } return Ok(rawData); } /// /// Chiamata GET: num richieste in coda (se non specificato è waiting, altrimenti ) /// GET: api/Prod/queue-len/ /// GET: api/Prod/queue-len/waiting /// GET: api/Prod/queue-len/running /// /// uid oggetto /// [HttpGet("qlen/{type}")] public async Task QueueLen(QueueType type = QueueType.waiting) { var result = await PService.QueueLen(type); return Ok(result); } /// /// Chiamata GET: dizionario stato richieste /// GET: api/Prod/queue-status/ /// /// uid oggetto /// [HttpGet("qstatus")] public async Task QueueStatus() { Stopwatch sw = new Stopwatch(); sw.Start(); Dictionary queueStatus = new Dictionary(); long numWait = await PService.QueueLen(QueueType.waiting); long numRun = await PService.QueueLen(QueueType.running); // simulo status... queueStatus.Add("waiting", numWait); queueStatus.Add("running", numRun); sw.Stop(); Log.Info($"QueueStatus | {sw.Elapsed.TotalMilliseconds:N3} ms"); return Ok(queueStatus); } #endregion Public Methods #region Private Fields private static Logger Log = LogManager.GetCurrentClassLogger(); private ProdService PService; private ExternalMessageProcessor EMProc; #endregion Private Fields } }