using static EgwCoreLib.Lux.Core.Enums; namespace Lux.API.Controllers { [Route("api/[controller]")] [ApiController] public class ProdController : ControllerBase { #region Public Constructors /// /// Costruttore metodo /// /// /// /// public ProdController(IProdService prodService, ExternalMessageProcessor extMessProc, ICalcRuidService crService) { _prodService = 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/BEAM/ABC012345 /// GET: api/Prod/getjob/WINDOW/ABC012345 /// /// /// /// [HttpGet("getjob/{envir}/{uid}")] public async Task> GetJob(string envir, string uid) { Constants.EXECENVIRONMENTS cEnvir = Constants.EXECENVIRONMENTS.WINDOW; Enum.TryParse(envir, out cEnvir); var result = await _prodService.GetJobAsync(cEnvir, 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"); } // completo info 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"); } } /// /// 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/WINDOW /// GET: api/Prod/getnext/BEAM /// /// Environment della richiesta /// [HttpGet("getnext/{envir}")] public async Task> GetNext(string envir) { Constants.EXECENVIRONMENTS cEnvir = Constants.EXECENVIRONMENTS.WINDOW; Enum.TryParse(envir, out cEnvir); var result = await _prodService.GetNextAsync(cEnvir); 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"); } // completo info 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 /// /// /// [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: num richieste in coda (se non specificato è waiting, altrimenti ) /// GET: api/Prod/queue-len/WINDOW/ /// GET: api/Prod/queue-len/WINDOW/waiting /// GET: api/Prod/queue-len/WINDOW/running /// GET: api/Prod/queue-len/BEAM/ /// GET: api/Prod/queue-len/BEAM/waiting /// GET: api/Prod/queue-len/BEAM/running /// /// Environment della richiesta /// Tipo coda (default waiting) /// [HttpGet("qlen/{envir}/{type}")] public async Task QueueLen(string envir, ProdQueueType type = ProdQueueType.waiting) { Constants.EXECENVIRONMENTS cEnvir = Constants.EXECENVIRONMENTS.WINDOW; Enum.TryParse(envir, out cEnvir); var result = await _prodService.QueueLenAsync(cEnvir, type); return Ok(result); } /// /// Chiamata GET: dizionario stato richieste /// GET: api/Prod/queue-status/ /// /// Environment della richiesta /// [HttpGet("qstatus/{envir}")] public async Task QueueStatus(string envir) { Stopwatch sw = new Stopwatch(); sw.Start(); Constants.EXECENVIRONMENTS cEnvir = Constants.EXECENVIRONMENTS.WINDOW; Enum.TryParse(envir, out cEnvir); Dictionary queueStatus = new Dictionary(); long numDone = await _prodService.QueueLenAsync(cEnvir, ProdQueueType.done); long numRun = await _prodService.QueueLenAsync(cEnvir, ProdQueueType.running); long numWait = await _prodService.QueueLenAsync(cEnvir, ProdQueueType.waiting); // simulo status... queueStatus.Add("waiting", numWait); queueStatus.Add("running", numRun); queueStatus.Add("done", numDone); sw.Stop(); Log.Info($"QueueStatus | {sw.Elapsed.TotalMilliseconds:N3} ms"); return Ok(queueStatus); } /// /// 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); } [HttpGet("version")] public string version() { var version = Assembly .GetExecutingAssembly() .GetName() .Version? .ToString() ?? "unknown"; return version; } #endregion Public Methods #region Private Fields private static Logger Log = LogManager.GetCurrentClassLogger(); private readonly ICalcRuidService _calcRuidService; private IProdService _prodService; private ExternalMessageProcessor EMProc; #endregion Private Fields } }