using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using MP.FileData; using Newtonsoft.Json; using NLog; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Diagnostics; using MP.FileData.Controllers; using MP.FileData.DTO; namespace MP.Prog.Data { public class FileArchDataService : IDisposable { #region Private Fields private static IConfiguration _configuration; private static ILogger _logger; private static List ElencoMacchine = new List(); private static NLog.Logger Log = LogManager.GetCurrentClassLogger(); private readonly IDistributedCache distributedCache; private readonly IMemoryCache memoryCache; /// /// Durata assoluta massima della cache /// private int chAbsExp = 15; /// /// Durata della cache in modalità inattiva (non acceduta) prima di venire rimossa /// NON estende oltre il tempo massimo di validità della cache (chAbsExp) /// private int chSliExp = 5; #endregion Private Fields #region Protected Fields protected static string connStringBBM = ""; protected static string connStringFatt = ""; #endregion Protected Fields #region Public Fields public static FileData.Controllers.FileController dbController; #endregion Public Fields #region Public Constructors public FileArchDataService(IConfiguration configuration, ILogger logger, IMemoryCache memoryCache, IDistributedCache distributedCache) { _logger = logger; _configuration = configuration; // conf cache this.memoryCache = memoryCache; this.distributedCache = distributedCache; // conf DB string connStr = _configuration.GetConnectionString("Mp.Prog"); if (string.IsNullOrEmpty(connStr)) { _logger.LogError("ConnString empty!"); } else { dbController = new FileData.Controllers.FileController(configuration); _logger.LogInformation("DbController OK"); } } #endregion Public Constructors #region Private Properties private DistributedCacheEntryOptions cacheOpt { get { return new DistributedCacheEntryOptions().SetAbsoluteExpiration(DateTime.Now.AddMinutes(chAbsExp)).SetSlidingExpiration(TimeSpan.FromMinutes(chSliExp)); } } private DistributedCacheEntryOptions cacheOptLong { get { return new DistributedCacheEntryOptions().SetAbsoluteExpiration(DateTime.Now.AddMinutes(chAbsExp * 10)).SetSlidingExpiration(TimeSpan.FromMinutes(chSliExp)); } } #endregion Private Properties #region Internal Methods internal Task FileApprove(FileData.DatabaseModels.FileModel currItem) { return Task.FromResult(dbController.FileModApprove(currItem)); } internal Task FileDelete(FileData.DatabaseModels.FileModel currItem) { return Task.FromResult(dbController.FileDelete(currItem)); } internal Task FileExport(FileData.DatabaseModels.FileModel currItem) { return Task.FromResult(dbController.FileExport(currItem)); } internal Task FileReject(FileData.DatabaseModels.FileModel currItem) { return Task.FromResult(dbController.FileModReject(currItem)); } internal Task FileUpdate(FileData.DatabaseModels.FileModel updItem) { return Task.FromResult(dbController.FileUpdate(updItem)); } internal void ResetController() { dbController.ResetController(); } #endregion Internal Methods #region Public Methods public void Dispose() { // Clear database controller dbController.Dispose(); } public async Task FileCountFilt(SelectData CurrFilter) { int numCount = 0; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); numCount = dbController.FileCountFilt(CurrFilter.IdxMacchina, CurrFilter.OnlyActive, CurrFilter.OnlyMod, CurrFilter.OnlyNoTag, CurrFilter.FileName, CurrFilter.Tag, CurrFilter.SearchVal); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB per FileCountFilt: {ts.TotalMilliseconds} ms"); return await Task.FromResult(numCount); } public Task FileGetByKey(int FileId) { return Task.FromResult(dbController.FileGetByKey(FileId)); } public async Task> FileGetFilt(SelectData CurrFilter) { List dbResult = new List(); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = dbController.FileGetFilt(CurrFilter.IdxMacchina, CurrFilter.OnlyActive, CurrFilter.OnlyMod, CurrFilter.OnlyNoTag, CurrFilter.FileName, CurrFilter.Tag, CurrFilter.SearchVal, CurrFilter.NumSkip, CurrFilter.PageSize).ToList(); //dbResult = dbController.FileGetFilt(CurrFilter.IdxMacchina, CurrFilter.OnlyActive, CurrFilter.OnlyMod, CurrFilter.FirstRecord, CurrFilter.PageSize * 10, CurrFilter.SearchVal).ToList(); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB per FileGetFilt: {ts.TotalMilliseconds} ms"); return await Task.FromResult(dbResult); } public async Task> GetArchiveStatus() { List dbResult = new List(); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); dbResult = dbController.GetArchiveStatus(); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB per GetArchiveStatus: {ts.TotalMilliseconds} ms"); return await Task.FromResult(dbResult); } public Task MacchinaGetByKey(string idxMacchina) { return Task.FromResult(dbController.MacchinaGetByKey(idxMacchina)); } public Task> MacchineGetAll() { return Task.FromResult(dbController.MacchineGetAll().ToList()); } public async Task> MachineList() { List answ = new List(); answ.Add(new AutocompleteModel { LabelField = "--- TUTTE ---", ValueField = "*" }); answ.AddRange(dbController.MacchineGetAll().Select(x => new AutocompleteModel { LabelField = $"{x.IdxMacchina} | {x.Nome} {x.Descrizione} ", ValueField = x.IdxMacchina }).ToList()); return await Task.FromResult(answ); } public void rollBackEdit(object item) { dbController.RollBackEntity(item); } public async Task> TagGetFilt(string SearchVal) { return await Task.FromResult(dbController.TagGetFilt(SearchVal, 200).ToList()); } public Task> TagGetSearch(string searchVal, int numRecord) { List answ = new List(); answ.Add(new AutocompleteModel { LabelField = "--- TUTTE ---", ValueField = "*" }); if (numRecord > -1) { answ.AddRange(dbController.TagGetFilt(searchVal, numRecord).Select(x => new AutocompleteModel { LabelField = $"{x.TagId}", ValueField = x.TagId }).ToList()); } return Task.FromResult(answ); } #if false protected string getCacheKey(string TableName, SelectData CurrFilter) { string answ = $"{TableName}:M_{CurrFilter.IdxMacchina}:A_{CurrFilter.CodArticolo}:K_{CurrFilter.KeyRichiesta}:O_{CurrFilter.IdxOdl}:D_{CurrFilter.DateStart:yyyyMMddHHmm}_{CurrFilter.DateEnd:yyyyMMddHHmm}"; return answ; } protected string getCacheKeyPaged(string TableName, SelectData CurrFilter) { string answ = $"{TableName}:M_{CurrFilter.IdxMacchina}:A_{CurrFilter.CodArticolo}:K_{CurrFilter.KeyRichiesta}:O_{CurrFilter.IdxOdl}:D_{CurrFilter.DateStart:yyMMddHHmm}_{CurrFilter.DateEnd:yyMMddHHmm}:R_{CurrFilter.FirstRecord}_{CurrFilter.FirstRecord + CurrFilter.NumRecord}"; return answ; } #endif /// /// Aggiorna intero archivio scansionando dati x tutte le macchine che hanno un path valido /// /// Numero giorni x ricerca all'indietro da data corrente / 0 = nessun limite /// public async Task updateAllArchive(int numDayPre, bool forceTag) { int checkDone = 0; var listaMacchine = await MacchineGetAll(); foreach (var item in listaMacchine.Where(x => !string.IsNullOrEmpty(x.BasePath)).ToList()) { checkDone += await updateMachineArchive(item.IdxMacchina, numDayPre, forceTag, false); } return await Task.FromResult(checkDone); } /// /// Aggiorna archivio di una amcchina scansionando path relativo /// /// Codice macchina /// Numero giorni x ricerca all'indietro da data corrente / 0 = nessun limite /// Forza la riverifica dei tags (x update da setup) /// Scrittura log verboso macchina /// public async Task updateMachineArchive(string idxMacchina, int numDayPre, bool forceTag, bool fullLog) { int checkDone = 0; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string ruleName = "Rule00.json"; try { var macchina = MacchinaGetByKey(idxMacchina).Result; if (macchina != null && !string.IsNullOrEmpty(macchina.BasePath)) { if (!string.IsNullOrEmpty(macchina.RuleName)) { ruleName = macchina.RuleName; // gestione confRule... SearchRules currRule = new SearchRules(); try { string rawData = File.ReadAllText(FileController.rulePath(ruleName)); currRule = JsonConvert.DeserializeObject(rawData); //Log.Info($"Conf rule acquisito da file {ruleName}:{Environment.NewLine}{rawData}"); } catch (Exception exc) { Log.Error($"Eccezione in deserializzazione conf rule{Environment.NewLine}{exc}"); } // se NON deserializzato inizializzo hard-coded if (currRule.Name == "ND") { // fare: lettura conf rule x recupero tag x singola macchina //$"\\b{fileName}" + @".{0,2}\([\w\d\s.]+\)"; Dictionary confReplace = new Dictionary(); confReplace.Add("(", " "); confReplace.Add(")", " "); Dictionary fileExtReplace = new Dictionary(); fileExtReplace.Add(".P-2", ""); // hard coded + salvataggio conf x creare json currRule = new SearchRules() { Name = "Commento Filename", Mode = SearchMode.StringOnFile, MaxChar2Search = 100, ReplaceCR = true, RegExPattern = "\\b{{fileName}}" + @".{0,2}\([\w\d\s./]+\)", RegExRepFileName = true, FileNameExtReplace = fileExtReplace, ExcludedTags = new List() { "M4", "M5", "M4+A", "M4+B", "M5+A", "M5+B" }, OutReplace = confReplace, OutExcludeFileName = true }; if (fullLog) { // serializzo string rawRule = JsonConvert.SerializeObject(currRule, Formatting.Indented); Log.Trace($"Conf rule generato:{Environment.NewLine}{rawRule}"); } } checkDone = dbController.CheckFileArchived(macchina.IdxMacchina, macchina.BasePath, numDayPre, "*.*", forceTag, currRule); } } } catch (Exception exc) { Log.Error($"Eccezione in updateMachineArchive{Environment.NewLine}{exc}{Environment.NewLine}{exc.InnerException}"); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Info($"Effettuato update archivio file MACCHINA | last {numDayPre} days | {checkDone} checked | {ts.TotalMilliseconds} ms"); return await Task.FromResult(checkDone); } #endregion Public Methods } }