From 95f2b208c908bbfc3235ff5567f9541b75d3dbfc Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 16 Jul 2025 16:28:05 +0200 Subject: [PATCH] WS: - inizio modifica x inclusione calcolo MD5 e import DB Ricette --- IOB-UT-NEXT/FtpActConf.cs | 69 +------------------- IOB-UT-NEXT/GenActConf.cs | 80 ++++++++++++++++++++++++ IOB-UT-NEXT/IOB-UT-NEXT.csproj | 5 ++ IOB-UT-NEXT/Objects.cs | 11 ++++ IOB-UT-NEXT/RedisMan.cs | 10 +-- IOB-WIN-FTP/Iob/Ftp.cs | 56 ++++++++--------- IOB-WIN-WS/DATA/CONF/L021.ini | 2 + IOB-WIN-WS/IobWs/EmmegiFPW.cs | 111 +++++++++++++++++++++------------ 8 files changed, 204 insertions(+), 140 deletions(-) create mode 100644 IOB-UT-NEXT/GenActConf.cs diff --git a/IOB-UT-NEXT/FtpActConf.cs b/IOB-UT-NEXT/FtpActConf.cs index 7ee333b0..1d7d3e80 100644 --- a/IOB-UT-NEXT/FtpActConf.cs +++ b/IOB-UT-NEXT/FtpActConf.cs @@ -6,12 +6,8 @@ using System.Threading.Tasks; namespace IOB_UT_NEXT { - public class FtpActConf + public class FtpActConf : GenActConf { - /// - /// ID azione configurata - /// - public string ActionId { get; set; } = "000"; /// /// IP / DNS name del ServerAddr FTP @@ -43,69 +39,6 @@ namespace IOB_UT_NEXT /// public bool SkipCert { get; set; } = true; - /// - /// Tempo di attesa in SEC standard prima della prossima ri-esecuzione - /// - public int ReExecVeto { get; set; } = 60; - - /// - /// Note opzionali - /// - public string Note { get; set; } = ""; - - /// - /// Elenco step da eseguire - /// - public List StepsList { get; set; } - } - /// - /// Configurazione di un singolo step FTP - /// - public class ActionConfig - { - /// - /// ID azione (per ordinamento) - /// - public string Id { get; set; } = "00"; - - /// - /// Descrizione step - /// - public string Description { get; set; } = "00"; - - /// - /// Azione richiesta - /// - public ActType Action { get; set; } = ActType.CheckDir; - - /// - /// Dizionario parametri specifici per azione richiesta (dipendenti da azione...) - /// - public Dictionary ParamList { get; set; } = new Dictionary(); - } - - /// - /// Enum azioni FTP gestite/da gestire - /// - public enum ActType - { - CheckDir, - CheckFile, - CreateDir, - DelDir, - DelFile, - //DelFileList, - DownloadDir, - DownloadFile, - GenRandomDir, - ListContent, - MirrorDirL2R, - MirrorDirR2L, - PingServer, - RemoveFileByName, - UploadDir, - UploadFile - } } diff --git a/IOB-UT-NEXT/GenActConf.cs b/IOB-UT-NEXT/GenActConf.cs new file mode 100644 index 00000000..cac92fbe --- /dev/null +++ b/IOB-UT-NEXT/GenActConf.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IOB_UT_NEXT +{ + public class GenActConf + { + /// + /// ID azione configurata + /// + public string ActionId { get; set; } = "000"; + + /// + /// Tempo di attesa in SEC standard prima della prossima ri-esecuzione + /// + public int ReExecVeto { get; set; } = 60; + + /// + /// Note opzionali + /// + public string Note { get; set; } = ""; + + /// + /// Elenco step da eseguire + /// + public List StepsList { get; set; } + + /// + /// Configurazione di un singolo step FTP + /// + public class ActionConfig + { + /// + /// ID azione (per ordinamento) + /// + public string Id { get; set; } = "00"; + + /// + /// Descrizione step + /// + public string Description { get; set; } = "00"; + + /// + /// Azione richiesta + /// + public ActType Action { get; set; } = ActType.CheckDir; + + /// + /// Dizionario parametri specifici per azione richiesta (dipendenti da azione...) + /// + public Dictionary ParamList { get; set; } = new Dictionary(); + } + + /// + /// Enum azioni gestite/da gestire + /// + public enum ActType + { + CheckDir, + CheckFile, + CreateDir, + DelDir, + DelFile, + //DelFileList, + DownloadDir, + DownloadFile, + GenRandomDir, + ListContent, + MirrorDirL2R, + MirrorDirR2L, + PingServer, + RemoveFileByName, + UploadDir, + UploadFile + } + } +} diff --git a/IOB-UT-NEXT/IOB-UT-NEXT.csproj b/IOB-UT-NEXT/IOB-UT-NEXT.csproj index f494e0ec..d8ceb982 100644 --- a/IOB-UT-NEXT/IOB-UT-NEXT.csproj +++ b/IOB-UT-NEXT/IOB-UT-NEXT.csproj @@ -180,10 +180,12 @@ + + @@ -213,10 +215,13 @@ + + + diff --git a/IOB-UT-NEXT/Objects.cs b/IOB-UT-NEXT/Objects.cs index 0940bb90..e58db839 100644 --- a/IOB-UT-NEXT/Objects.cs +++ b/IOB-UT-NEXT/Objects.cs @@ -59,11 +59,22 @@ namespace IOB_UT_NEXT #endregion Public Methods } + /// + /// Elenco task di tipo FTP + /// public class FtpTaskList { public List ListTask { get; set; } = new List(); } + /// + /// Elenco task generici + /// + public class GenTaskList + { + public List ListTask { get; set; } = new List(); + } + /// /// Gestione dati di timing /// diff --git a/IOB-UT-NEXT/RedisMan.cs b/IOB-UT-NEXT/RedisMan.cs index beef51d8..f5f5f38a 100644 --- a/IOB-UT-NEXT/RedisMan.cs +++ b/IOB-UT-NEXT/RedisMan.cs @@ -13,6 +13,11 @@ namespace IOB_UT_NEXT { #region Public Fields + /// + /// Hash REDIS x dati IOB + /// + public string redIobKey = ""; + /// /// Hash REDIS x dati IOB /// @@ -1425,11 +1430,6 @@ namespace IOB_UT_NEXT /// protected string redIobChannel = "IobChannel"; - /// - /// Hash REDIS x dati IOB - /// - protected string redIobKey = ""; - /// /// Hash REDIS x dati server /// diff --git a/IOB-WIN-FTP/Iob/Ftp.cs b/IOB-WIN-FTP/Iob/Ftp.cs index cb1297c8..3db455b7 100644 --- a/IOB-WIN-FTP/Iob/Ftp.cs +++ b/IOB-WIN-FTP/Iob/Ftp.cs @@ -110,7 +110,7 @@ namespace IOB_WIN_FTP.Iob // Verificare il protocollo: dovrebbe togliere SOLO i task eseguiti... Dictionary taskDone = new Dictionary(); - ActionConfig currAct = new ActionConfig(); + GenActConf.ActionConfig currAct = new GenActConf.ActionConfig(); var currActParam = new Dictionary(); string actKey = "RemoteDir"; string newDir = ""; @@ -153,11 +153,11 @@ namespace IOB_WIN_FTP.Iob actKey = "RemoteDir"; newDir = $"{RemoteBaseDir}/{item.Value}"; currActParam.Add(actKey, newDir); - currAct = new ActionConfig() + currAct = new GenActConf.ActionConfig() { Id = "01", Description = "Verifica esistenza directory", - Action = ActType.CheckDir, + Action = GenActConf.ActType.CheckDir, ParamList = currActParam }; //eseguo step... @@ -166,11 +166,11 @@ namespace IOB_WIN_FTP.Iob if (!dirOk) { // nuovo act x crearla! - currAct = new ActionConfig() + currAct = new GenActConf.ActionConfig() { Id = "02", Description = "Creazione directory", - Action = ActType.CreateDir, + Action = GenActConf.ActType.CreateDir, ParamList = currActParam }; //eseguo step... @@ -359,15 +359,15 @@ namespace IOB_WIN_FTP.Iob if (!string.IsNullOrEmpty(reqFolder)) { // verifico se ci sia... - ActionConfig currAct = new ActionConfig(); + GenActConf.ActionConfig currAct = new GenActConf.ActionConfig(); var currActParam = new Dictionary(); // compongo remDir dai 2 parametri... currActParam.Add("RemoteDir", $"{RemoteBaseDir}/{reqFolder}"); - currAct = new ActionConfig() + currAct = new GenActConf.ActionConfig() { Id = "01", Description = "Verifica esistenza directory", - Action = ActType.CheckDir, + Action = GenActConf.ActType.CheckDir, ParamList = currActParam }; //eseguo step... @@ -655,7 +655,7 @@ namespace IOB_WIN_FTP.Iob /// /// /// - private bool doStep(ActionConfig step) + private bool doStep(GenActConf.ActionConfig step) { bool fatto = false; string remoteVal = ""; @@ -666,7 +666,7 @@ namespace IOB_WIN_FTP.Iob // faccio switch in base al tipo di azione da eseguire... switch (step.Action) { - case ActType.CheckDir: + case GenActConf.ActType.CheckDir: if (step.ParamList != null && step.ParamList.Count > 0) { sw.Restart(); @@ -685,10 +685,10 @@ namespace IOB_WIN_FTP.Iob } break; - case ActType.CheckFile: + case GenActConf.ActType.CheckFile: break; - case ActType.CreateDir: + case GenActConf.ActType.CreateDir: if (step.ParamList != null && step.ParamList.Count > 0) { sw.Restart(); @@ -715,29 +715,29 @@ namespace IOB_WIN_FTP.Iob } break; - case ActType.DelDir: + case GenActConf.ActType.DelDir: break; - case ActType.DelFile: + case GenActConf.ActType.DelFile: break; - case ActType.DownloadDir: + case GenActConf.ActType.DownloadDir: break; - case ActType.DownloadFile: + case GenActConf.ActType.DownloadFile: break; - case ActType.GenRandomDir: + case GenActConf.ActType.GenRandomDir: break; - case ActType.ListContent: + case GenActConf.ActType.ListContent: break; - case ActType.MirrorDirL2R: + case GenActConf.ActType.MirrorDirL2R: break; - case ActType.MirrorDirR2L: + case GenActConf.ActType.MirrorDirR2L: // eseguo mirroring directory actKey = "FtpSync"; actVal = "SRC --> DEST | Size"; @@ -808,10 +808,10 @@ namespace IOB_WIN_FTP.Iob break; - case ActType.PingServer: + case GenActConf.ActType.PingServer: break; - case ActType.RemoveFileByName: + case GenActConf.ActType.RemoveFileByName: string fName2Del = ""; int numRem = 0; if (step.ParamList != null && step.ParamList.Count > 1) @@ -854,10 +854,10 @@ namespace IOB_WIN_FTP.Iob break; - case ActType.UploadDir: + case GenActConf.ActType.UploadDir: break; - case ActType.UploadFile: + case GenActConf.ActType.UploadFile: if (step.ParamList != null && step.ParamList.Count > 1) { sw.Restart(); @@ -964,11 +964,11 @@ namespace IOB_WIN_FTP.Iob Dictionary currActParam = new Dictionary(); currActParam.Add("RemoteDir", remDir); currActParam.Add("FileName2Del", fNameOdl); - ActionConfig currAct = new ActionConfig() + GenActConf.ActionConfig currAct = new GenActConf.ActionConfig() { Id = "01", Description = "Clean Curr ODL Files", - Action = ActType.RemoveFileByName, + Action = GenActConf.ActType.RemoveFileByName, ParamList = currActParam }; // eseguo step... @@ -996,11 +996,11 @@ namespace IOB_WIN_FTP.Iob // invio file x ODL attivo currActParam.Add("LocalFile", locFile); currActParam.Add("RemoteFile", remFile); - ActionConfig currAct = new ActionConfig() + GenActConf.ActionConfig currAct = new GenActConf.ActionConfig() { Id = "01", Description = "Upload File", - Action = ActType.UploadFile, + Action = GenActConf.ActType.UploadFile, ParamList = currActParam }; // eseguo step... diff --git a/IOB-WIN-WS/DATA/CONF/L021.ini b/IOB-WIN-WS/DATA/CONF/L021.ini index 558ca039..5bfebcce 100644 --- a/IOB-WIN-WS/DATA/CONF/L021.ini +++ b/IOB-WIN-WS/DATA/CONF/L021.ini @@ -70,6 +70,8 @@ ENABLE_DYN_DATA=TRUE DISABLE_SEND_WDST=TRUE PARAM_CONF=L021.json REST_CONF=L021.json +;parametri speciali x gestione checkfile +FileInPath=C:\Steamware\EmmegiFPW\FileTaglierina.xlsx [BRANCH] NAME=master \ No newline at end of file diff --git a/IOB-WIN-WS/IobWs/EmmegiFPW.cs b/IOB-WIN-WS/IobWs/EmmegiFPW.cs index 1f357eeb..fc925dc5 100644 --- a/IOB-WIN-WS/IobWs/EmmegiFPW.cs +++ b/IOB-WIN-WS/IobWs/EmmegiFPW.cs @@ -4,6 +4,7 @@ using IOB_UT_NEXT.Config; //using IOB_WIN_WS.DTO; using MapoSDK; using Newtonsoft.Json; +using StackExchange.Redis; using System; using System.Collections.Generic; using System.IO; @@ -311,15 +312,15 @@ namespace IOB_WIN_WS.IobWs parentForm.commPlcActive = true; // chiamo metodo connect - var rawResp = ExecuteCallGet(GetUrlResource("GetStatus"), true); - lgInfo($"GetConnection | {rawResp} | EmmegiFPW.tryConnect"); + var rawData = ExecuteCallGet(GetUrlResource("GetStatus"), true); + lgInfo($"GetConnection | {rawData} | EmmegiFPW.tryConnect"); - if (!string.IsNullOrEmpty(rawResp)) + if (!string.IsNullOrEmpty(rawData)) { connectionOk = true; queueInEnabCurr = true; // salvo lo status con i relativi contenuti... - SaveCurrStatus(rawResp); + SaveCurrStatus(rawData); if (adpRunning) { lgInfo("Connessione EmmegiFPW OK"); @@ -327,7 +328,7 @@ namespace IOB_WIN_WS.IobWs } else { - lgError($"Errore check connessione EmmegiFPW | rawData: {rawResp}"); + lgError($"Errore check connessione EmmegiFPW | rawData: {rawData}"); } } catch (Exception exc) @@ -378,7 +379,7 @@ namespace IOB_WIN_WS.IobWs } } - private EmmegiResp.StatusDTO currStatusDTO = new EmmegiResp.StatusDTO(); + private EmmegiResp.StatusDTO currStatusDTO { get; set; } = new EmmegiResp.StatusDTO(); private EmmegiResp.MachineStatus currState { @@ -408,10 +409,10 @@ namespace IOB_WIN_WS.IobWs /// /// Struttura delle risposte alle chiamare REST specifiche /// - internal class EmmegiResp + public class EmmegiResp { - internal enum MachineStatus + public enum MachineStatus { // manuale ON, @@ -439,7 +440,7 @@ namespace IOB_WIN_WS.IobWs #region Internal Classes [XmlRoot("result_workstation_status")] - internal class StatusDTO + public class StatusDTO { [XmlElement("workstation")] public Workstation Workstation { get; set; } @@ -448,7 +449,7 @@ namespace IOB_WIN_WS.IobWs /// /// Obj workstation /// - internal class Workstation + public class Workstation { [XmlElement("id")] @@ -482,7 +483,7 @@ namespace IOB_WIN_WS.IobWs /// /// Obj WorkstationId /// - internal class WorkstationId + public class WorkstationId { [XmlAttribute("id")] public string IdValue { get; set; } @@ -697,6 +698,11 @@ namespace IOB_WIN_WS.IobWs { bool answ = false; + // verifico esistenza file csv preesistenti, se fossero stati creati otlre xx Ore prima li considera scaduti + + // processo scrittura files PODL con OPRxxx x ogni file missing/scaduto + // NB: impiego array json + dati degli ODL non ancora eseguiti + // conf path e file string basePath = @"x:\"; string srcFile = "DATA/TEMPLATE_ODL_USDT.csv"; @@ -735,36 +741,9 @@ namespace IOB_WIN_WS.IobWs answ = true; } return answ; - } - /// - /// Effettua eventuale file import, archiviando file importati - /// - es gestione file excel di Giacovelli - /// - es gestione ritorno ricette FIMAT - /// - /// - protected virtual bool ProcessFileImport() - { - bool answ = false; - - /* ------------------------------------------ - * esecuzione cablata, si potrebbe costruire una cosa più flessibile tramite conf: - * Oggetto MultiStepFileImport - * { - * StepName: Step01 - * ProcType: Excel2Json - * FolderIn: xxx - * FolderOut: xxx - * FolderErr: xxx - * },{ - * StepName: Step02 - * ProcType: Json2RegGiac - * FolderIn: xxx - * FolderOut: xxx - * FolderErr: xxx - * } - * ------------------------------------------*/ +#if false if (!string.IsNullOrEmpty(fileImportFolder)) { // verifico esistenza folders... @@ -851,6 +830,60 @@ namespace IOB_WIN_WS.IobWs } } } + } +#endif + } + + + /// + /// Effettua eventuale file import del file excel come array json in REDIS + /// + /// + protected override bool ProcessFileImport() + { + bool answ = false; + + /* ------------------------------------------ + * esecuzione cablata, si potrebbe costruire una cosa più flessibile tramite conf, + * la procedura prevede: + * - controllo MD5 file sorgente *.xlsx + * - verifica MD5 precedente + * - verifica in redis del dict seralizzato + * + * in caso di mancanza REDIS o variazione MD5 --> lancio script import dati col relativo file di conf + * ------------------------------------------*/ + + // init condizioni check + bool cachePresent = false; + bool changedFile = true; + // cerco il file da controllare + string FileInPath = IOBConfFull.OptParGet("FileInPath"); + if (!string.IsNullOrEmpty(FileInPath)) + { + if (File.Exists(FileInPath)) + { + // verifico presenza in cache REDIS + string rKey = "IOB-WIN:Conf:ParamsUSTD"; + // $"{redisMan.redIobKey}:FPW:RECIPE-FILE"; + string rawData = redisMan.getRSV(rKey); + cachePresent = !string.IsNullOrEmpty(rawData) && rawData.Length > 2; + if (cachePresent) + { + // calcolo MD5 + string newMd5 = baseUtils.GetFileMd5(FileInPath); + // verifico MD5 precedente + rKey = $"{redisMan.redIobKey}:FPW:FILE-MD5"; + string oldMd5 = redisMan.getRSV(rKey); + changedFile = !newMd5.Equals(oldMd5); + } + // se c'è una condizione di trigger effettuo import chiamando task esterno + conf file + if (changedFile || !cachePresent) + { + // avvio proc import tramite exe tool esterno... + + answ = true; + } + } } return answ; }