diff --git a/IobConf.Core/IobConf.Core.csproj b/IobConf.Core/IobConf.Core.csproj index d36839cf..1aee7485 100644 --- a/IobConf.Core/IobConf.Core.csproj +++ b/IobConf.Core/IobConf.Core.csproj @@ -7,9 +7,9 @@ - - - + + + diff --git a/IobConf.UI/Components/IniConverter.razor b/IobConf.UI/Components/IniConverter.razor index 8396668f..b83224bc 100644 --- a/IobConf.UI/Components/IniConverter.razor +++ b/IobConf.UI/Components/IniConverter.razor @@ -11,48 +11,57 @@
-
-
-
-
-

INI

+ @if (!fileOk) + { +
+ No file found +
+ } + else + { +
+
+
+
+

INI

+
+
+
-
+
+

@confINI

-
-

@confINI

-
-
-
-
-
-
-

JSON

+
+
+
+
+

JSON

+
+
+ +
-
- +
+

@confJson

-
-

@confJson

-
-
-
-
-
-
-

YAML

+
+
+
+
+

YAML

+
+
+ +
-
- +
+

@confYaml

-
-

@confYaml

-
-
+ }
\ No newline at end of file diff --git a/IobConf.UI/Components/IniConverter.razor.cs b/IobConf.UI/Components/IniConverter.razor.cs index a9b777f1..5949b386 100644 --- a/IobConf.UI/Components/IniConverter.razor.cs +++ b/IobConf.UI/Components/IniConverter.razor.cs @@ -7,15 +7,23 @@ namespace IobConf.UI.Components { #region Public Methods - public async Task LoadINI() + public void LoadINI() { checkOutDir(); - await Task.Delay(1); - rawFileContent = File.ReadAllText(iniPath); - confINI=getMarkup(rawFileContent); - CurrentConf = IobConfTree.LoadFromINI(iniPath); - updateConf(); + if (File.Exists(iniPath)) + { + fileOk = true; + rawFileContent = File.ReadAllText(iniPath); + confINI = getMarkup(rawFileContent); + CurrentConf = IobConfTree.LoadFromINI(iniPath); + updateConf(); + } + else + { + fileOk = false; + } } + public async Task SaveJson() { checkOutDir(); @@ -32,13 +40,33 @@ namespace IobConf.UI.Components CurrentConf.SaveYaml(fileName); } - private void updateConf() + #endregion Public Methods + + #region Protected Properties + + protected MarkupString confINI { get; set; } + protected MarkupString confJson { get; set; } + protected MarkupString confYaml { get; set; } + protected IobConfTree CurrentConf { get; set; } = new IobConfTree(); + protected bool fileOk { get; set; } = false; + + protected string iniPath { - // aggiorno conf JSON/YAML - confJson = getMarkup(CurrentConf.GetJson()); - confYaml = getMarkup(CurrentConf.GetYaml()); + get => _iniPath; + set + { + if (!iniPath.Equals(value)) + { + _iniPath = value; + LoadINI(); + } + } } + #endregion Protected Properties + + #region Protected Methods + /// /// Converte la stringa in formato markup valido /// @@ -49,40 +77,26 @@ namespace IobConf.UI.Components return new MarkupString(rawData.Replace("\n", "
").Replace(" ", "  ")); } - protected string iniPath = @"C:\temp\DATA\CONF\SIMUL_01.ini"; - - #endregion Public Methods - - #region Protected Fields - - protected string baseDir = @"c:\temp\IobConf"; - - protected string CodIOB = "NewIOB_00"; - - #endregion Protected Fields - - #region Protected Properties - - protected MarkupString confINI { get; set; } - protected MarkupString confJson { get; set; } - - protected MarkupString confYaml { get; set; } - - protected string rawFileContent = ""; - - protected IobConfTree CurrentConf { get; set; } = new IobConfTree(); - - #endregion Protected Properties - - #region Protected Methods - protected override async Task OnInitializedAsync() { - await LoadINI(); + LoadINI(); + await Task.Delay(1); } #endregion Protected Methods + #region Private Fields + + private string _iniPath = @"C:\temp\DATA\CONF\SIMUL_01.ini"; + + private string baseDir = @"c:\temp\IobConf"; + + private string CodIOB = "NewIOB_00"; + + private string rawFileContent = ""; + + #endregion Private Fields + #region Private Methods private void checkOutDir() @@ -93,6 +107,13 @@ namespace IobConf.UI.Components } } + private void updateConf() + { + // aggiorno conf JSON/YAML + confJson = getMarkup(CurrentConf.GetJson()); + confYaml = getMarkup(CurrentConf.GetYaml()); + } + #endregion Private Methods } } \ No newline at end of file diff --git a/IobConf.UI/IobConf.UI.csproj b/IobConf.UI/IobConf.UI.csproj index e62007f2..398ab854 100644 --- a/IobConf.UI/IobConf.UI.csproj +++ b/IobConf.UI/IobConf.UI.csproj @@ -12,6 +12,10 @@ <_WebToolingArtifacts Remove="Properties\PublishProfiles\IIS04.pubxml" /> + + + + diff --git a/IobConf.UI/NLog.config b/IobConf.UI/NLog.config deleted file mode 100644 index 154a5706..00000000 --- a/IobConf.UI/NLog.config +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - diff --git a/IobConf.UI/Pages/Converter.razor.cs b/IobConf.UI/Pages/Converter.razor.cs index 5da535d4..6c82ddc9 100644 --- a/IobConf.UI/Pages/Converter.razor.cs +++ b/IobConf.UI/Pages/Converter.razor.cs @@ -19,10 +19,5 @@ namespace IobConf.UI.Pages { public partial class Converter { - private int currentCount = 0; - private void IncrementCount() - { - currentCount++; - } } } \ No newline at end of file diff --git a/IobConf.UI/Program.cs b/IobConf.UI/Program.cs index 3b6381ad..b9ce99ac 100644 --- a/IobConf.UI/Program.cs +++ b/IobConf.UI/Program.cs @@ -1,9 +1,16 @@ using IobConf.UI.Data; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Web; +using NLog; +using NLog.Web; var builder = WebApplication.CreateBuilder(args); +var logger = LogManager.Setup() + .LoadConfigurationFromAppSettings() + .GetCurrentClassLogger(); +logger.Info("Program.cs: startup"); + // Add services to the container. builder.Services.AddRazorPages(); builder.Services.AddServerSideBlazor(); @@ -28,4 +35,5 @@ app.UseRouting(); app.MapBlazorHub(); app.MapFallbackToPage("/_Host"); +logger.Info("Run App"); app.Run(); diff --git a/IobConf.UI/appsettings.json b/IobConf.UI/appsettings.json index 10f68b8c..566ce6d4 100644 --- a/IobConf.UI/appsettings.json +++ b/IobConf.UI/appsettings.json @@ -5,5 +5,48 @@ "Microsoft.AspNetCore": "Warning" } }, - "AllowedHosts": "*" + "AllowedHosts": "*", + "NLog": { + "variables": { + "baseFileDir": "${basedir}/logs/", + "layout": "${longdate} | ${uppercase:${level}} | ${logger:shortName=false} | ${message}" + }, + // "internalLogLevel": "Info", + // "internalLogFile": "c:\\temp\\internal-nlog.txt", + "extensions": [ + { "assembly": "NLog.Extensions.Logging" }, + { "assembly": "NLog.Web.AspNetCore" } + ], + "throwConfigExceptions": true, + "targets": { + "async": true, + "logfile": { + "type": "File", + "fileName": "${basedir}/logs/${shortdate}.log", + "archiveEvery": "Day", + "archiveFileName": "${basedir}/logs/old/${shortdate}_{#}.log", + "archiveNumbering": "DateAndSequence", + "archiveAboveSize": "1024000", + "archiveDateFormat": "HH", + "maxArchiveFiles": "60", + "maxArchiveDays": "30" + }, + "logconsole": { + "type": "ColoredConsole", + "layout": "${longdate} | ${uppercase:${level}} | ${logger:shortName=true} | ${message}" + } + }, + "rules": [ + { + "logger": "*", + "minLevel": "Trace", + "writeTo": "logconsole" + }, + { + "logger": "*", + "minLevel": "Info", + "writeTo": "logfile" + } + ] + } } diff --git a/MP-TAB3/MP-TAB3.csproj b/MP-TAB3/MP-TAB3.csproj index a28e2509..8a695a6d 100644 --- a/MP-TAB3/MP-TAB3.csproj +++ b/MP-TAB3/MP-TAB3.csproj @@ -3,7 +3,7 @@ net6.0 enable - 6.16.2406.508 + 6.16.2409.408 enable MP_TAB3 @@ -25,9 +25,13 @@ - - - + + + + + + + diff --git a/MP-TAB3/NLog.config b/MP-TAB3/NLog.config deleted file mode 100644 index 10411f3f..00000000 --- a/MP-TAB3/NLog.config +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/MP-TAB3/Program.cs b/MP-TAB3/Program.cs index 11cb304a..96d5bc17 100644 --- a/MP-TAB3/Program.cs +++ b/MP-TAB3/Program.cs @@ -6,14 +6,21 @@ using Microsoft.AspNetCore.StaticFiles; using Microsoft.Extensions.FileProviders; using MP.Data; using MP.Data.Services; +using NLog; +using NLog.Web; using StackExchange.Redis; using static Org.BouncyCastle.Math.EC.ECCurve; var builder = WebApplication.CreateBuilder(args); +var logger = LogManager.Setup() + .LoadConfigurationFromAppSettings() + .GetCurrentClassLogger(); +logger.Info("Program.cs: startup"); ConfigurationManager configuration = builder.Configuration; // REDIS setup +logger.Info("Setup REDIS"); var cString = configuration.GetConnectionString("Redis"); string connStringRedis = cString ?? "localhost:6379, DefaultDatabase=5, connectTimeout=5000, syncTimeout=5000, asyncTimeout=5000, abortConnect=false, ssl=false"; //string redisSrvAddr = connStringRedis.Substring(0, connStringRedis.IndexOf(":")); @@ -44,6 +51,7 @@ builder.Services.AddScoped(); builder.Services.AddHttpContextAccessor(); +logger.Info("Aggiunti services"); var app = builder.Build(); @@ -79,9 +87,12 @@ if (!string.IsNullOrEmpty(BasePathDisegni)) } } +logger.Info("Add disegni path"); + app.UseRouting(); app.MapBlazorHub(); app.MapFallbackToPage("/_Host"); +logger.Info("Run App"); app.Run(); diff --git a/MP-TAB3/Resources/ChangeLog.html b/MP-TAB3/Resources/ChangeLog.html index bf02e83c..5f90d708 100644 --- a/MP-TAB3/Resources/ChangeLog.html +++ b/MP-TAB3/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

Versione: 6.16.2406.508

+

Versione: 6.16.2409.408


Note di rilascio:
  • diff --git a/MP-TAB3/Resources/VersNum.txt b/MP-TAB3/Resources/VersNum.txt index 27d57623..9fd70b9c 100644 --- a/MP-TAB3/Resources/VersNum.txt +++ b/MP-TAB3/Resources/VersNum.txt @@ -1 +1 @@ -6.16.2406.508 +6.16.2409.408 diff --git a/MP-TAB3/Resources/manifest.xml b/MP-TAB3/Resources/manifest.xml index d2856c26..a7db1dc0 100644 --- a/MP-TAB3/Resources/manifest.xml +++ b/MP-TAB3/Resources/manifest.xml @@ -1,6 +1,6 @@ - 6.16.2406.508 + 6.16.2409.408 https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/MP-TAB3.zip https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/ChangeLog.html false diff --git a/MP-TAB3/appsettings.json b/MP-TAB3/appsettings.json index 5db9c2a2..09876947 100644 --- a/MP-TAB3/appsettings.json +++ b/MP-TAB3/appsettings.json @@ -15,6 +15,49 @@ "MP.Tab": "Server=SQL2016DEV;Database=MoonPro; User ID=sa;Password=keyhammer16; integrated security=False; MultipleActiveResultSets=True; App=MP.TAB3;", "MP.Mag": "Server=SQL2016DEV;Database=MoonPro_MAG; User ID=sa;Password=keyhammer16; integrated security=False; MultipleActiveResultSets=True; App=MP.TAB3;" }, + "NLog": { + "variables": { + "baseFileDir": "${basedir}/logs/", + "layout": "${longdate} | ${uppercase:${level}} | ${logger:shortName=false} | ${message}" + }, + // "internalLogLevel": "Info", + // "internalLogFile": "c:\\temp\\internal-nlog.txt", + "extensions": [ + { "assembly": "NLog.Extensions.Logging" }, + { "assembly": "NLog.Web.AspNetCore" } + ], + "throwConfigExceptions": true, + "targets": { + "async": true, + "logfile": { + "type": "File", + "fileName": "${basedir}/logs/${shortdate}.log", + "archiveEvery": "Day", + "archiveFileName": "${basedir}/logs/old/${shortdate}_{#}.log", + "archiveNumbering": "DateAndSequence", + "archiveAboveSize": "1024000", + "archiveDateFormat": "HH", + "maxArchiveFiles": "60", + "maxArchiveDays": "30" + }, + "logconsole": { + "type": "ColoredConsole", + "layout": "${longdate} | ${uppercase:${level}} | ${logger:shortName=true} | ${message}" + } + }, + "rules": [ + { + "logger": "*", + "minLevel": "Trace", + "writeTo": "logconsole" + }, + { + "logger": "*", + "minLevel": "Info", + "writeTo": "logfile" + } + ] + }, "OptConf": { "msRefresh": "1100", "CodModulo": "MP-TAB3", diff --git a/MP.AppAuth/AppAuthContext.cs b/MP.AppAuth/AppAuthContext.cs index 4ea914e2..c8c74357 100644 --- a/MP.AppAuth/AppAuthContext.cs +++ b/MP.AppAuth/AppAuthContext.cs @@ -59,6 +59,8 @@ namespace MP.AppAuth public virtual DbSet DbSetGruppi2Oper { get; set; } public virtual DbSet DbSetUpdMan { get; set; } public virtual DbSet DbSetVocabolario { get; set; } + public virtual DbSet DbSetPermessi { get; set; } = null!; + public virtual DbSet DbSetPermessi2Funzione { get; set; } = null!; #endregion Public Properties @@ -134,6 +136,72 @@ namespace MP.AppAuth entity.Property(e => e.CodGruppo).HasMaxLength(50); }); + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.CodPermesso); + + entity.ToTable("Permessi"); + + entity.Property(e => e.CodPermesso) + .HasMaxLength(50) + .IsUnicode(false) + .HasColumnName("COD_PERMESSO") + .UseCollation("Latin1_General_CI_AS"); + + entity.Property(e => e.Descrizione) + .HasMaxLength(50) + .IsUnicode(false) + .HasColumnName("DESCRIZIONE") + .UseCollation("Latin1_General_CI_AS"); + + entity.Property(e => e.Gruppo).HasColumnName("GRUPPO"); + + entity.Property(e => e.Nome) + .HasMaxLength(50) + .IsUnicode(false) + .HasColumnName("NOME") + .UseCollation("Latin1_General_CI_AS"); + + entity.Property(e => e.Numero).HasColumnName("NUMERO"); + + entity.Property(e => e.Url) + .HasMaxLength(250) + .IsUnicode(false) + .HasColumnName("URL") + .UseCollation("Latin1_General_CI_AS"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => new { e.CodPermesso, e.CodFunzione }); + + entity.ToTable("Permessi2Funzione"); + + entity.Property(e => e.CodPermesso) + .HasMaxLength(50) + .IsUnicode(false) + .HasColumnName("COD_PERMESSO") + .UseCollation("Latin1_General_CI_AS"); + + entity.Property(e => e.CodFunzione) + .HasMaxLength(31) + .HasColumnName("COD_FUNZIONE") + .UseCollation("Latin1_General_CI_AS"); + + entity.Property(e => e.Readwrite) + .HasMaxLength(1) + .IsUnicode(false) + .HasColumnName("READWRITE") + .IsFixedLength() + .UseCollation("Latin1_General_CI_AS"); + + entity.HasOne(d => d.PermessiNav) + .WithMany(p => p.Permessi2FunzioneNav) + .HasForeignKey(d => d.CodPermesso) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("FK_Permessi2Funzione_Permessi"); + }); + // modelBuilder.Seed(); diff --git a/MP.AppAuth/Controllers/AppAuthController.cs b/MP.AppAuth/Controllers/AppAuthController.cs index d0fce9ae..24757db7 100644 --- a/MP.AppAuth/Controllers/AppAuthController.cs +++ b/MP.AppAuth/Controllers/AppAuthController.cs @@ -11,14 +11,6 @@ namespace MP.AppAuth.Controllers { public class AppAuthController : IDisposable { - #region Private Fields - - private static IConfiguration _configuration; - private static AppAuthContext dbCtx; - private static Logger Log = LogManager.GetCurrentClassLogger(); - - #endregion Private Fields - #region Public Constructors public AppAuthController(IConfiguration configuration) @@ -48,6 +40,7 @@ namespace MP.AppAuth.Controllers } return dbResult; } + /// /// Elenco Record x Gruppi /// @@ -64,28 +57,6 @@ namespace MP.AppAuth.Controllers return dbResult; } - public List AnagOpGetAll(string searchVal) - { - List dbResult = new List(); - using (AppAuthContext localDbCtx = new AppAuthContext(_configuration)) - { - if (!string.IsNullOrEmpty(searchVal)) - { - dbResult = localDbCtx - .DbSetAnagOpr - .Where(x => x.Cognome.Contains(searchVal) || x.Nome.Contains(searchVal)) - .ToList(); - } - else - { - dbResult = localDbCtx - .DbSetAnagOpr - .ToList(); - } - } - // ritorno - return dbResult; - } public List AnagOpByGruppoGetFilt(string codGruppo, string searchVal) { List dbResult = new List(); @@ -122,12 +93,106 @@ namespace MP.AppAuth.Controllers return dbResult; } + public List AnagOpGetAll(string searchVal) + { + List dbResult = new List(); + using (AppAuthContext localDbCtx = new AppAuthContext(_configuration)) + { + if (!string.IsNullOrEmpty(searchVal)) + { + dbResult = localDbCtx + .DbSetAnagOpr + .Where(x => x.Cognome.Contains(searchVal) || x.Nome.Contains(searchVal)) + .ToList(); + } + else + { + dbResult = localDbCtx + .DbSetAnagOpr + .ToList(); + } + } + // ritorno + return dbResult; + } + public void Dispose() { // Clear database context dbCtx.Dispose(); } + /// + /// Elenco completo permessi2funzione + /// + /// + public List Permessi2FunzioneGetAll() + { + List dbResult = new List(); + using (AppAuthContext dbCtx = new AppAuthContext(_configuration)) + { + dbResult = dbCtx + .DbSetPermessi2Funzione + .ToList(); + } + return dbResult; + } + + /// + /// Elenco permessi2funzione filtrato x elenco funzioni + /// + /// + public List Permessi2FunzioneGetFilt(List FunList) + { + List dbResult = new List(); + using (AppAuthContext dbCtx = new AppAuthContext(_configuration)) + { + dbResult = dbCtx + .DbSetPermessi2Funzione + .Where(x => FunList.Contains(x.CodFunzione)) + .ToList(); + } + return dbResult; + } + + /// + /// Elenco completo permessi + /// + /// + public List PermessiGetAll() + { + List dbResult = new List(); + using (AppAuthContext dbCtx = new AppAuthContext(_configuration)) + { + dbResult = dbCtx + .DbSetPermessi + .ToList(); + } + return dbResult; + } + + /// + /// Elenco permessi dato elenco funzioni + /// + /// + /// + public List PermessiGetByFunc(List ListCodFun) + { + List dbResult = new List(); + using (AppAuthContext dbCtx = new AppAuthContext(_configuration)) + { + var listPer = PermessiGetAll(); + var listP2F = Permessi2FunzioneGetFilt(ListCodFun); + + var query = from permesso in listPer + join p2f in listP2F on permesso.CodPermesso equals p2f.CodPermesso + select permesso; + + dbResult = query.ToList(); + } + return dbResult; + } + public void ResetController() { dbCtx = new AppAuthContext(_configuration); @@ -190,5 +255,13 @@ namespace MP.AppAuth.Controllers } #endregion Public Methods + + #region Private Fields + + private static IConfiguration _configuration; + private static AppAuthContext dbCtx; + private static Logger Log = LogManager.GetCurrentClassLogger(); + + #endregion Private Fields } } \ No newline at end of file diff --git a/MP.AppAuth/Controllers/MPUserController.cs b/MP.AppAuth/Controllers/MPUserController.cs new file mode 100644 index 00000000..ab42c488 --- /dev/null +++ b/MP.AppAuth/Controllers/MPUserController.cs @@ -0,0 +1,59 @@ +using Microsoft.Extensions.Configuration; +using MP.AppAuth.Models; +using NLog; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MP.AppAuth.Controllers +{ + public class MPUserController : IDisposable + { + #region Public Constructors + + public MPUserController(IConfiguration configuration) + { + _configuration = configuration; + Log.Info("Avviata classe MPUserController"); + } + + #endregion Public Constructors + + #region Public Methods + + /// + /// Elenco Diritti utente da modulo + /// + /// UserName cercato + /// Modulo desiderato, se "" allora tutti i diritti + /// + public List DirittiUtente(string UserName, string Modulo) + { + List dbResult = new List(); + using (UserAuthContext dbCtx = new UserAuthContext(_configuration)) + { + dbResult = dbCtx + .DbSetUserDiritti + .Where(x => x.UserName == UserName && (string.IsNullOrEmpty(Modulo) || x.Modulo == Modulo)) + .ToList(); + } + return dbResult; + } + + public void Dispose() + { + GC.Collect(); + } + + #endregion Public Methods + + #region Private Fields + + private static IConfiguration _configuration = null!; + private static Logger Log = LogManager.GetCurrentClassLogger(); + + #endregion Private Fields + } +} \ No newline at end of file diff --git a/MP.AppAuth/HwSwInfo.cs b/MP.AppAuth/HwSwInfo.cs index c08ebfbe..464ff70c 100644 --- a/MP.AppAuth/HwSwInfo.cs +++ b/MP.AppAuth/HwSwInfo.cs @@ -46,13 +46,6 @@ namespace MP.AppAuth #endregion Public Constructors -#if false - /// - /// Singleton! - /// - public static HwSwInfo man = new HwSwInfo(); -#endif - #region Public Properties /// diff --git a/MP.AppAuth/MP.AppAuth.csproj b/MP.AppAuth/MP.AppAuth.csproj index 48ce41bc..b8b2a8c4 100644 --- a/MP.AppAuth/MP.AppAuth.csproj +++ b/MP.AppAuth/MP.AppAuth.csproj @@ -16,7 +16,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/MP.AppAuth/Models/Permessi2FunzioneModel.cs b/MP.AppAuth/Models/Permessi2FunzioneModel.cs new file mode 100644 index 00000000..e031e923 --- /dev/null +++ b/MP.AppAuth/Models/Permessi2FunzioneModel.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MP.AppAuth.Models +{ + // + // This is here so CodeMaid doesn't reorganize this document + // + [Table("Permessi2Funzione")] + public partial class Permessi2FunzioneModel + { + public string CodPermesso { get; set; } = null!; + public string CodFunzione { get; set; } = null!; + public string? Readwrite { get; set; } + + public virtual PermessiModel PermessiNav { get; set; } = null!; + } +} diff --git a/MP.AppAuth/Models/PermessiModel.cs b/MP.AppAuth/Models/PermessiModel.cs new file mode 100644 index 00000000..007aee5c --- /dev/null +++ b/MP.AppAuth/Models/PermessiModel.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MP.AppAuth.Models +{ + // + // This is here so CodeMaid doesn't reorganize this document + // + [Table("Permessi")] + public partial class PermessiModel + { + public PermessiModel() + { + Permessi2FunzioneNav = new HashSet(); + } + + public string CodPermesso { get; set; } = null!; + public string Url { get; set; } = null!; + public int? Gruppo { get; set; } + public int? Numero { get; set; } + public string? Nome { get; set; } + public string? Descrizione { get; set; } + + public virtual ICollection Permessi2FunzioneNav { get; set; } + } +} diff --git a/MP.AppAuth/Models/UserDirittiModel.cs b/MP.AppAuth/Models/UserDirittiModel.cs new file mode 100644 index 00000000..f097342e --- /dev/null +++ b/MP.AppAuth/Models/UserDirittiModel.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MP.AppAuth.Models +{ + + // + // This is here so CodeMaid doesn't reorganize this document + // + [Table("DIRITTI")] + public partial class UserDirittiModel + { + [Column("USER_NAME"), MaxLength(50)] + public string UserName { get; set; } = ""; + [Column("COD_CDC"), MaxLength(50)] + public string CdC { get; set; } = ""; + [Column("COD_MODULO"), MaxLength(31)] + public string Modulo { get; set; } = ""; + [Column("COD_FUNZIONE"), MaxLength(31)] + public string Funzione { get; set; } = ""; + [Column("VALUE"), MaxLength(255)] + public string? Valore { get; set; } = ""; + } +} diff --git a/MP.AppAuth/UserAuthContext.cs b/MP.AppAuth/UserAuthContext.cs new file mode 100644 index 00000000..8a0823aa --- /dev/null +++ b/MP.AppAuth/UserAuthContext.cs @@ -0,0 +1,104 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using MP.AppAuth.Models; +using NLog; +using NLog.Fluent; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MP.AppAuth +{ + public partial class UserAuthContext : DbContext + { + #region Public Constructors + + [Obsolete("This constructor should never be used directly, and is only needed to generate entityframework stuff. Connection string can be adapted as pleased.")] + public UserAuthContext() + { + } + + public UserAuthContext(IConfiguration configuration) + { + _configuration = configuration; + try + { + // se non ci fosse... crea o migra! + Database.Migrate(); + } + catch (Exception exc) + { + Log.Error(exc, "Exception during context initialization 01"); + } + } + + public UserAuthContext(DbContextOptions options) : base(options) + { + try + { + // se non ci fosse... crea o migra! + Database.Migrate(); + } + catch (Exception exc) + { + Log.Error(exc, "Exception during context initialization 02"); + } + } + + #endregion Public Constructors + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + if (!optionsBuilder.IsConfigured) + { + string connString = _configuration.GetConnectionString("MP.Land.Auth"); + if (!string.IsNullOrEmpty(connString)) + { + optionsBuilder.UseSqlServer(connString); + } + else + { + optionsBuilder.UseSqlServer("Server=SQL2016DEV;Database=MoonPro_Anagrafica;Trusted_Connection=True;"); + } + } + } + + #region Public Properties + + public virtual DbSet DbSetUserDiritti { get; set; } = null!; + + #endregion Public Properties + + #region Protected Methods + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity(entity => + { + entity.HasKey(e => new { e.UserName, e.CdC, e.Modulo, e.Funzione }); + + entity.ToTable("DIRITTI"); + }); + + OnModelCreatingPartial(modelBuilder); + } + + #endregion Protected Methods + + #region Private Fields + + private static NLog.Logger Log = LogManager.GetCurrentClassLogger(); + + private IConfiguration _configuration; + + #endregion Private Fields + + #region Private Methods + + partial void OnModelCreatingPartial(ModelBuilder modelBuilder); + + #endregion Private Methods + } +} \ No newline at end of file diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index c5a2f7fd..9ba39d77 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -207,7 +207,7 @@ namespace MP.Data.Controllers dbResult = dbCtx .DbSetArticoli .AsNoTracking() - .Where(x => (azienda == "*" || x.Azienda.Equals(azienda, StringComparison.InvariantCultureIgnoreCase)) && (string.IsNullOrEmpty(searchVal) || x.CodArticolo.Contains(searchVal) || x.DescArticolo.Contains(searchVal) || x.Disegno.Contains(searchVal))) + .Where(x => (azienda == "*" || x.Azienda.ToLower().Equals(azienda.ToLower())) && (string.IsNullOrEmpty(searchVal) || x.CodArticolo.Contains(searchVal) || x.DescArticolo.Contains(searchVal) || x.Disegno.Contains(searchVal))) .OrderBy(x => x.CodArticolo) .Take(numRecord) .ToList(); diff --git a/MP.Data/MP.Data.csproj b/MP.Data/MP.Data.csproj index 93a7fb20..247dff73 100644 --- a/MP.Data/MP.Data.csproj +++ b/MP.Data/MP.Data.csproj @@ -18,22 +18,22 @@ - + - - - - - - - + + + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + \ No newline at end of file diff --git a/MP.FileData/MP.FileData.csproj b/MP.FileData/MP.FileData.csproj index 529ef021..2b9b560a 100644 --- a/MP.FileData/MP.FileData.csproj +++ b/MP.FileData/MP.FileData.csproj @@ -6,20 +6,19 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + diff --git a/MP.INVE/Data/MiDataService.cs b/MP.INVE/Data/MiDataService.cs index 09b5488e..d4b71a40 100644 --- a/MP.INVE/Data/MiDataService.cs +++ b/MP.INVE/Data/MiDataService.cs @@ -6,6 +6,7 @@ using StackExchange.Redis; using System.Diagnostics; using EgwCoreLib.Razor; using EgwCoreLib.Razor.Data; +using EgwCoreLib.Utils; namespace MP.INVE.Data { diff --git a/MP.INVE/MP.INVE.csproj b/MP.INVE/MP.INVE.csproj index 13ee92b2..60f976f6 100644 --- a/MP.INVE/MP.INVE.csproj +++ b/MP.INVE/MP.INVE.csproj @@ -5,7 +5,7 @@ enable enable MP.INVE - 6.16.2402.1914 + 6.16.2409.408 @@ -21,11 +21,14 @@ - + - - + + + + + diff --git a/MP.INVE/NLog.config b/MP.INVE/NLog.config deleted file mode 100644 index b32ba10a..00000000 --- a/MP.INVE/NLog.config +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/MP.INVE/Program.cs b/MP.INVE/Program.cs index 76d25e2a..e6c81e3f 100644 --- a/MP.INVE/Program.cs +++ b/MP.INVE/Program.cs @@ -6,6 +6,8 @@ using Microsoft.AspNetCore.Components.Web; using MP.INVE.Components; using MP.INVE.Data; using MP.INVE.Services; +using NLog; +using NLog.Web; using StackExchange.Redis; var builder = WebApplication.CreateBuilder(args); @@ -18,9 +20,16 @@ var builder = WebApplication.CreateBuilder(args); * * */ + +var logger = LogManager.Setup() + .LoadConfigurationFromAppSettings() + .GetCurrentClassLogger(); +logger.Info("Program.cs: startup"); + ConfigurationManager configuration = builder.Configuration; // REDIS setup +logger.Info("Setup REDIS"); string connStringRedis = configuration.GetConnectionString("Redis"); string redisSrvAddr = connStringRedis.Substring(0, connStringRedis.IndexOf(":")); // avvio oggetto shared x redis... @@ -41,6 +50,8 @@ builder.Services.AddBlazoredLocalStorage(); builder.Services.AddHttpClient(); builder.Services.AddSingleton(); +logger.Info("Aggiunti services"); + var app = builder.Build(); // Configure the HTTP request pipeline. @@ -60,4 +71,5 @@ app.UseRouting(); app.MapBlazorHub(); app.MapFallbackToPage("/_Host"); +logger.Info("Run App"); app.Run(); diff --git a/MP.INVE/Resources/ChangeLog.html b/MP.INVE/Resources/ChangeLog.html index 133369ca..b166755d 100644 --- a/MP.INVE/Resources/ChangeLog.html +++ b/MP.INVE/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOINVE -

    Versione: 6.16.2402.1914

    +

    Versione: 6.16.2409.408


    Note di rilascio:
    • diff --git a/MP.INVE/Resources/VersNum.txt b/MP.INVE/Resources/VersNum.txt index a4449e2e..9fd70b9c 100644 --- a/MP.INVE/Resources/VersNum.txt +++ b/MP.INVE/Resources/VersNum.txt @@ -1 +1 @@ -6.16.2402.1914 +6.16.2409.408 diff --git a/MP.INVE/Resources/manifest.xml b/MP.INVE/Resources/manifest.xml index 7d28b553..9866626f 100644 --- a/MP.INVE/Resources/manifest.xml +++ b/MP.INVE/Resources/manifest.xml @@ -1,6 +1,6 @@ - 6.16.2402.1914 + 6.16.2409.408 https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/MP.INVE.zip https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/ChangeLog.html false diff --git a/MP.INVE/appsettings.json b/MP.INVE/appsettings.json index 7511901f..0caf0371 100644 --- a/MP.INVE/appsettings.json +++ b/MP.INVE/appsettings.json @@ -5,6 +5,49 @@ "Microsoft.AspNetCore": "Warning" } }, + "NLog": { + "variables": { + "baseFileDir": "${basedir}/logs/", + "layout": "${longdate} | ${uppercase:${level}} | ${logger:shortName=false} | ${message}" + }, + // "internalLogLevel": "Info", + // "internalLogFile": "c:\\temp\\internal-nlog.txt", + "extensions": [ + { "assembly": "NLog.Extensions.Logging" }, + { "assembly": "NLog.Web.AspNetCore" } + ], + "throwConfigExceptions": true, + "targets": { + "async": true, + "logfile": { + "type": "File", + "fileName": "${basedir}/logs/${shortdate}.log", + "archiveEvery": "Day", + "archiveFileName": "${basedir}/logs/old/${shortdate}_{#}.log", + "archiveNumbering": "DateAndSequence", + "archiveAboveSize": "1024000", + "archiveDateFormat": "HH", + "maxArchiveFiles": "60", + "maxArchiveDays": "30" + }, + "logconsole": { + "type": "ColoredConsole", + "layout": "${longdate} | ${uppercase:${level}} | ${logger:shortName=true} | ${message}" + } + }, + "rules": [ + { + "logger": "*", + "minLevel": "Trace", + "writeTo": "logconsole" + }, + { + "logger": "*", + "minLevel": "Info", + "writeTo": "logfile" + } + ] + }, "AllowedHosts": "*", "CodApp": "MP.INVE", "ConnectionStrings": { diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj index 2d6759b0..c18c95c9 100644 --- a/MP.IOC/MP.IOC.csproj +++ b/MP.IOC/MP.IOC.csproj @@ -22,9 +22,10 @@ - - - + + + + diff --git a/MP.IOC/Program.cs b/MP.IOC/Program.cs index 6bfc3270..fc2ab5ae 100644 --- a/MP.IOC/Program.cs +++ b/MP.IOC/Program.cs @@ -1,9 +1,16 @@ using Microsoft.Extensions.Configuration; using MP.IOC.Data; +using NLog; +using NLog.Web; using StackExchange.Redis; var builder = WebApplication.CreateBuilder(args); +var logger = LogManager.Setup() + .LoadConfigurationFromAppSettings() + .GetCurrentClassLogger(); +logger.Info("Program.cs: startup"); + // Add services to the container. builder.Services.AddControllers(); @@ -13,6 +20,7 @@ builder.Services.AddSwaggerGen(); ConfigurationManager configuration = builder.Configuration; // REDIS setup +logger.Info("Setup REDIS"); string connStringRedis = configuration.GetConnectionString("Redis"); string redisSrvAddr = connStringRedis.Substring(0, connStringRedis.IndexOf(":")); // avvio oggetto shared x redis... @@ -28,6 +36,7 @@ if (app.Environment.IsDevelopment() || app.Environment.IsStaging()) app.UseSwagger(); app.UseSwaggerUI(); } +logger.Info("Added swagger"); app.UseHttpsRedirection(); @@ -39,4 +48,6 @@ app.UseStaticFiles(); app.MapControllers(); +logger.Info("Run App"); + app.Run(); diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html index 46297c1a..2aa300c6 100644 --- a/MP.IOC/Resources/ChangeLog.html +++ b/MP.IOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-IOC -

      Versione: 6.16.2310.411

      +

      Versione: 6.16.2409.409


      Note di rilascio:
      • diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt index e1d45667..aa8ead2c 100644 --- a/MP.IOC/Resources/VersNum.txt +++ b/MP.IOC/Resources/VersNum.txt @@ -1 +1 @@ -6.16.2310.411 +6.16.2409.409 diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml index b9a0b9da..28cce849 100644 --- a/MP.IOC/Resources/manifest.xml +++ b/MP.IOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 6.16.2310.411 + 6.16.2409.409 https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html false diff --git a/MP.IOC/appsettings.json b/MP.IOC/appsettings.json index cc3c93b2..f272f2db 100644 --- a/MP.IOC/appsettings.json +++ b/MP.IOC/appsettings.json @@ -5,6 +5,49 @@ "Microsoft.AspNetCore": "Warning" } }, + "NLog": { + "variables": { + "baseFileDir": "${basedir}/logs/", + "layout": "${longdate} | ${uppercase:${level}} | ${logger:shortName=false} | ${message}" + }, + // "internalLogLevel": "Info", + // "internalLogFile": "c:\\temp\\internal-nlog.txt", + "extensions": [ + { "assembly": "NLog.Extensions.Logging" }, + { "assembly": "NLog.Web.AspNetCore" } + ], + "throwConfigExceptions": true, + "targets": { + "async": true, + "logfile": { + "type": "File", + "fileName": "${basedir}/logs/${shortdate}.log", + "archiveEvery": "Day", + "archiveFileName": "${basedir}/logs/old/${shortdate}_{#}.log", + "archiveNumbering": "DateAndSequence", + "archiveAboveSize": "1024000", + "archiveDateFormat": "HH", + "maxArchiveFiles": "60", + "maxArchiveDays": "30" + }, + "logconsole": { + "type": "ColoredConsole", + "layout": "${longdate} | ${uppercase:${level}} | ${logger:shortName=true} | ${message}" + } + }, + "rules": [ + { + "logger": "*", + "minLevel": "Trace", + "writeTo": "logconsole" + }, + { + "logger": "*", + "minLevel": "Info", + "writeTo": "logfile" + } + ] + }, "AllowedHosts": "*", "CodApp": "MP.IOC", "ConnectionStrings": { diff --git a/MP.Land/Data/AppAuthService.cs b/MP.Land/Data/AppAuthService.cs index a4c803b7..0ce151e2 100644 --- a/MP.Land/Data/AppAuthService.cs +++ b/MP.Land/Data/AppAuthService.cs @@ -1,17 +1,15 @@ using Microsoft.Extensions.Configuration; -using System; using Microsoft.Extensions.Logging; +using MP.AppAuth.Controllers; +using MP.AppAuth.Models; +using Newtonsoft.Json; +using NLog; +using StackExchange.Redis; +using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Threading.Tasks; -using NLog; -using Microsoft.Extensions.Caching.Distributed; -using Microsoft.Extensions.Caching.Memory; -using System.Diagnostics; -using System.Text; -using Newtonsoft.Json; -using System.Diagnostics.Eventing.Reader; -using MP.AppAuth.Models; namespace MP.Land.Data { @@ -19,20 +17,36 @@ namespace MP.Land.Data { #region Public Fields - public static AppAuth.Controllers.AppAuthController dbController; - public static AppAuth.Controllers.MPController MpDbController; + // diritti (cablòato) + public const string RoleSuperAdmin = "MoonPro_SuperAdmin"; + + public static AppAuthController dbController; + public static MPController MpDbController; + public static MPUserController userController; #endregion Public Fields #region Public Constructors - public AppAuthService(IConfiguration configuration, ILogger logger, IMemoryCache memoryCache, IDistributedCache distributedCache) + public AppAuthService(IConfiguration configuration, ILogger logger, IConnectionMultiplexer redisConnMult) { _logger = logger; _configuration = configuration; - // conf cache - this.memoryCache = memoryCache; - this.distributedCache = distributedCache; + + // cod app + CodApp = _configuration.GetValue("ServerConf:CodApp"); + Modulo = _configuration.GetValue("ServerConf:Modulo"); + + // Conf cache + redisConn = redisConnMult; + redisDb = this.redisConn.GetDatabase(); + + // json serializer... FIX errore loop circolare https://www.ryadel.com/en/jsonserializationexception-self-referencing-loop-detected-error-fix-entity-framework-asp-net-core/ + JSSettings = new JsonSerializerSettings() + { + ReferenceLoopHandling = ReferenceLoopHandling.Ignore + }; + // conf DB string connStr = _configuration.GetConnectionString("MP.Land"); if (string.IsNullOrEmpty(connStr)) @@ -41,8 +55,9 @@ namespace MP.Land.Data } else { - dbController = new AppAuth.Controllers.AppAuthController(configuration); - MpDbController = new AppAuth.Controllers.MPController(configuration); + dbController = new AppAuthController(configuration); + MpDbController = new MPController(configuration); + userController = new MPUserController(configuration); _logger.LogInformation("DbController OK"); } } @@ -200,6 +215,41 @@ namespace MP.Land.Data return await Task.FromResult(answ); } + /// + /// Elenco diritti dato utente + /// + /// + /// + public async Task> DirittiGetByUser(string UserName) + { + string source = "DB"; + List? dbResult = new List(); + string currKey = $"{rKeyDirittiUser}:{UserName}"; + Stopwatch sw = new Stopwatch(); + sw.Start(); + string? rawData = await redisDb.StringGetAsync(currKey); + if (!string.IsNullOrEmpty(rawData) && rawData.Length > 2) + { + source = "REDIS"; + var tempResult = JsonConvert.DeserializeObject>(rawData); + dbResult = tempResult ?? new List(); + } + else + { + // recupero diritti utente + dbResult = userController.DirittiUtente(UserName, Modulo); + rawData = JsonConvert.SerializeObject(dbResult, JSSettings); + await redisDb.StringSetAsync(currKey, rawData, UltraLongCache); + } + if (dbResult == null) + { + dbResult = new List(); + } + sw.Stop(); + Log.Debug($"DirittiGetByUser | {source} | {sw.ElapsedMilliseconds} ms"); + return dbResult; + } + public void Dispose() { // Clear database controller @@ -207,15 +257,65 @@ namespace MP.Land.Data MpDbController.Dispose(); } - public async Task ResetCache() + public async Task FlushRedisCache() { - string cacheKey = ":MP:VOCAB"; - await distributedCache.RemoveAsync(cacheKey); + RedisValue pattern = new RedisValue($"{redisBaseAddr}:*"); + bool answ = await ExecFlushRedisPattern(pattern); // reset in RAM Vocabolario = new Dictionary(); CheckVoc(); } + /// + /// Elenco permessi dato utente + /// + /// + /// + public async Task> PermessiGetByUser(string UserName) + { + string source = "DB"; + List? dbResult = new List(); + string currKey = $"{rKeyPermUser}:{UserName}"; + Stopwatch sw = new Stopwatch(); + sw.Start(); + string? rawData = await redisDb.StringGetAsync(currKey); + if (!string.IsNullOrEmpty(rawData)) + { + source = "REDIS"; + var tempResult = JsonConvert.DeserializeObject>(rawData); + if (tempResult == null) + { + dbResult = new List(); + } + else + { + dbResult = tempResult; + } + } + else + { + // recupero diritti utente + var userRightList = userController.DirittiUtente(UserName, Modulo); + // proietto come funzioni... + var ListFunc = userRightList.Select(x => x.Funzione).ToList(); + // trasformo i permessi utente + if (ListFunc == null) + { + ListFunc = new List(); + } + dbResult = dbController.PermessiGetByFunc(ListFunc); + rawData = JsonConvert.SerializeObject(dbResult, JSSettings); + await redisDb.StringSetAsync(currKey, rawData, UltraLongCache); + } + if (dbResult == null) + { + dbResult = new List(); + } + sw.Stop(); + Log.Debug($"PermessiGetByUser | {source} | {sw.ElapsedMilliseconds} ms"); + return dbResult; + } + public string Traduci(string lemma, string lingua = "IT") { string answ = $"__{lemma}__"; @@ -295,28 +395,29 @@ namespace MP.Land.Data protected void CheckVoc() { - string cacheKey = ":MP:VOCAB"; - string rawData; if (Vocabolario.Count == 0) { - var redisDataList = distributedCache.Get(cacheKey); - if (redisDataList != null) + string source = "DB"; + string currKey = $"{redisBaseAddr}:MP:VOCAB"; + Stopwatch sw = new Stopwatch(); + sw.Start(); + string? rawData = redisDb.StringGet(currKey); + if (!string.IsNullOrEmpty(rawData) && rawData.Length > 2) { - rawData = Encoding.UTF8.GetString(redisDataList); - Vocabolario = JsonConvert.DeserializeObject>(rawData); + source = "REDIS"; + var tempResult = JsonConvert.DeserializeObject>(rawData); + Vocabolario = tempResult ?? new Dictionary(); } else { - Stopwatch stopWatch = new Stopwatch(); - stopWatch.Start(); - Vocabolario = dbController.VocabolarioGetAll().ToDictionary(x => $"{x.Lingua}#{x.Lemma}", x => x.Traduzione); + Vocabolario = dbController + .VocabolarioGetAll() + .ToDictionary(x => $"{x.Lingua}#{x.Lemma}", x => x.Traduzione); rawData = JsonConvert.SerializeObject(Vocabolario); - redisDataList = Encoding.UTF8.GetBytes(rawData); - distributedCache.Set(cacheKey, redisDataList, cacheOptLong); - stopWatch.Stop(); - TimeSpan ts = stopWatch.Elapsed; - Log.Trace($"Effettuato rilettura da DB + caching per VocabolarioModel: {ts.TotalMilliseconds} ms"); + redisDb.StringSet(currKey, rawData, UltraLongCache); } + sw.Stop(); + Log.Trace($"Rilettura Vocabolario | {source} | {sw.ElapsedMilliseconds} ms"); } } @@ -324,28 +425,47 @@ namespace MP.Land.Data #region Private Fields + // gestione key Redis + private const string redisBaseAddr = "MP:LAND"; + + private const string rKeyDirittiUser = $"{redisBaseAddr}:DIR_USER"; + + private const string rKeyPermUser = $"{redisBaseAddr}:PERM_USER"; + private static IConfiguration _configuration; private static ILogger _logger; private static List ElencoMacchine = new List(); + private static JsonSerializerSettings? JSSettings; + private static Logger Log = LogManager.GetCurrentClassLogger(); - private readonly IDistributedCache distributedCache; - - private readonly IMemoryCache memoryCache; + private static string Modulo = ""; /// - /// Durata assoluta massima della cache + /// Durata cache lunga IN SECONDI /// - private int chAbsExp = 15; + private int cacheTtlLong = 60 * 5; /// - /// Durata della cache in modalità inattiva (non acceduta) prima di venire rimossa NON - /// estende oltre il tempo massimo di validità della cache (chAbsExp) + /// Durata cache breve IN SECONDI /// - private int chSliExp = 5; + private int cacheTtlShort = 60 * 1; + + /// + /// Oggetto per connessione a REDIS + /// + private IConnectionMultiplexer redisConn; + + //ISubscriber sub = redis.GetSubscriber(); + /// + /// Oggetto DB redis da impiegare x chiamate R/W + /// + private IDatabase redisDb = null!; + + private Random rnd = new Random(); private Dictionary Vocabolario = new Dictionary(); @@ -353,22 +473,63 @@ namespace MP.Land.Data #region Private Properties - private DistributedCacheEntryOptions cacheOpt + private string CodApp { get; set; } = ""; + + /// + /// Durata cache lunga (+ perturbazione percentuale +/-10%) + /// + private TimeSpan FastCache { - get - { - return new DistributedCacheEntryOptions().SetAbsoluteExpiration(DateTime.Now.AddMinutes(chAbsExp)).SetSlidingExpiration(TimeSpan.FromMinutes(chSliExp)); - } + get => TimeSpan.FromSeconds(cacheTtlShort * rnd.Next(900, 1100) / 1000); } - private DistributedCacheEntryOptions cacheOptLong + /// + /// Durata cache lunga (+ perturbazione percentuale +/-10%) + /// + private TimeSpan LongCache { - get - { - return new DistributedCacheEntryOptions().SetAbsoluteExpiration(DateTime.Now.AddMinutes(chAbsExp * 10)).SetSlidingExpiration(TimeSpan.FromMinutes(chSliExp)); - } + get => TimeSpan.FromSeconds(cacheTtlLong * rnd.Next(900, 1100) / 1000); + } + + /// + /// Durata cache lunga (+ perturbazione percentuale +/-10%) + /// + private TimeSpan UltraLongCache + { + get => TimeSpan.FromSeconds(cacheTtlLong * 10 * rnd.Next(900, 1100) / 1000); } #endregion Private Properties + + #region Private Methods + + /// + /// Esegue flush memoria redis dato pattern + /// + /// + /// + private async Task ExecFlushRedisPattern(RedisValue pattern) + { + bool answ = false; + var listEndpoints = redisConn.GetEndPoints(); + foreach (var endPoint in listEndpoints) + { + //var server = redisConnAdmin.GetServer(listEndpoints[0]); + var server = redisConn.GetServer(endPoint); + if (server != null) + { + var keyList = server.Keys(redisDb.Database, pattern); + foreach (var item in keyList) + { + await redisDb.KeyDeleteAsync(item); + } + answ = true; + } + } + + return answ; + } + + #endregion Private Methods } } \ No newline at end of file diff --git a/MP.Land/Data/LicenseService.cs b/MP.Land/Data/LicenseService.cs index ede92400..6d342015 100644 --- a/MP.Land/Data/LicenseService.cs +++ b/MP.Land/Data/LicenseService.cs @@ -5,6 +5,7 @@ using Microsoft.Extensions.Logging; using MP.AppAuth.Models; using Newtonsoft.Json; using RestSharp; +using StackExchange.Redis; using System; using System.Collections.Generic; using System.Linq; @@ -28,12 +29,20 @@ namespace MP.Land.Data ///
    /// /// - /// - public LicenseService(IConfiguration configuration, ILogger logger, IDistributedCache distributedCache) + /// + public LicenseService(IConfiguration configuration, ILogger logger, IConnectionMultiplexer redisConnMult) { _logger = logger; _configuration = configuration; - this.distributedCache = distributedCache; + // Conf cache + redisConn = redisConnMult; + redisDb = this.redisConn.GetDatabase(); + + // json serializer... FIX errore loop circolare https://www.ryadel.com/en/jsonserializationexception-self-referencing-loop-detected-error-fix-entity-framework-asp-net-core/ + JSSettings = new JsonSerializerSettings() + { + ReferenceLoopHandling = ReferenceLoopHandling.Ignore + }; } #endregion Public Constructors @@ -114,7 +123,6 @@ namespace MP.Land.Data { List dbResult = new List(); string cacheKey = $"{rKeyAttByLic}:{MasterKey}"; - trackCache(cacheKey); string rawData = await getRSV(cacheKey); if (!string.IsNullOrEmpty(rawData)) { @@ -226,7 +234,6 @@ namespace MP.Land.Data { List dbResult = new List(); string cacheKey = $"{rkeyAppInfo}:{MasterKey}"; - trackCache(cacheKey); string rawData = await getRSV(cacheKey); if (!string.IsNullOrEmpty(rawData)) { @@ -281,7 +288,8 @@ namespace MP.Land.Data bool fatto = false; string cacheKey = $"{rKeyAttByLic}:{MasterKey}"; var rawData = JsonConvert.SerializeObject(newActList); - await setRSV(cacheKey, rawData, numDays * cacheFact * 24); + TimeSpan cacheTs = TimeSpan.FromDays(numDays); + await setRSV(cacheKey, rawData, cacheTs); fatto = true; if (EA_InfoUpdated != null) { @@ -295,7 +303,8 @@ namespace MP.Land.Data bool fatto = false; string cacheKey = $"{rkeyAppInfo}:{MasterKey}"; var rawData = JsonConvert.SerializeObject(newAppInfo); - await setRSV(cacheKey, rawData, numDays * cacheFact * 24); + TimeSpan cacheTs = TimeSpan.FromDays(numDays); + await setRSV(cacheKey, rawData, cacheTs); fatto = true; if (EA_InfoUpdated != null) { @@ -362,12 +371,8 @@ namespace MP.Land.Data /// protected async Task getRSV(string rKey) { - string answ = ""; - var redisDataList = await distributedCache.GetAsync(rKey); - if (redisDataList != null) - { - answ = Encoding.UTF8.GetString(redisDataList); - } + var rawData = await redisDb.StringGetAsync(rKey); + string answ = rawData.HasValue ? $"{rawData}" : ""; return answ; } @@ -376,14 +381,11 @@ namespace MP.Land.Data /// /// /// - /// + /// /// - protected async Task setRSV(string rKey, string rVal, int cacheMult) + protected async Task setRSV(string rKey, string rVal, TimeSpan cacheTS) { - bool fatto = false; - var redisDataList = Encoding.UTF8.GetBytes(rVal); - await distributedCache.SetAsync(rKey, redisDataList, cacheOpt(cacheMult)); - fatto = true; + bool fatto = await redisDb.StringSetAsync(rKey, rVal, cacheTS); return fatto; } @@ -392,29 +394,14 @@ namespace MP.Land.Data /// /// /// - /// + /// /// - protected async Task setRSV(string rKey, int rValInt, int cacheMult) + protected async Task setRSV(string rKey, int rValInt, TimeSpan cacheTS) { - bool fatto = false; - var redisDataList = Encoding.UTF8.GetBytes($"{rValInt}"); - await distributedCache.SetAsync(rKey, redisDataList, cacheOpt(cacheMult)); - fatto = true; + bool fatto = await setRSV(rkeyAppInfo, $"{rValInt}", cacheTS); return fatto; } - /// - /// Registra in cache chiave se non fosse già in elenco - /// - /// - protected void trackCache(string newKey) - { - if (!cachedDataList.Contains(newKey)) - { - cachedDataList.Add(newKey); - } - } - #endregion Protected Methods #region Private Fields @@ -426,34 +413,25 @@ namespace MP.Land.Data /// private static string apiUrl = "https://liman.egalware.com/ELM.API/"; + private static JsonSerializerSettings? JSSettings; + /// /// Chiave redis x info della licenza /// private static string rkeyAppInfo = "LongCache:AppInfo"; - //private static string apiUrl = "https://localhost:44351/"; - private readonly IDistributedCache distributedCache; - /// - /// Elenco obj in cache + /// Oggetto per connessione a REDIS /// - private List cachedDataList = new List(); + private IConnectionMultiplexer redisConn; + //ISubscriber sub = redis.GetSubscriber(); /// - /// Fattorte conversione cache sliding --> 1 h + /// Oggetto DB redis da impiegare x chiamate R/W /// - private int cacheFact = 12; + private IDatabase redisDb = null!; - /// - /// Durata assoluta massima della cache IN SECONDI - /// - private int chAbsExp = 60 * 5; - - /// - /// Durata della cache IN SECONDI in modalità inattiva (non acceduta) prima di venire - /// rimossa NON estende oltre il tempo massimo di validità della cache (chAbsExp) - /// - private int chSliExp = 60 * 1; + private Random rnd = new Random(); #endregion Private Fields @@ -465,18 +443,6 @@ namespace MP.Land.Data #region Private Methods - /// - /// Opzioni cache con moltiplicatore durata risp durata base (1/5 minuti) - /// - /// - /// - private DistributedCacheEntryOptions cacheOpt(int multFact) - { - var numSecAbsExp = chAbsExp * multFact; - var numSecSliExp = chSliExp * multFact; - return new DistributedCacheEntryOptions().SetAbsoluteExpiration(DateTime.Now.AddSeconds(numSecAbsExp)).SetSlidingExpiration(TimeSpan.FromSeconds(numSecSliExp)); - } - /// /// Elenco attivazioni attuali /// diff --git a/MP.Land/MP.Land.csproj b/MP.Land/MP.Land.csproj index 2c47ece8..b6a88f90 100644 --- a/MP.Land/MP.Land.csproj +++ b/MP.Land/MP.Land.csproj @@ -3,7 +3,7 @@ net6.0 MP.Land - 6.16.2407.3117 + 6.16.2409.0319 @@ -43,19 +43,19 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - + + + + diff --git a/MP.Land/NLog.config b/MP.Land/NLog.config deleted file mode 100644 index bd414080..00000000 --- a/MP.Land/NLog.config +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/MP.Land/Pages/About.razor b/MP.Land/Pages/About.razor index 61755d61..ffa93c15 100644 --- a/MP.Land/Pages/About.razor +++ b/MP.Land/Pages/About.razor @@ -84,7 +84,7 @@
    Key
    -
    +
    diff --git a/MP.Land/Pages/RefreshData.razor b/MP.Land/Pages/RefreshData.razor index d38688b9..60872fe4 100644 --- a/MP.Land/Pages/RefreshData.razor +++ b/MP.Land/Pages/RefreshData.razor @@ -20,8 +20,8 @@ await Task.Delay(100); LicServ.AKVList = new List(); await Task.Delay(100); - await DataService.ResetCache(); - await Task.Delay(100); + await DataService.FlushRedisCache(); + await Task.Delay(200); // redireziono NavManager.NavigateTo(""); diff --git a/MP.Land/Pages/Unauthorized.razor b/MP.Land/Pages/Unauthorized.razor new file mode 100644 index 00000000..67fad157 --- /dev/null +++ b/MP.Land/Pages/Unauthorized.razor @@ -0,0 +1,16 @@ +@page "/Unauthorized" + +
    +
    + Accesso Negato +
    +
    +
    + +
    +
    + +
    + diff --git a/MP.Land/Pages/Unauthorized.razor.css b/MP.Land/Pages/Unauthorized.razor.css new file mode 100644 index 00000000..d48f9705 --- /dev/null +++ b/MP.Land/Pages/Unauthorized.razor.css @@ -0,0 +1,81 @@ +.textMain { + font-size: 4rem; + -webkit-animation: glow 9s ease-in-out infinite alternate; + -moz-animation: glow 9s ease-in-out infinite alternate; + animation: glow 9s ease-in-out infinite alternate; +} +@-webkit-keyframes glow { + 0% { + text-shadow: 0 0 0px #000; + } + 90%, + 100% { + text-shadow: 0 0 10px #fff, 0 0 20px #0073e6; + } + 95% { + text-shadow: 0 0 15px #fff, 0 0 20px #4da6ff, 0 0 30px #4da6ff; + } +} +@media (max-width: 600px) { + .textMain { + font-size: 2rem; + } +} +@media (max-width: 992px) { + .textMain { + font-size: 3rem; + } +} +.backImage { + background-image: url('img/darkthree02.jpg'); + background-repeat: no-repeat; + animation: zoom-bg 4s ease-in-out infinite; +} +@keyframes zoom-bg { + 0%, + 80% { + background-size: 100% 100%; + filter: brightness(80%); + } + 90% { + background-size: 500% 500%; + background-position: 50% 50%; + filter: brightness(120%); + } + 100% { + background-size: 100% 100%; + filter: brightness(80%); + } +} +.frontImage { + padding: 0rem; + background: -webkit-linear-gradient(135deg, #000 30%, #D8951C 45%, #FAF2A2 50%, #C8850C 55%, #000 70%); + background-size: 250% 250%; + animation: gradient-bg 6s ease-in-out infinite; +} +@keyframes gradient-bg { + 0% { + background-position: 0% 50%; + filter: brightness(90%); + box-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #0ff, 0 0 40px #0ff, 0 0 50px #0073e6, 0 0 60px #0073e6, 0 0 70px #0073e6; + } + 40% { + filter: brightness(105%); + box-shadow: 0 0 40px #fff, 0 0 50px #4da6ff, 0 0 60px #4da6ff, 0 0 70px #4da6ff, 0 0 80px #4da6ff, 0 0 90px #4da6ff, 0 0 100px #4da6ff; + } + 80% { + background-position: 0% 50%; + filter: brightness(90%); + box-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #0ff, 0 0 40px #0ff, 0 0 50px #0073e6, 0 0 60px #0073e6, 0 0 70px #0073e6; + } + 92% { + background-position: 100% 50%; + filter: brightness(110%); + box-shadow: 0 0 0px #fff; + } + 100% { + background-position: 0% 50%; + filter: brightness(90%); + box-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #0ff, 0 0 40px #0ff, 0 0 50px #0073e6, 0 0 60px #0073e6, 0 0 70px #0073e6; + } +} \ No newline at end of file diff --git a/MP.Land/Pages/Unauthorized.razor.less b/MP.Land/Pages/Unauthorized.razor.less new file mode 100644 index 00000000..9fdbcd36 --- /dev/null +++ b/MP.Land/Pages/Unauthorized.razor.less @@ -0,0 +1,96 @@ +@timeGlow: 9s; + +.textMain { + font-size: 4rem; + -webkit-animation: glow @timeGlow ease-in-out infinite alternate; + -moz-animation: glow @timeGlow ease-in-out infinite alternate; + animation: glow @timeGlow ease-in-out infinite alternate; +} + +@-webkit-keyframes glow { + 0% { + text-shadow: 0 0 0px #000; + } + + 90%, 100% { + text-shadow: 0 0 10px #fff, 0 0 20px #0073e6; + } + + 95% { + text-shadow: 0 0 15px #fff, 0 0 20px #4da6ff, 0 0 30px #4da6ff; + } +} + +@media (max-width: 600px) { + .textMain { + font-size: 2rem; + } +} +@media (max-width: 992px) { + .textMain { + font-size: 3rem; + } +} + + +.backImage { + background-image: url('img/darkthree02.jpg'); + background-repeat: no-repeat; + animation: zoom-bg 4s ease-in-out infinite; +} + +@keyframes zoom-bg { + 0%, 80% { + background-size: 100% 100%; + filter: brightness(80%); + } + + 90% { + background-size: 500% 500%; + background-position: 50% 50%; + filter: brightness(120%); + } + + 100% { + background-size: 100% 100%; + filter: brightness(80%); + } +} + +.frontImage { + padding: 0rem; + background: -webkit-linear-gradient(135deg, #000 30%, #D8951C 45%, #FAF2A2 50%, #C8850C 55%, #000 70%); + background-size: 250% 250%; + animation: gradient-bg 6s ease-in-out infinite; +} + +@keyframes gradient-bg { + 0% { + background-position: 0% 50%; + filter: brightness(90%); + box-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #0ff, 0 0 40px #0ff, 0 0 50px #0073e6, 0 0 60px #0073e6, 0 0 70px #0073e6; + } + + 40% { + filter: brightness(105%); + box-shadow: 0 0 40px #fff, 0 0 50px #4da6ff, 0 0 60px #4da6ff, 0 0 70px #4da6ff, 0 0 80px #4da6ff, 0 0 90px #4da6ff, 0 0 100px #4da6ff; + } + + 80% { + background-position: 0% 50%; + filter: brightness(90%); + box-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #0ff, 0 0 40px #0ff, 0 0 50px #0073e6, 0 0 60px #0073e6, 0 0 70px #0073e6; + } + + 92% { + background-position: 100% 50%; + filter: brightness(110%); + box-shadow: 0 0 0px #fff; + } + + 100% { + background-position: 0% 50%; + filter: brightness(90%); + box-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #0ff, 0 0 40px #0ff, 0 0 50px #0073e6, 0 0 60px #0073e6, 0 0 70px #0073e6; + } +} diff --git a/MP.Land/Pages/Unauthorized.razor.min.css b/MP.Land/Pages/Unauthorized.razor.min.css new file mode 100644 index 00000000..7e3d8abe --- /dev/null +++ b/MP.Land/Pages/Unauthorized.razor.min.css @@ -0,0 +1 @@ +.textMain{font-size:4rem;-webkit-animation:glow 9s ease-in-out infinite alternate;-moz-animation:glow 9s ease-in-out infinite alternate;animation:glow 9s ease-in-out infinite alternate;}@-webkit-keyframes glow{0%{text-shadow:0 0 0 #000;}90%,100%{text-shadow:0 0 10px #fff,0 0 20px #0073e6;}95%{text-shadow:0 0 15px #fff,0 0 20px #4da6ff,0 0 30px #4da6ff;}}@media(max-width:600px){.textMain{font-size:2rem;}}@media(max-width:992px){.textMain{font-size:3rem;}}.backImage{background-image:url('img/darkthree02.jpg');background-repeat:no-repeat;animation:zoom-bg 4s ease-in-out infinite;}@keyframes zoom-bg{0%,80%{background-size:100% 100%;filter:brightness(80%);}90%{background-size:500% 500%;background-position:50% 50%;filter:brightness(120%);}100%{background-size:100% 100%;filter:brightness(80%);}}.frontImage{padding:0;background:-webkit-linear-gradient(135deg,#000 30%,#d8951c 45%,#faf2a2 50%,#c8850c 55%,#000 70%);background-size:250% 250%;animation:gradient-bg 6s ease-in-out infinite;}@keyframes gradient-bg{0%{background-position:0% 50%;filter:brightness(90%);box-shadow:0 0 10px #fff,0 0 20px #fff,0 0 30px #0ff,0 0 40px #0ff,0 0 50px #0073e6,0 0 60px #0073e6,0 0 70px #0073e6;}40%{filter:brightness(105%);box-shadow:0 0 40px #fff,0 0 50px #4da6ff,0 0 60px #4da6ff,0 0 70px #4da6ff,0 0 80px #4da6ff,0 0 90px #4da6ff,0 0 100px #4da6ff;}80%{background-position:0% 50%;filter:brightness(90%);box-shadow:0 0 10px #fff,0 0 20px #fff,0 0 30px #0ff,0 0 40px #0ff,0 0 50px #0073e6,0 0 60px #0073e6,0 0 70px #0073e6;}92%{background-position:100% 50%;filter:brightness(110%);box-shadow:0 0 0 #fff;}100%{background-position:0% 50%;filter:brightness(90%);box-shadow:0 0 10px #fff,0 0 20px #fff,0 0 30px #0ff,0 0 40px #0ff,0 0 50px #0073e6,0 0 60px #0073e6,0 0 70px #0073e6;}} \ No newline at end of file diff --git a/MP.Land/Program.cs b/MP.Land/Program.cs index 19472dd2..6adef8ec 100644 --- a/MP.Land/Program.cs +++ b/MP.Land/Program.cs @@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; +using NLog; using NLog.Web; using System; using System.Collections.Generic; @@ -30,9 +31,9 @@ namespace MP.Land public static void Main(string[] args) { // inclusione NLog: - // https://github.com/NLog/NLog/wiki/Getting-started-with-ASP.NET-Core-5 - // https://codewithmukesh.com/blog/logging-with-nlog-in-aspnet-core/ - var logger = NLog.Web.NLogBuilder.ConfigureNLog("NLog.config").GetCurrentClassLogger(); + var logger = LogManager.Setup() + .LoadConfigurationFromAppSettings() + .GetCurrentClassLogger(); try { logger.Info("MP.Land Application Starting Up"); diff --git a/MP.Land/Resources/ChangeLog.html b/MP.Land/Resources/ChangeLog.html index 68770304..4c7a6cea 100644 --- a/MP.Land/Resources/ChangeLog.html +++ b/MP.Land/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo Tablet MAPO - DotNet6 -

    Versione: 6.16.2407.3117

    +

    Versione: 6.16.2409.0319


    Note di rilascio:
      diff --git a/MP.Land/Resources/VersNum.txt b/MP.Land/Resources/VersNum.txt index db65b563..efc29a77 100644 --- a/MP.Land/Resources/VersNum.txt +++ b/MP.Land/Resources/VersNum.txt @@ -1 +1 @@ -6.16.2407.3117 +6.16.2409.0319 diff --git a/MP.Land/Resources/manifest.xml b/MP.Land/Resources/manifest.xml index f294da22..d1c57c73 100644 --- a/MP.Land/Resources/manifest.xml +++ b/MP.Land/Resources/manifest.xml @@ -1,6 +1,6 @@ - 6.16.2407.3117 + 6.16.2409.0319 https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/MP.Land.zip https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/ChangeLog.html false diff --git a/MP.Land/Shared/MainLayout.razor.cs b/MP.Land/Shared/MainLayout.razor.cs index 0ba4bfd0..058d26af 100644 --- a/MP.Land/Shared/MainLayout.razor.cs +++ b/MP.Land/Shared/MainLayout.razor.cs @@ -70,7 +70,6 @@ namespace MP.Land.Shared protected bool annualAuthOk { get; set; } = false; - private List ListRecords; #endregion Private Properties } diff --git a/MP.Land/Shared/NavMenu.razor b/MP.Land/Shared/NavMenu.razor index 613c30f2..547e2abb 100644 --- a/MP.Land/Shared/NavMenu.razor +++ b/MP.Land/Shared/NavMenu.razor @@ -9,56 +9,56 @@
      -@code { - private bool collapseNavMenu = true; - - private string NavMenuCssClass => collapseNavMenu ? "collapse" : null; - - private void ToggleNavMenu() - { - collapseNavMenu = !collapseNavMenu; - } -} \ No newline at end of file diff --git a/MP.Land/Shared/NavMenu.razor.cs b/MP.Land/Shared/NavMenu.razor.cs new file mode 100644 index 00000000..30eb547b --- /dev/null +++ b/MP.Land/Shared/NavMenu.razor.cs @@ -0,0 +1,149 @@ +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Authorization; +using Microsoft.AspNetCore.Mvc.RazorPages; +using Microsoft.Extensions.Configuration; +using MP.AppAuth.Models; +using MP.Land.Data; +using System.Collections.Generic; +using System.Configuration; +using System.Linq; +using System.Threading.Tasks; + +namespace MP.Land.Shared +{ + public partial class NavMenu + { + #region Protected Properties + + [Inject] + protected AuthenticationStateProvider AuthStateProvider { get; set; } = null!; + + [Inject] + protected AppAuthService DataService { get; set; } + + protected bool IsSuperAdmin + { + get => HasRight(AppAuthService.RoleSuperAdmin); + } + + [Inject] + protected NavigationManager NavManager { get; set; } = null!; + + protected string pageName + { + get + { + string pName = NavManager.ToBaseRelativePath(NavManager.Uri).ToLower(); + if (pName.Contains("?")) + { + pName = pName.Substring(0, pName.IndexOf("?")); + } + return pName; + } + } + + protected override async Task OnInitializedAsync() + { + await ReloadData(); + } + + protected List UserPerm { get; set; } = new List(); + protected List UserRight { get; set; } = new List(); + + #endregion Protected Properties + + #region Protected Methods + + protected bool HasRight(string codFunz) + { + bool answ = false; + if (UserRight != null && UserRight.Count > 0) + { + answ = UserRight + .Where(x => x.Funzione.Equals(codFunz, System.StringComparison.InvariantCultureIgnoreCase)) + .Count() > 0; + } + return answ; + } + + #endregion Protected Methods + + #region Private Fields + + private bool collapseNavMenu = true; + + private bool isLoading { get; set; } = false; + private string SafePages = ""; + private string userName = ""; + + #endregion Private Fields + + #region Private Properties + + [Inject] + private IConfiguration ConfMan { get; set; } = null!; + + private string NavMenuCssClass => collapseNavMenu ? "collapse" : null; + + #endregion Private Properties + + #region Private Methods + + private void checkAuth() + { + // verifico pagina tra i permessi, se manca --> rimando a pagina unauth... se contiene + // index --> salto + if (!pageName.Contains("index")) + { + bool isAuth = false; + if (UserPerm != null) + { + isAuth = UserPerm.Where(x => x.Url.ToLower() == pageName).Count() > 0; + bool pageIsSafe = SafePages.ToLower().Contains($"|{pageName.ToLower()}|"); + if (!pageIsSafe && !isAuth) + { + NavManager.NavigateTo("Unauthorized", true); + } + } + } + } + + private async Task ReloadData() + { + isLoading = true; + await Task.Delay(1); + // sistemo elenco pagine safe... + SafePages = ConfMan.GetValue("Application:SafePages").ToLower(); + var authState = await AuthStateProvider.GetAuthenticationStateAsync(); + var user = authState.User; + if (user.Identity != null && user.Identity.IsAuthenticated) + { + userName = $"{user.Identity.Name}"; + } + else + { + userName = "N.A."; + } + // carico diritti... + var domUser = userName.Split("\\"); + if (domUser.Length > 0) + { + string dominio = domUser[0]; + string uName = domUser[1]; + UserRight = await DataService.DirittiGetByUser(uName); + UserPerm = await DataService.PermessiGetByUser(uName); + } + checkAuth(); + await Task.Delay(1); + isLoading = false; + await Task.Delay(1); + } + + private void ToggleNavMenu() + { + collapseNavMenu = !collapseNavMenu; + } + + #endregion Private Methods + } +} \ No newline at end of file diff --git a/MP.Land/Startup.cs b/MP.Land/Startup.cs index 0fd913d8..50e8e855 100644 --- a/MP.Land/Startup.cs +++ b/MP.Land/Startup.cs @@ -11,8 +11,10 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using MP.Land.Data; +using StackExchange.Redis; using System; using System.Collections.Generic; +using System.Configuration; using System.Globalization; using System.Linq; using System.Threading.Tasks; @@ -116,13 +118,12 @@ namespace MP.Land options.FallbackPolicy = options.DefaultPolicy; }); + // REDIS setup + string connStringRedis = Configuration.GetConnectionString("Redis"); + string redisSrvAddr = connStringRedis.Substring(0, connStringRedis.IndexOf(":")); + // avvio oggetto shared x redis... + var redisMultiplexer = ConnectionMultiplexer.Connect(connStringRedis); - services.AddStackExchangeRedisCache(options => - { - //options.ConfigurationOptions = new StackExchange.Redis.ConfigurationOptions() { KeepAlive = 180, DefaultDatabase = 1, EndPoints = { { "localhost", 6379 } } }; - options.Configuration = Configuration["ConnectionStrings:Redis"]; - options.InstanceName = "MP:Land"; - }); services.AddLocalization(); @@ -135,6 +136,7 @@ namespace MP.Land services.AddScoped(); services.AddScoped(); + services.AddSingleton(redisMultiplexer); services.AddBlazoredLocalStorage(); services.AddBlazoredSessionStorage(); diff --git a/MP.Land/appsettings.Production.json b/MP.Land/appsettings.Production.json index 61a2b439..9958c471 100644 --- a/MP.Land/appsettings.Production.json +++ b/MP.Land/appsettings.Production.json @@ -14,6 +14,7 @@ "ConnectionStrings": { "DefaultConnection": "Server=SQL2016DEV;Database=MoonPro;Trusted_Connection=True;MultipleActiveResultSets=true", "MP.Land": "Server=SQL2016DEV;Database=MoonPro;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=MP.Land;", + "MP.Land.Auth": "Server=SQL2016DEV;Database=MoonPro_Anagrafica;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=MP.Land;", "Redis": "localhost:26379,serviceName=devel,defaultDatabase=5,keepAlive=180,asyncTimeout=5000" }, "ServerConf": { diff --git a/MP.Land/appsettings.json b/MP.Land/appsettings.json index 8276633e..4dcddcfe 100644 --- a/MP.Land/appsettings.json +++ b/MP.Land/appsettings.json @@ -6,6 +6,49 @@ "Microsoft.Hosting.Lifetime": "Information" } }, + "NLog": { + "variables": { + "baseFileDir": "${basedir}/logs/", + "layout": "${longdate} | ${uppercase:${level}} | ${logger:shortName=false} | ${message}" + }, + // "internalLogLevel": "Info", + // "internalLogFile": "c:\\temp\\internal-nlog.txt", + "extensions": [ + { "assembly": "NLog.Extensions.Logging" }, + { "assembly": "NLog.Web.AspNetCore" } + ], + "throwConfigExceptions": true, + "targets": { + "async": true, + "logfile": { + "type": "File", + "fileName": "${basedir}/logs/${shortdate}.log", + "archiveEvery": "Day", + "archiveFileName": "${basedir}/logs/old/${shortdate}_{#}.log", + "archiveNumbering": "DateAndSequence", + "archiveAboveSize": "1024000", + "archiveDateFormat": "HH", + "maxArchiveFiles": "60", + "maxArchiveDays": "30" + }, + "logconsole": { + "type": "ColoredConsole", + "layout": "${longdate} | ${uppercase:${level}} | ${logger:shortName=true} | ${message}" + } + }, + "rules": [ + { + "logger": "*", + "minLevel": "Trace", + "writeTo": "logconsole" + }, + { + "logger": "*", + "minLevel": "Info", + "writeTo": "logfile" + } + ] + }, "AllowedHosts": "*", "QrJumpPath": "MP/TAB/jumper?", "Environment": "Steam DEV", @@ -13,10 +56,16 @@ "ConnectionStrings": { "DefaultConnection": "Server=SQL2016DEV;Database=MoonPro;Trusted_Connection=True;MultipleActiveResultSets=true", "MP.Land": "Server=SQL2016DEV;Database=MoonPro;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=MP.Land;", + "MP.Land.Auth": "Server=SQL2016DEV;Database=MoonPro_Anagrafica;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=MP.Land;", //"MP.Land": "Server=SQL2016DEV;Database=MoonPro_ONE;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=MP.Land;", "Redis": "localhost:26379, serviceName=devel, defaultDatabase=1, keepAlive=180, connectTimeout=5000, syncTimeout=5000, asyncTimeout=5000, abortConnect=false, ssl=false, allowAdmin=true" }, + "Application": { + "SafePages": "||LAND|Home|Index|About|Help|Unauthorized|" + }, "ServerConf": { + "CodApp": "MP-LAND", + "Modulo": "MoonPro", "BaseUrl": "https://localhost:44309/", "downloadPath": "C:\\Steamware\\installers\\MP" } diff --git a/MP.Land/compilerconfig.json b/MP.Land/compilerconfig.json index 4d2d12c3..443f733b 100644 --- a/MP.Land/compilerconfig.json +++ b/MP.Land/compilerconfig.json @@ -6,5 +6,9 @@ { "outputFile": "wwwroot/css/site.css", "inputFile": "wwwroot/css/site.less" + }, + { + "outputFile": "Pages/Unauthorized.razor.css", + "inputFile": "Pages/Unauthorized.razor.less" } ] \ No newline at end of file diff --git a/MP.Land/compilerconfig.json.defaults b/MP.Land/compilerconfig.json.defaults new file mode 100644 index 00000000..41870cc5 --- /dev/null +++ b/MP.Land/compilerconfig.json.defaults @@ -0,0 +1,71 @@ +{ + "compilers": { + "less": { + "autoPrefix": "", + "cssComb": "none", + "ieCompat": true, + "math": null, + "strictMath": false, + "strictUnits": false, + "relativeUrls": true, + "rootPath": "", + "sourceMapRoot": "", + "sourceMapBasePath": "", + "sourceMap": false + }, + "sass": { + "autoPrefix": "", + "loadPaths": "", + "style": "expanded", + "relativeUrls": true, + "sourceMap": false + }, + "nodesass": { + "autoPrefix": "", + "includePath": "", + "indentType": "space", + "indentWidth": 2, + "outputStyle": "nested", + "precision": 5, + "relativeUrls": true, + "sourceMapRoot": "", + "lineFeed": "", + "sourceMap": false + }, + "stylus": { + "sourceMap": false + }, + "babel": { + "sourceMap": false + }, + "coffeescript": { + "bare": false, + "runtimeMode": "node", + "sourceMap": false + }, + "handlebars": { + "root": "", + "noBOM": false, + "name": "", + "namespace": "", + "knownHelpersOnly": false, + "forcePartial": false, + "knownHelpers": [], + "commonjs": "", + "amd": false, + "sourceMap": false + } + }, + "minifiers": { + "css": { + "enabled": true, + "termSemicolons": true, + "gzip": false + }, + "javascript": { + "enabled": true, + "termSemicolons": true, + "gzip": false + } + } +} \ No newline at end of file diff --git a/MP.Land/wwwroot/img/BMA.png b/MP.Land/wwwroot/img/BMA.png new file mode 100644 index 00000000..ceb3d8f8 Binary files /dev/null and b/MP.Land/wwwroot/img/BMA.png differ diff --git a/MP.Land/wwwroot/img/CaptainMarvel.jpg b/MP.Land/wwwroot/img/CaptainMarvel.jpg new file mode 100644 index 00000000..896f6bc9 Binary files /dev/null and b/MP.Land/wwwroot/img/CaptainMarvel.jpg differ diff --git a/MP.Land/wwwroot/img/DarkThree01.jpg b/MP.Land/wwwroot/img/DarkThree01.jpg new file mode 100644 index 00000000..6800fca1 Binary files /dev/null and b/MP.Land/wwwroot/img/DarkThree01.jpg differ diff --git a/MP.Land/wwwroot/img/DarkThree02.jpg b/MP.Land/wwwroot/img/DarkThree02.jpg new file mode 100644 index 00000000..b6e2c6bb Binary files /dev/null and b/MP.Land/wwwroot/img/DarkThree02.jpg differ diff --git a/MP.Land/wwwroot/img/DarkThree03.jpg b/MP.Land/wwwroot/img/DarkThree03.jpg new file mode 100644 index 00000000..9f83cb6d Binary files /dev/null and b/MP.Land/wwwroot/img/DarkThree03.jpg differ diff --git a/MP.Land/wwwroot/img/DarkThree04.jpg b/MP.Land/wwwroot/img/DarkThree04.jpg new file mode 100644 index 00000000..b4db8876 Binary files /dev/null and b/MP.Land/wwwroot/img/DarkThree04.jpg differ diff --git a/MP.Land/wwwroot/img/WonderWoman.jpg b/MP.Land/wwwroot/img/WonderWoman.jpg new file mode 100644 index 00000000..5e1721f1 Binary files /dev/null and b/MP.Land/wwwroot/img/WonderWoman.jpg differ diff --git a/MP.Mon/MP.Mon.csproj b/MP.Mon/MP.Mon.csproj index af49b3ea..297f0d66 100644 --- a/MP.Mon/MP.Mon.csproj +++ b/MP.Mon/MP.Mon.csproj @@ -4,7 +4,7 @@ net6.0 enable enable - 6.16.2405.2315 + 6.16.2409.408 @@ -36,10 +36,12 @@ - - + + + - + + diff --git a/MP.Mon/Pages/Index.razor.cs b/MP.Mon/Pages/Index.razor.cs index 09f5893a..82a49a45 100644 --- a/MP.Mon/Pages/Index.razor.cs +++ b/MP.Mon/Pages/Index.razor.cs @@ -7,6 +7,7 @@ using Newtonsoft.Json; using NLog; using System; using EgwCoreLib.Razor; +using EgwCoreLib.Razor.Data; namespace MP.Mon.Pages { diff --git a/MP.Mon/Program.cs b/MP.Mon/Program.cs index 05cc597e..0e629c94 100644 --- a/MP.Mon/Program.cs +++ b/MP.Mon/Program.cs @@ -2,6 +2,8 @@ using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Web; using MP.Data; using MP.Data.Services; +using NLog; +using NLog.Web; using StackExchange.Redis; var builder = WebApplication.CreateBuilder(args); @@ -14,15 +16,24 @@ var builder = WebApplication.CreateBuilder(args); * * */ + + +var logger = LogManager.Setup() + .LoadConfigurationFromAppSettings() + .GetCurrentClassLogger(); +logger.Info("Program.cs: startup"); + ConfigurationManager configuration = builder.Configuration; // REDIS setup +logger.Info("Setup REDIS"); string connStringRedis = configuration.GetConnectionString("Redis"); string redisSrvAddr = connStringRedis.Substring(0, connStringRedis.IndexOf(":")); // avvio oggetto shared x redis... var redisMultiplexer = ConnectionMultiplexer.Connect(connStringRedis); // Add services to the container. +logger.Info("Setup Services"); builder.Services.AddRazorPages(); builder.Services.AddServerSideBlazor(); builder.Services.AddSingleton(redisMultiplexer); @@ -47,4 +58,5 @@ app.UseRouting(); app.MapBlazorHub(); app.MapFallbackToPage("/_Host"); +logger.Info("Run App"); app.Run(); diff --git a/MP.Mon/Resources/ChangeLog.html b/MP.Mon/Resources/ChangeLog.html index 1b4d3524..6d28526c 100644 --- a/MP.Mon/Resources/ChangeLog.html +++ b/MP.Mon/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MON MAPO -

      Versione: 6.16.2405.2315

      +

      Versione: 6.16.2409.408


      Note di rilascio:
      • diff --git a/MP.Mon/Resources/VersNum.txt b/MP.Mon/Resources/VersNum.txt index 65bc5654..9fd70b9c 100644 --- a/MP.Mon/Resources/VersNum.txt +++ b/MP.Mon/Resources/VersNum.txt @@ -1 +1 @@ -6.16.2405.2315 +6.16.2409.408 diff --git a/MP.Mon/Resources/manifest.xml b/MP.Mon/Resources/manifest.xml index 7b903672..7deddf2a 100644 --- a/MP.Mon/Resources/manifest.xml +++ b/MP.Mon/Resources/manifest.xml @@ -1,6 +1,6 @@ - 6.16.2405.2315 + 6.16.2409.408 https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/MP.Mon.zip https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/ChangeLog.html false diff --git a/MP.Mon/appsettings.json b/MP.Mon/appsettings.json index 52783bef..c07811cc 100644 --- a/MP.Mon/appsettings.json +++ b/MP.Mon/appsettings.json @@ -5,6 +5,49 @@ "Microsoft.AspNetCore": "Warning" } }, + "NLog": { + "variables": { + "baseFileDir": "${basedir}/logs/", + "layout": "${longdate} | ${uppercase:${level}} | ${logger:shortName=false} | ${message}" + }, + // "internalLogLevel": "Info", + // "internalLogFile": "c:\\temp\\internal-nlog.txt", + "extensions": [ + { "assembly": "NLog.Extensions.Logging" }, + { "assembly": "NLog.Web.AspNetCore" } + ], + "throwConfigExceptions": true, + "targets": { + "async": true, + "logfile": { + "type": "File", + "fileName": "${basedir}/logs/${shortdate}.log", + "archiveEvery": "Day", + "archiveFileName": "${basedir}/logs/old/${shortdate}_{#}.log", + "archiveNumbering": "DateAndSequence", + "archiveAboveSize": "1024000", + "archiveDateFormat": "HH", + "maxArchiveFiles": "60", + "maxArchiveDays": "30" + }, + "logconsole": { + "type": "ColoredConsole", + "layout": "${longdate} | ${uppercase:${level}} | ${logger:shortName=true} | ${message}" + } + }, + "rules": [ + { + "logger": "*", + "minLevel": "Trace", + "writeTo": "logconsole" + }, + { + "logger": "*", + "minLevel": "Info", + "writeTo": "logfile" + } + ] + }, "AllowedHosts": "*", "CodApp": "MP.MON", "ConnectionStrings": { diff --git a/MP.Prog/Data/FileArchDataService.cs b/MP.Prog/Data/FileArchDataService.cs index 3839ea0d..4c0ac100 100644 --- a/MP.Prog/Data/FileArchDataService.cs +++ b/MP.Prog/Data/FileArchDataService.cs @@ -14,46 +14,12 @@ using System.Threading.Tasks; using System.Diagnostics; using MP.FileData.Controllers; using MP.FileData.DTO; +using StackExchange.Redis; 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; @@ -62,13 +28,15 @@ namespace MP.Prog.Data #region Public Constructors - public FileArchDataService(IConfiguration configuration, ILogger logger, IMemoryCache memoryCache, IDistributedCache distributedCache) + public FileArchDataService(IConfiguration configuration, ILogger logger, IConnectionMultiplexer redisConnMult) { _logger = logger; _configuration = configuration; - // conf cache - this.memoryCache = memoryCache; - this.distributedCache = distributedCache; + + // Conf cache + redisConn = redisConnMult; + redisDb = this.redisConn.GetDatabase(); + // conf DB string connStr = _configuration.GetConnectionString("MP.Prog"); if (string.IsNullOrEmpty(connStr)) @@ -84,60 +52,6 @@ namespace MP.Prog.Data #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() @@ -227,24 +141,12 @@ namespace MP.Prog.Data 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 + /// + /// Numero giorni x ricerca all'indietro da data corrente / 0 = nessun limite + /// /// public async Task updateAllArchive(int numDayPre, bool forceTag) { @@ -262,7 +164,9 @@ namespace MP.Prog.Data /// Aggiorna archivio di una amcchina scansionando path relativo /// /// Codice macchina - /// Numero giorni x ricerca all'indietro da data corrente / 0 = nessun limite + /// + /// 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 /// @@ -342,5 +246,109 @@ namespace MP.Prog.Data } #endregion Public Methods + + #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 Protected Fields + + protected static string connStringBBM = ""; + protected static string connStringFatt = ""; + + #endregion Protected Fields + + #region Private Fields + + private static IConfiguration _configuration; + + private static ILogger _logger; + + private static List ElencoMacchine = new List(); + + private static NLog.Logger Log = LogManager.GetCurrentClassLogger(); + + /// + /// Durata cache lunga IN SECONDI + /// + private int cacheTtlLong = 60 * 5; + + /// + /// Durata cache breve IN SECONDI + /// + private int cacheTtlShort = 60 * 1; + + /// + /// Oggetto per connessione a REDIS + /// + private IConnectionMultiplexer redisConn; + + //ISubscriber sub = redis.GetSubscriber(); + /// + /// Oggetto DB redis da impiegare x chiamate R/W + /// + private IDatabase redisDb = null!; + + private Random rnd = new Random(); + + #endregion Private Fields + + #region Private Properties + + /// + /// Durata cache lunga (+ perturbazione percentuale +/-10%) + /// + private TimeSpan FastCache + { + get => TimeSpan.FromSeconds(cacheTtlShort * rnd.Next(900, 1100) / 1000); + } + + /// + /// Durata cache lunga (+ perturbazione percentuale +/-10%) + /// + private TimeSpan LongCache + { + get => TimeSpan.FromSeconds(cacheTtlLong * rnd.Next(900, 1100) / 1000); + } + + /// + /// Durata cache lunga (+ perturbazione percentuale +/-10%) + /// + private TimeSpan UltraLongCache + { + get => TimeSpan.FromSeconds(cacheTtlLong * 10 * rnd.Next(900, 1100) / 1000); + } + + #endregion Private Properties } } \ No newline at end of file diff --git a/MP.Prog/MP.Prog.csproj b/MP.Prog/MP.Prog.csproj index 57016ff1..b4b1a161 100644 --- a/MP.Prog/MP.Prog.csproj +++ b/MP.Prog/MP.Prog.csproj @@ -3,7 +3,7 @@ net6.0 MP.Prog - 6.16.2402.1919 + 6.16.2409.0409 @@ -18,15 +18,11 @@ - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - + + + + + diff --git a/MP.Prog/NLog.config b/MP.Prog/NLog.config deleted file mode 100644 index b32ba10a..00000000 --- a/MP.Prog/NLog.config +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/MP.Prog/Program.cs b/MP.Prog/Program.cs index 514283f1..904ca0f8 100644 --- a/MP.Prog/Program.cs +++ b/MP.Prog/Program.cs @@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; +using NLog; using NLog.Web; using System; using System.Collections.Generic; @@ -30,9 +31,9 @@ namespace MP.Prog public static void Main(string[] args) { // inclusione NLog: - // https://github.com/NLog/NLog/wiki/Getting-started-with-ASP.NET-Core-5 - // https://codewithmukesh.com/blog/logging-with-nlog-in-aspnet-core/ - var logger = NLog.Web.NLogBuilder.ConfigureNLog("NLog.config").GetCurrentClassLogger(); + var logger = LogManager.Setup() + .LoadConfigurationFromAppSettings() + .GetCurrentClassLogger(); try { logger.Info("MP.Prog Application Starting Up"); diff --git a/MP.Prog/Resources/ChangeLog.html b/MP.Prog/Resources/ChangeLog.html index 744b45bd..5883b33b 100644 --- a/MP.Prog/Resources/ChangeLog.html +++ b/MP.Prog/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo gestione Programmi MAPO -

        Versione: 6.16.2402.1919

        +

        Versione: 6.16.2409.0409


        Note di rilascio:
          diff --git a/MP.Prog/Resources/VersNum.txt b/MP.Prog/Resources/VersNum.txt index dad8f7b3..5916d145 100644 --- a/MP.Prog/Resources/VersNum.txt +++ b/MP.Prog/Resources/VersNum.txt @@ -1 +1 @@ -6.16.2402.1919 +6.16.2409.0409 diff --git a/MP.Prog/Resources/manifest.xml b/MP.Prog/Resources/manifest.xml index aa988e2a..e880d563 100644 --- a/MP.Prog/Resources/manifest.xml +++ b/MP.Prog/Resources/manifest.xml @@ -1,6 +1,6 @@ - 6.16.2402.1919 + 6.16.2409.0409 https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/MP.Prog.zip https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/ChangeLog.html false diff --git a/MP.Prog/Startup.cs b/MP.Prog/Startup.cs index 88d0719c..c54dcc14 100644 --- a/MP.Prog/Startup.cs +++ b/MP.Prog/Startup.cs @@ -8,6 +8,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using MP.Prog.Data; +using StackExchange.Redis; using System; using System.Collections.Generic; using System.Globalization; @@ -116,12 +117,20 @@ namespace MP.Prog // options.ConnectionString = elmaConn; //}); +#if false services.AddStackExchangeRedisCache(options => - { - //options.Configuration = "localhost:6379"; - options.ConfigurationOptions = new StackExchange.Redis.ConfigurationOptions() { KeepAlive = 180, DefaultDatabase = 5, EndPoints = { { "localhost", 6379 } } }; - options.InstanceName = "MP:Prog"; - }); + { + //options.Configuration = "localhost:6379"; + options.ConfigurationOptions = new StackExchange.Redis.ConfigurationOptions() { KeepAlive = 180, DefaultDatabase = 5, EndPoints = { { "localhost", 6379 } } }; + options.InstanceName = "MP:Prog"; + }); +#endif + // REDIS setup + string connStringRedis = Configuration.GetConnectionString("Redis"); + string redisSrvAddr = connStringRedis.Substring(0, connStringRedis.IndexOf(":")); + // avvio oggetto shared x redis... + var redisMultiplexer = ConnectionMultiplexer.Connect(connStringRedis); + services.AddLocalization(); @@ -134,6 +143,7 @@ namespace MP.Prog //services.AddSingleton(); services.AddScoped(); services.AddScoped(); + services.AddSingleton(redisMultiplexer); } #endregion Public Methods diff --git a/MP.Prog/appsettings.json b/MP.Prog/appsettings.json index fed4f415..1f253868 100644 --- a/MP.Prog/appsettings.json +++ b/MP.Prog/appsettings.json @@ -1,18 +1,61 @@ { - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft": "Warning", - "Microsoft.Hosting.Lifetime": "Information" - } - }, - "AllowedHosts": "*", - "Tags": { - "DefaultSearch": "##" - }, - "ConnectionStrings": { - "DefaultConnection": "Server=SQL2016DEV;Database=MoonPro_PROG;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=MP.Prog;", - "MP.Prog": "Server=SQL2016DEV;Database=MoonPro_PROG;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=MP.Prog;", - "Redis": "localhost:26379,serviceName=devel,DefaultDatabase=5,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false" + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" } + }, + "NLog": { + "variables": { + "baseFileDir": "${basedir}/logs/", + "layout": "${longdate} | ${uppercase:${level}} | ${logger:shortName=false} | ${message}" + }, + // "internalLogLevel": "Info", + // "internalLogFile": "c:\\temp\\internal-nlog.txt", + "extensions": [ + { "assembly": "NLog.Extensions.Logging" }, + { "assembly": "NLog.Web.AspNetCore" } + ], + "throwConfigExceptions": true, + "targets": { + "async": true, + "logfile": { + "type": "File", + "fileName": "${basedir}/logs/${shortdate}.log", + "archiveEvery": "Day", + "archiveFileName": "${basedir}/logs/old/${shortdate}_{#}.log", + "archiveNumbering": "DateAndSequence", + "archiveAboveSize": "1024000", + "archiveDateFormat": "HH", + "maxArchiveFiles": "60", + "maxArchiveDays": "30" + }, + "logconsole": { + "type": "ColoredConsole", + "layout": "${longdate} | ${uppercase:${level}} | ${logger:shortName=true} | ${message}" + } + }, + "rules": [ + { + "logger": "*", + "minLevel": "Trace", + "writeTo": "logconsole" + }, + { + "logger": "*", + "minLevel": "Info", + "writeTo": "logfile" + } + ] + }, + "AllowedHosts": "*", + "Tags": { + "DefaultSearch": "##" + }, + "ConnectionStrings": { + "DefaultConnection": "Server=SQL2016DEV;Database=MoonPro_PROG;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=MP.Prog;", + "MP.Prog": "Server=SQL2016DEV;Database=MoonPro_PROG;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=MP.Prog;", + "Redis": "localhost:26379,serviceName=devel,DefaultDatabase=5,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false" + } } \ No newline at end of file diff --git a/MP.SPEC/Components/SelFilterXDL.razor.cs b/MP.SPEC/Components/SelFilterXDL.razor.cs index 039b0c0b..1d5b96a5 100644 --- a/MP.SPEC/Components/SelFilterXDL.razor.cs +++ b/MP.SPEC/Components/SelFilterXDL.razor.cs @@ -76,7 +76,7 @@ namespace MP.SPEC.Components protected async Task getReparto() { string keyStor = "reparto"; - string localReparto = await localStorage.GetItemAsync(keyStor); + string localReparto = await localStorage.GetItemAsync(keyStor) ?? ""; if (!string.IsNullOrEmpty(localReparto)) { selReparto = localReparto; diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 4745597d..8a971750 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -329,7 +329,7 @@ namespace MP.SPEC.Data // cerco in cache redis... string redKeyArtUsed = $"{Utils.redKeyArtUsed}:{codArticolo}"; string redKeyTabCheckArt = Utils.redKeyTabCheckArt; - string rawData = redisDb.StringGet(redKeyArtUsed); + var rawData = redisDb.StringGet(redKeyArtUsed); if (!string.IsNullOrEmpty(rawData)) { bool.TryParse(rawData, out answ); @@ -340,11 +340,11 @@ namespace MP.SPEC.Data try { // cerco in cache se ci sia la tabella con gli articoli impiegati... - string rawTable = redisDb.StringGet(redKeyTabCheckArt); + var rawTable = redisDb.StringGet(redKeyTabCheckArt); List? artList = new List(); if (!string.IsNullOrEmpty(rawTable)) { - artList = JsonConvert.DeserializeObject>(rawTable); + artList = JsonConvert.DeserializeObject>($"{rawTable}"); } // rileggo... if (artList == null || artList.Count == 0) diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 55df5528..f23b909c 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 6.16.2404.3016 + 6.16.2409.407 1800a78a-6ff1-40f9-b490-87fb8bfc1394 @@ -38,12 +38,14 @@ - + - - + + + + diff --git a/MP.SPEC/NLog.config b/MP.SPEC/NLog.config deleted file mode 100644 index 3e4185f4..00000000 --- a/MP.SPEC/NLog.config +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/MP.SPEC/Pages/ODL.razor.cs b/MP.SPEC/Pages/ODL.razor.cs index 5c291bfc..9c6414e0 100644 --- a/MP.SPEC/Pages/ODL.razor.cs +++ b/MP.SPEC/Pages/ODL.razor.cs @@ -90,7 +90,7 @@ namespace MP.SPEC.Pages protected async Task getReparto() { string keyStor = "reparto"; - string localReparto = await localStorage.GetItemAsync(keyStor); + string localReparto = await localStorage.GetItemAsync(keyStor)??""; if (!string.IsNullOrEmpty(localReparto)) { selReparto = localReparto; diff --git a/MP.SPEC/Pages/PODL.razor.cs b/MP.SPEC/Pages/PODL.razor.cs index a9b0f7b9..689c44f7 100644 --- a/MP.SPEC/Pages/PODL.razor.cs +++ b/MP.SPEC/Pages/PODL.razor.cs @@ -90,7 +90,7 @@ namespace MP.SPEC.Pages protected async Task getReparto() { string keyStor = "reparto"; - string localReparto = await localStorage.GetItemAsync(keyStor); + string localReparto = await localStorage.GetItemAsync(keyStor) ?? ""; if (!string.IsNullOrEmpty(localReparto)) { selReparto = localReparto; diff --git a/MP.SPEC/Program.cs b/MP.SPEC/Program.cs index a8e143df..af583595 100644 --- a/MP.SPEC/Program.cs +++ b/MP.SPEC/Program.cs @@ -6,6 +6,8 @@ using Microsoft.AspNetCore.Components.Web; using MP.SPEC.Components; using MP.SPEC.Data; using MP.SPEC.Services; +using NLog; +using NLog.Web; using StackExchange.Redis; var builder = WebApplication.CreateBuilder(args); @@ -18,15 +20,26 @@ var builder = WebApplication.CreateBuilder(args); * * */ + +var logger = LogManager.Setup() + .LoadConfigurationFromAppSettings() + .GetCurrentClassLogger(); +logger.Info("Program.cs: startup"); + ConfigurationManager configuration = builder.Configuration; + // REDIS setup +logger.Info("Setup REDIS"); string connStringRedis = configuration.GetConnectionString("Redis"); //string connStringRedis = configuration.GetConnectionString("RedisAdmin"); string redisSrvAddr = connStringRedis.Substring(0, connStringRedis.IndexOf(":")); // avvio oggetto shared x redis... var redisMultiplexer = ConnectionMultiplexer.Connect(connStringRedis); + + // Add services to the container. +logger.Info("Setup Auth"); builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme) .AddNegotiate(); @@ -47,7 +60,10 @@ builder.Services.AddBlazoredSessionStorage(); builder.Services.AddHttpClient(); builder.Services.AddSingleton(); +logger.Info("Aggiunti services"); + var app = builder.Build(); +logger.Info("Build App"); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) @@ -75,4 +91,6 @@ app.UseEndpoints(endpoints => //app.MapBlazorHub(); //app.MapFallbackToPage("/_Host"); +logger.Info("Run App"); + app.Run(); diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index e18988bd..f69bd808 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

          Versione: 6.16.2404.3016

          +

          Versione: 6.16.2409.407


          Note di rilascio:
          • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 2ac7ed17..6d551475 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -6.16.2404.3016 +6.16.2409.407 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index 55ccba52..eb62f5bf 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 6.16.2404.3016 + 6.16.2409.407 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false diff --git a/MP.SPEC/appsettings.json b/MP.SPEC/appsettings.json index 45897fa7..9e519fb5 100644 --- a/MP.SPEC/appsettings.json +++ b/MP.SPEC/appsettings.json @@ -5,6 +5,49 @@ "Microsoft.AspNetCore": "Warning" } }, + "NLog": { + "variables": { + "baseFileDir": "${basedir}/logs/", + "layout": "${longdate} | ${uppercase:${level}} | ${logger:shortName=false} | ${message}" + }, + // "internalLogLevel": "Info", + // "internalLogFile": "c:\\temp\\internal-nlog.txt", + "extensions": [ + { "assembly": "NLog.Extensions.Logging" }, + { "assembly": "NLog.Web.AspNetCore" } + ], + "throwConfigExceptions": true, + "targets": { + "async": true, + "logfile": { + "type": "File", + "fileName": "${basedir}/logs/${shortdate}.log", + "archiveEvery": "Day", + "archiveFileName": "${basedir}/logs/old/${shortdate}_{#}.log", + "archiveNumbering": "DateAndSequence", + "archiveAboveSize": "1024000", + "archiveDateFormat": "HH", + "maxArchiveFiles": "60", + "maxArchiveDays": "30" + }, + "logconsole": { + "type": "ColoredConsole", + "layout": "${longdate} | ${uppercase:${level}} | ${logger:shortName=true} | ${message}" + } + }, + "rules": [ + { + "logger": "*", + "minLevel": "Trace", + "writeTo": "logconsole" + }, + { + "logger": "*", + "minLevel": "Info", + "writeTo": "logfile" + } + ] + }, "AllowedHosts": "*", "CodApp": "MP.SPEC", "ConnectionStrings": { diff --git a/MP.Stats/MP.Stats.csproj b/MP.Stats/MP.Stats.csproj index f67a0e50..f45e6145 100644 --- a/MP.Stats/MP.Stats.csproj +++ b/MP.Stats/MP.Stats.csproj @@ -4,8 +4,8 @@ net6.0 MP.Stats 826e877c-ba70-4253-84cb-d0b1cafd4440 - 6.16.2404.1616 - 6.16.2404.1616 + 6.16.2409.0409 + 6.16.2409.0409 true $(NoWarn);1591 @@ -188,13 +188,15 @@ - + + - - + + + diff --git a/MP.Stats/NLog.config b/MP.Stats/NLog.config deleted file mode 100644 index bd414080..00000000 --- a/MP.Stats/NLog.config +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/MP.Stats/Program.cs b/MP.Stats/Program.cs index cf9c5b1a..5d5f9eab 100644 --- a/MP.Stats/Program.cs +++ b/MP.Stats/Program.cs @@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; +using NLog; using NLog.Web; using System; using System.Collections.Generic; @@ -23,7 +24,7 @@ namespace MP.Stats .ConfigureLogging(logging => { logging.ClearProviders(); - logging.SetMinimumLevel(LogLevel.Information); + logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Information); //logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace); }) .UseNLog(); @@ -31,9 +32,9 @@ namespace MP.Stats public static void Main(string[] args) { // inclusione NLog: - // https://github.com/NLog/NLog/wiki/Getting-started-with-ASP.NET-Core-5 - // https://codewithmukesh.com/blog/logging-with-nlog-in-aspnet-core/ - var logger = NLog.Web.NLogBuilder.ConfigureNLog("NLog.config").GetCurrentClassLogger(); + var logger = LogManager.Setup() + .LoadConfigurationFromAppSettings() + .GetCurrentClassLogger(); try { logger.Info("MP.STATS Application Starting Up"); diff --git a/MP.Stats/Resources/ChangeLog.html b/MP.Stats/Resources/ChangeLog.html index e7ccfa0d..e916b4f3 100644 --- a/MP.Stats/Resources/ChangeLog.html +++ b/MP.Stats/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo statistiche MAPO -

            Versione: 6.16.2404.1616

            +

            Versione: 6.16.2409.0409


            Note di rilascio:
              diff --git a/MP.Stats/Resources/VersNum.txt b/MP.Stats/Resources/VersNum.txt index a3d398a6..5916d145 100644 --- a/MP.Stats/Resources/VersNum.txt +++ b/MP.Stats/Resources/VersNum.txt @@ -1 +1 @@ -6.16.2404.1616 +6.16.2409.0409 diff --git a/MP.Stats/Resources/manifest.xml b/MP.Stats/Resources/manifest.xml index cd0ba20d..ffde1027 100644 --- a/MP.Stats/Resources/manifest.xml +++ b/MP.Stats/Resources/manifest.xml @@ -1,6 +1,6 @@ - 6.16.2404.1616 + 6.16.2409.0409 https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/MP.Stats.zip https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/ChangeLog.html false diff --git a/MP.Stats/appsettings.json b/MP.Stats/appsettings.json index 6e1fcc91..b12244ca 100644 --- a/MP.Stats/appsettings.json +++ b/MP.Stats/appsettings.json @@ -1,16 +1,59 @@ { - "Logging": { - "LogLevel": { - "Default": "Trace", - "Microsoft": "Warning", - "Microsoft.Hosting.Lifetime": "Information" - } + "Logging": { + "LogLevel": { + "Default": "Trace", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "AllowedHosts": "*", + "NLog": { + "variables": { + "baseFileDir": "${basedir}/logs/", + "layout": "${longdate} | ${uppercase:${level}} | ${logger:shortName=false} | ${message}" }, - "AllowedHosts": "*", + // "internalLogLevel": "Info", + // "internalLogFile": "c:\\temp\\internal-nlog.txt", + "extensions": [ + { "assembly": "NLog.Extensions.Logging" }, + { "assembly": "NLog.Web.AspNetCore" } + ], + "throwConfigExceptions": true, + "targets": { + "async": true, + "logfile": { + "type": "File", + "fileName": "${basedir}/logs/${shortdate}.log", + "archiveEvery": "Day", + "archiveFileName": "${basedir}/logs/old/${shortdate}_{#}.log", + "archiveNumbering": "DateAndSequence", + "archiveAboveSize": "1024000", + "archiveDateFormat": "HH", + "maxArchiveFiles": "60", + "maxArchiveDays": "30" + }, + "logconsole": { + "type": "ColoredConsole", + "layout": "${longdate} | ${uppercase:${level}} | ${logger:shortName=true} | ${message}" + } + }, + "rules": [ + { + "logger": "*", + "minLevel": "Trace", + "writeTo": "logconsole" + }, + { + "logger": "*", + "minLevel": "Info", + "writeTo": "logfile" + } + ] + }, "ConnectionStrings": { "Redis": "localhost:26379,serviceName=devel,DefaultDatabase=5,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false,allowAdmin=true", "DefaultConnection": "Server=SQL2016DEV;Database=MoonPro_STATS;Trusted_Connection=True;MultipleActiveResultSets=true", "MP.Stats": "Server=SQL2016DEV;Database=MoonPro_STATS;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=MP.STATS;" }, - "FormatDur": "HH:mm.ss.ff" + "FormatDur": "HH:mm.ss.ff" } \ No newline at end of file