diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3fffdd88..88ebaaa0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -285,6 +285,24 @@ IOC:build: script: - dotnet build $env:APP_NAME/$env:APP_NAME.csproj +RIOC:build: + stage: build + tags: + - win + variables: + APP_NAME: MP.RIOC + SOL_NAME: MP-RIOC + rules: + - if: $CI_COMMIT_BRANCH == 'develop' + - if: $CI_COMMIT_BRANCH == 'master' + - if: $CI_COMMIT_BRANCH =~ /^feature\/IOC.+/ + when: always + before_script: + - *nuget-fix + - dotnet restore "$env:SOL_NAME.sln" + script: + - dotnet build $env:APP_NAME/$env:APP_NAME.csproj + TAB3:build: stage: build tags: @@ -350,8 +368,6 @@ LAND:SDK:deploy: - '& "$env:NUGET_PATH" setapikey $NUGET_API_KEY -source http://nexus.steamware.net/repository/nuget-hosted' - '& "$env:NUGET_PATH" push *$env:NUM_DEB.nupkg -Source http://nexus.steamware.net/repository/nuget-hosted' - - PROG:IIS01:deploy: stage: deploy tags: @@ -485,6 +501,25 @@ IOC:IIS01:deploy: - dotnet build $env:APP_NAME/$env:APP_NAME.csproj - dotnet publish -p:PublishProfile=IIS01.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=$IIS_PWD -p:AllowUntrustedCertificate=true -p:verbosity=quiet $env:APP_NAME/$env:APP_NAME.csproj +RIOC:IIS01:deploy: + stage: deploy + tags: + - win + variables: + APP_NAME: MP.RIOC + SOL_NAME: MP-RIOC + before_script: + - *nuget-fix + - dotnet restore "$env:SOL_NAME.sln" + rules: + - if: $CI_COMMIT_BRANCH == 'develop' + - if: $CI_COMMIT_BRANCH =~ /^feature\/IOC.+/ + when: always + needs: ["RIOC:build"] + script: + - dotnet build $env:APP_NAME/$env:APP_NAME.csproj + - dotnet publish -p:PublishProfile=IIS01.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=$IIS_PWD -p:AllowUntrustedCertificate=true -p:verbosity=quiet $env:APP_NAME/$env:APP_NAME.csproj + TAB3:IIS01:deploy: stage: deploy tags: @@ -654,6 +689,24 @@ IOC:IIS03:deploy: - dotnet publish -p:PublishProfile=IIS03.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=$IIS_PWD -p:AllowUntrustedCertificate=true -p:verbosity=quiet $env:APP_NAME/$env:APP_NAME.csproj - dotnet publish -p:PublishProfile=IIS04.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=$IIS_PWD -p:AllowUntrustedCertificate=true -p:verbosity=quiet $env:APP_NAME/$env:APP_NAME.csproj +RIOC:IIS03:deploy: + stage: deploy + tags: + - win + variables: + APP_NAME: MP.RIOC + SOL_NAME: MP-RIOC + before_script: + - *nuget-fix + - dotnet restore "$env:SOL_NAME.sln" + rules: + - if: $CI_COMMIT_BRANCH == 'master' + needs: ["RIOC:build"] + script: + - dotnet build $env:APP_NAME/$env:APP_NAME.csproj + - dotnet publish -p:PublishProfile=IIS03.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=$IIS_PWD -p:AllowUntrustedCertificate=true -p:verbosity=quiet $env:APP_NAME/$env:APP_NAME.csproj + - dotnet publish -p:PublishProfile=IIS04.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release -p:username=jenkins -p:Password=$IIS_PWD -p:AllowUntrustedCertificate=true -p:verbosity=quiet $env:APP_NAME/$env:APP_NAME.csproj + TAB3:IIS03:deploy: stage: deploy tags: @@ -873,6 +926,28 @@ IOC:installer: - *hashBuild - *nexusUpload +RIOC:installer: + stage: installer + tags: + - win + variables: + APP_NAME: MP.RIOC + SOL_NAME: MP-RIOC + NEXUS_PATH: MP-RIOC + before_script: + - *nuget-fix + - dotnet restore "$env:SOL_NAME.sln" + rules: + - if: $CI_COMMIT_BRANCH == 'master' + - if: $CI_COMMIT_BRANCH == 'develop' + needs: ["IOC:build"] + script: + - dotnet build $env:APP_NAME/$env:APP_NAME.csproj + - dotnet publish -p:PublishProfile=IISProfile.pubxml -p:RunCodeAnalysis=false -p:Configuration=Release $env:APP_NAME/$env:APP_NAME.csproj -o:publish -p:verbosity=quiet + # qui il deploy su nexus... + - *hashBuild + - *nexusUpload + # -------------------------------- # RELEASE (tags only + sdk) # -------------------------------- @@ -897,7 +972,6 @@ LAND:release: - dotnet build $env:APP_NAME/$env:APP_NAME.csproj - dotnet publish -c Release -o ./publish $env:APP_NAME/$env:APP_NAME.csproj -p:verbosity=quiet - LAND:SDK:release: stage: release tags: @@ -1067,3 +1141,24 @@ IOC:release: - dotnet build $env:APP_NAME/$env:APP_NAME.csproj - dotnet publish -c Release -o ./publish $env:APP_NAME/$env:APP_NAME.csproj -p:verbosity=quiet +RIOC:release: + stage: release + tags: + - win + variables: + APP_NAME: MP.RIOC + SOL_NAME: MP-RIOC + NEXUS_PATH: MP-RIOC + before_script: + - *nuget-fix + - dotnet restore "$env:SOL_NAME.sln" + rules: + - if: $CI_COMMIT_TAG + needs: ["IOC:build"] + artifacts: + paths: + - publish/ + script: + - dotnet build $env:APP_NAME/$env:APP_NAME.csproj + - dotnet publish -c Release -o ./publish $env:APP_NAME/$env:APP_NAME.csproj -p:verbosity=quiet + diff --git a/Directory.Packages.props b/Directory.Packages.props index de7d50f2..f5b8b499 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -7,8 +7,8 @@ - - + + @@ -28,15 +28,16 @@ - + - + + diff --git a/MP-RIOC/MP-RIOC.http b/MP-RIOC/MP-RIOC.http new file mode 100644 index 00000000..af71d627 --- /dev/null +++ b/MP-RIOC/MP-RIOC.http @@ -0,0 +1,6 @@ +@MP_RIOC_HostAddress = http://localhost:5290 + +GET {{MP_RIOC_HostAddress}}/weatherforecast/ +Accept: application/json + +### diff --git a/MP-RIOC/MP-RIOC.slnx b/MP-RIOC/MP-RIOC.slnx new file mode 100644 index 00000000..c16a708c --- /dev/null +++ b/MP-RIOC/MP-RIOC.slnx @@ -0,0 +1,5 @@ + + + + + diff --git a/MP-RIOC/MP.RIOC.csproj b/MP-RIOC/MP.RIOC.csproj new file mode 100644 index 00000000..62b5640a --- /dev/null +++ b/MP-RIOC/MP.RIOC.csproj @@ -0,0 +1,46 @@ + + + + net8.0 + enable + enable + MP.RIOC + 8.16.2605.812 + + + + + + + + + + + + + + + + + + + + + + + + + Always + + + Always + + + Always + + + + + + + diff --git a/MP-RIOC/Pages/Index.cshtml b/MP-RIOC/Pages/Index.cshtml new file mode 100644 index 00000000..6332b46a --- /dev/null +++ b/MP-RIOC/Pages/Index.cshtml @@ -0,0 +1,97 @@ + +@page +@using MP.RIOC.Services +@inject RouteStatsManager StatsManager +@{ + Layout = null; + var rawData = StatsManager.Snapshot(); + var metrics = rawData.OrderByDescending(x => x.Value.Count).Take(10); +} + + + + MP.RIOC Dashboard + + + +
+
+
+

MAPO MES

+
Live Dashboard
+
+
+

MP-RIOC

+

Router I/O Controller

+
+
+
+
+ Stato: ● Online +
+
+ Versione: @System.Reflection.Assembly.GetExecutingAssembly().GetName().Version +
+
+ + + + + + + + + + @foreach (var stat in metrics) + { + + + + + + } + @if (!metrics.Any()) + { + + + + } + +
Target | Metodo | IDChiamateLatenza Media
+ @if(stat.Key.StartsWith("IOC")) { NEW } + else { OLD } + @stat.Key + @stat.Value.Count@(stat.Value.AvgDuration)ms
Nessun dato raccolto al momento.
+ +
+ Ultimo aggiornamento: @DateTime.Now.ToString("HH:mm:ss") +

+
+ + \ No newline at end of file diff --git a/MP-RIOC/Pages/Index.cshtml.cs b/MP-RIOC/Pages/Index.cshtml.cs new file mode 100644 index 00000000..0d5b03ed --- /dev/null +++ b/MP-RIOC/Pages/Index.cshtml.cs @@ -0,0 +1,12 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace MP.RIOC.Pages +{ + public class IndexModel : PageModel + { + public void OnGet() + { + } + } +} diff --git a/MP-RIOC/Program.cs b/MP-RIOC/Program.cs new file mode 100644 index 00000000..31e3342f --- /dev/null +++ b/MP-RIOC/Program.cs @@ -0,0 +1,178 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Diagnostics; +using MP.Core.Conf; +using MP.Data; +using MP.RIOC.Services; +using NLog; +using NLog.Web; +using StackExchange.Redis; +using System.Diagnostics; +using System.Net; +using System.Reflection; + +var builder = WebApplication.CreateBuilder(args); + +// recupero env corrente +var env = builder.Environment; +var logger = LogManager.Setup() + .LoadConfigurationFromAppSettings() + .GetCurrentClassLogger(); + +var assemblyVersion = Assembly.GetExecutingAssembly().GetName().Version?.ToString(); +logger.Info($"MP.RIOC | Program.cs: startup | v.{assemblyVersion}"); +logger.Info($"Current ASPNETCORE_ENVIRONMENT: {env.EnvironmentName}"); + +// Config setup +ConfigurationManager configuration = builder.Configuration; +// REDIS setup +logger.Info("Config OK"); +string confRedis = configuration.GetConnectionString("Redis") ?? "localhost:6379"; +string redisSrvAddr = confRedis.Substring(0, confRedis.IndexOf(":")); +logger.Info("Setup REDIS OK"); + +builder.Services.Configure( + builder.Configuration.GetSection("RedisScripts")); +logger.Info("RedisScript Provider configured"); + +// Metodi principali x accesso dati +var connStr = builder.Configuration.GetConnectionString("MP.Data") + ?? throw new InvalidOperationException("ConnString 'MP.Data' mancante."); + +//builder.Services.AddMemoryCache(); + +builder.Services.AddDbContextFactory(options => + options.UseSqlServer(connStr) + .EnableSensitiveDataLogging(false) // true solo in Sviluppo + .ConfigureWarnings(w => w.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning))); + +// MP.Data DbContext for Stats repositories +string utilsConnString = builder.Configuration.GetConnectionString("MP.Utils") ?? "Server=localhost;Database=MoonPro_Utils; integrated security=True; MultipleActiveResultSets=True; App=MP.IOC;"; +builder.Services.AddDbContextFactory(options => + options.UseSqlServer(utilsConnString)); + +// MP.Data Services Utils - Statistiche DB +builder.Services.AddIocDataLayer(); + +// 1. Configurazione dell'invoker personalizzato (Risolve i tuoi errori) +var httpClientInvoker = new HttpMessageInvoker(new SocketsHttpHandler +{ + UseProxy = false, + AllowAutoRedirect = false, + AutomaticDecompression = DecompressionMethods.None, + UseCookies = false, + // Correzione per il tracing: usa il propagatore corrente di sistema + ActivityHeadersPropagator = DistributedContextPropagator.Current, + ConnectTimeout = TimeSpan.FromSeconds(30), + + // Gestione certificato (ignora errori per localhost/test) + SslOptions = new System.Net.Security.SslClientAuthenticationOptions + { + RemoteCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => true + } +}); + +builder.Services.AddSingleton(httpClientInvoker); +builder.Services.AddHttpForwarder(); + +// avvio oggetto shared x redis... +var redisMux = ConnectionMultiplexer.Connect(confRedis); +builder.Services.AddSingleton(redisMux); + +// Registrazione dei servizi custom +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); +builder.Services.AddHostedService(); +builder.Services.AddHostedService(); +builder.Services.AddSingleton(); + +logger.Info("Standard service configured"); + +// WeightProvider: Redis/Memory da config +var weightOnRedis = builder.Configuration.GetValue("ServerConf:RedisWeight", false); +if (weightOnRedis) +{ + builder.Services.AddSingleton(); +} +else +{ + builder.Services.AddSingleton(); +} +logger.Info($"Weight service configured | use Redis: {weightOnRedis}"); + +// RouteManager registration (singleton) +builder.Services.AddSingleton(); +logger.Info("Singleton Route Manager registered"); + +// aggiunta pagina razor di stato +builder.Services.AddRazorPages(); + +var app = builder.Build(); + +// Blocco per la migrazione automatica del DB Utils... +using (var scope = app.Services.CreateScope()) +{ + var services = scope.ServiceProvider; + try + { + var context = services.GetRequiredService(); + context.Database.Migrate(); + } + catch (Exception ex) + { + var migrateLogger = services.GetRequiredService>(); + migrateLogger.LogError(ex, "Si � verificato un errore durante l'aggiornamento del database."); + } +} + +// 1. Configurazione Base Path +string baseUrl = configuration.GetValue("ServerConf:BaseUrlIoc") ?? "/MP/RIOC"; +app.UsePathBase(baseUrl); + +// 2. Middleware statici (essenziali per CSS/JS delle pagine Razor) +app.UseStaticFiles(); + +// 3. Abilita il Routing (necessario per MapGet e MapRazorPages) +app.UseRouting(); + +// 4. Logging middleware +app.Use(async (ctx, next) => +{ + logger.Debug($"Incoming request PathBase='{ctx.Request.PathBase}' Path='{ctx.Request.Path}'"); + await next(); +}); + +// 5. Il cuore del Proxy (MapWhen è terminale per le richieste che lo soddisfano) +string routePath = configuration.GetValue("ServerConf:RoutePath") ?? "/api/IOB"; +string fullPath = $"{baseUrl}{routePath}".Replace("//", "/"); +logger.Info($"BaseUrl: {baseUrl}"); +app.MapWhen(ctx => ctx.Request.Path.StartsWithSegments(routePath, StringComparison.OrdinalIgnoreCase), + builder => + { + builder.Run(async ctx => + { + var routeManager = ctx.RequestServices.GetRequiredService(); + await routeManager.HandleAsync(ctx); + }); + }); + +// 6. Definizione degli Endpoints locali +app.MapRazorPages(); + +app.MapGet("/router-status", (RouteStatsManager stats) => Results.Ok(new +{ + Status = "Online", + Version = assemblyVersion, + Mode = weightOnRedis ? "Redis" : "InMemory", + Time = DateTime.Now, + Metrics = stats.Snapshot() +})); + +// 7. Fallback "intelligente" +// Invece di app.Run, usiamo MapFallback che viene eseguito SOLO se nessun altro endpoint o MapWhen ha risposto +app.MapFallback(async context => +{ + context.Response.StatusCode = 404; + await context.Response.WriteAsync("Router: Endpoint non trovato o non mappato."); +}); + +app.Run(); \ No newline at end of file diff --git a/MP-RIOC/Properties/PublishProfiles/IIS01.pubxml b/MP-RIOC/Properties/PublishProfiles/IIS01.pubxml new file mode 100644 index 00000000..9278d2ad --- /dev/null +++ b/MP-RIOC/Properties/PublishProfiles/IIS01.pubxml @@ -0,0 +1,32 @@ + + + + + MSDeploy + true + Release + Any CPU + https://iis01.egalware.com/MP/RIOC/ + false + b9188473-f4ae-4f9f-be2d-70edaace0db9 + false + https://iis01.egalware.com:8172/MsDeploy.axd + Default Web Site/MP/RIOC + + false + WMSVC + true + true + jenkins + <_SavePWD>true + <_TargetId>IISWebDeploy + net8.0 + win-x64 + + + + filePath + logs\\.*\.log$ + + + \ No newline at end of file diff --git a/MP-RIOC/Properties/PublishProfiles/IIS01.pubxml.user b/MP-RIOC/Properties/PublishProfiles/IIS01.pubxml.user new file mode 100644 index 00000000..3b31eede --- /dev/null +++ b/MP-RIOC/Properties/PublishProfiles/IIS01.pubxml.user @@ -0,0 +1,10 @@ + + + + + True|2026-05-08T09:24:06.9798007Z||;True|2026-05-08T11:21:55.9425582+02:00||;True|2026-05-08T11:20:08.8391895+02:00||;True|2026-05-08T11:10:23.1435148+02:00||;True|2026-05-08T11:06:12.1010825+02:00||;True|2026-05-08T10:36:29.2623112+02:00||;False|2026-05-08T10:35:26.8348462+02:00||;True|2026-05-08T10:03:20.5314448+02:00||;True|2026-05-08T09:56:52.4040695+02:00||;True|2026-05-08T09:51:01.5094407+02:00||;False|2026-05-08T09:50:28.6127819+02:00||;False|2026-05-08T09:50:16.2479705+02:00||;True|2026-05-08T09:49:12.5533796+02:00||;True|2026-05-08T09:47:48.2838701+02:00||;True|2026-05-08T09:46:52.6514721+02:00||;True|2026-05-08T09:46:30.4584308+02:00||;True|2026-05-08T09:46:00.3430830+02:00||;True|2026-05-08T09:44:50.2145461+02:00||;False|2026-05-08T09:42:53.1130763+02:00||;True|2026-05-08T09:34:45.8167687+02:00||;False|2026-05-08T09:34:21.4017890+02:00||;True|2026-05-08T09:24:04.8527556+02:00||;False|2026-05-08T09:04:47.5869659+02:00||;False|2026-05-08T09:01:28.1405561+02:00||;False|2026-05-08T09:00:37.4358771+02:00||;False|2026-05-08T08:58:53.9394322+02:00||;False|2026-05-08T08:57:18.3710854+02:00||;False|2026-05-08T08:56:39.0642155+02:00||;True|2026-05-08T08:36:15.4113336+02:00||;False|2026-05-08T08:35:31.1992313+02:00||;False|2026-05-08T08:34:56.3101908+02:00||;False|2026-05-08T08:34:41.2943768+02:00||;True|2026-05-08T08:28:29.2065443+02:00||; + + + AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAlmCNMQ0J1UqPM+RugOqtLgAAAAACAAAAAAAQZgAAAAEAACAAAABmDmKQdTOJuzYQ2FFyU+1htQ8H/TQ+IM9D7RchZs6pvgAAAAAOgAAAAAIAACAAAABeb+XK2KUWpsQ2fiYxFKeezXYyZloQPjo9Qkmjbf+FlyAAAAAR+ckV3KTLXMIMyW4f5PBdp6Uxv5tWJ5LldbO4N+tXYUAAAACJwytTC9fJKy3wyHTlSVYRd/OdBUQ8pCweu3wSK3CGvcpgwT+VFYooELXfzgEV8l6P6FrAdGoF0gt9O3yyn1X4 + + \ No newline at end of file diff --git a/MP-RIOC/Properties/PublishProfiles/IIS03.pubxml b/MP-RIOC/Properties/PublishProfiles/IIS03.pubxml new file mode 100644 index 00000000..e2916a71 --- /dev/null +++ b/MP-RIOC/Properties/PublishProfiles/IIS03.pubxml @@ -0,0 +1,25 @@ + + + + + MSDeploy + true + Release + Any CPU + https://iis03.egalware.com/MP/RIOC/ + false + b9188473-f4ae-4f9f-be2d-70edaace0db9 + false + https://iis03.egalware.com:8172/MsDeploy.axd + Default Web Site/MP/RIOC + + false + WMSVC + true + true + jenkins + <_SavePWD>true + <_TargetId>IISWebDeploy + net8.0 + + \ No newline at end of file diff --git a/MP-RIOC/Properties/PublishProfiles/IIS04.pubxml b/MP-RIOC/Properties/PublishProfiles/IIS04.pubxml new file mode 100644 index 00000000..0322e090 --- /dev/null +++ b/MP-RIOC/Properties/PublishProfiles/IIS04.pubxml @@ -0,0 +1,25 @@ + + + + + MSDeploy + true + Release + Any CPU + https://iis04.egalware.com/MP/RIOC/ + false + b9188473-f4ae-4f9f-be2d-70edaace0db9 + false + https://iis04.egalware.com:8172/MsDeploy.axd + Default Web Site/MP/RIOC + + false + WMSVC + true + true + jenkins + <_SavePWD>true + <_TargetId>IISWebDeploy + net8.0 + + \ No newline at end of file diff --git a/MP-RIOC/Properties/PublishProfiles/IISProfile.pubxml b/MP-RIOC/Properties/PublishProfiles/IISProfile.pubxml new file mode 100644 index 00000000..43da778a --- /dev/null +++ b/MP-RIOC/Properties/PublishProfiles/IISProfile.pubxml @@ -0,0 +1,20 @@ + + + + + Package + Release + Any CPU + + true + false + f3794272-87ad-7c42-2528-6b119dbbc4d5 + bin\publish\MP.RIOC.zip + true + Default Web Site/MP/RIOC + <_TargetId>IISWebDeployPackage + net8.0 + win-x64 + false + + \ No newline at end of file diff --git a/MP-RIOC/Properties/PublishProfiles/IISProfile.pubxml.user b/MP-RIOC/Properties/PublishProfiles/IISProfile.pubxml.user new file mode 100644 index 00000000..3224acae --- /dev/null +++ b/MP-RIOC/Properties/PublishProfiles/IISProfile.pubxml.user @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/MP-RIOC/Properties/launchSettings.json b/MP-RIOC/Properties/launchSettings.json new file mode 100644 index 00000000..b57a323d --- /dev/null +++ b/MP-RIOC/Properties/launchSettings.json @@ -0,0 +1,41 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:15280", + "sslPort": 44323 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "MP/RIOC/api/IOB/", + "applicationUrl": "http://localhost:5290", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "MP/RIOC/api/IOB/", + "applicationUrl": "https://localhost:7120;http://localhost:5290", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "MP/RIOC/api/IOB/", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/MP.IOC/RedisScript/RedisUpdateScript_v5.lua b/MP-RIOC/RedisScript/RedisUpdateScript_v5.lua similarity index 100% rename from MP.IOC/RedisScript/RedisUpdateScript_v5.lua rename to MP-RIOC/RedisScript/RedisUpdateScript_v5.lua diff --git a/MP.IOC/RedisScript/RedisUpdateScript_v6.lua b/MP-RIOC/RedisScript/RedisUpdateScript_v6.lua similarity index 100% rename from MP.IOC/RedisScript/RedisUpdateScript_v6.lua rename to MP-RIOC/RedisScript/RedisUpdateScript_v6.lua diff --git a/MP-RIOC/Resources/ChangeLog-original.html b/MP-RIOC/Resources/ChangeLog-original.html new file mode 100644 index 00000000..2ec27a72 --- /dev/null +++ b/MP-RIOC/Resources/ChangeLog-original.html @@ -0,0 +1,31 @@ + + Modulo MP-RIOC +

Versione: {{CURRENT-REL}}

+
Note di rilascio: +
    +
  • + Ultime modifiche: +
      {{LAST-CHANGES}}
    +
  • +
  • + v.8.16.* → +
      +
    • Ottimizzazioni varie x Redis
    • +
    +
  • +
  • + v.8.16.* → +
      +
    • Prima release dotNet 8.0 router
    • +
    +
  • +
+
+
+ +
+ +
+ \ No newline at end of file diff --git a/MP-RIOC/Resources/ChangeLog.html b/MP-RIOC/Resources/ChangeLog.html new file mode 100644 index 00000000..f24ab287 --- /dev/null +++ b/MP-RIOC/Resources/ChangeLog.html @@ -0,0 +1,31 @@ + + Modulo MP-RIOC +

Versione: 8.16.2605.812

+
Note di rilascio: +
    +
  • + Ultime modifiche: +
      {{LAST-CHANGES}}
    +
  • +
  • + v.8.16.* → +
      +
    • Ottimizzazioni varie x Redis
    • +
    +
  • +
  • + v.8.16.* → +
      +
    • Prima release dotNet 8.0 router
    • +
    +
  • +
+
+
+ +
+ +
+ diff --git a/MP-RIOC/Resources/VersNum.txt b/MP-RIOC/Resources/VersNum.txt new file mode 100644 index 00000000..3ac974ab --- /dev/null +++ b/MP-RIOC/Resources/VersNum.txt @@ -0,0 +1 @@ +8.16.2605.812 diff --git a/MP-RIOC/Resources/logoSteamware.png b/MP-RIOC/Resources/logoSteamware.png new file mode 100644 index 00000000..0958b50a Binary files /dev/null and b/MP-RIOC/Resources/logoSteamware.png differ diff --git a/MP-RIOC/Resources/manifest-original.xml b/MP-RIOC/Resources/manifest-original.xml new file mode 100644 index 00000000..f95e0763 --- /dev/null +++ b/MP-RIOC/Resources/manifest-original.xml @@ -0,0 +1,7 @@ + + + 1.0.0.0 + https://nexus.steamware.net/repository/SWS/{{DIRNAME}}/{{BRANCHNAME}}/{{PACKNAME}}.zip + https://nexus.steamware.net/repository/SWS/{{DIRNAME}}/{{BRANCHNAME}}/ChangeLog.html + false + diff --git a/MP-RIOC/Resources/manifest.xml b/MP-RIOC/Resources/manifest.xml new file mode 100644 index 00000000..3cb930b3 --- /dev/null +++ b/MP-RIOC/Resources/manifest.xml @@ -0,0 +1,7 @@ + + + 8.16.2605.812 + 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-RIOC/Services/IWeightProvider.cs b/MP-RIOC/Services/IWeightProvider.cs new file mode 100644 index 00000000..b18e4fcb --- /dev/null +++ b/MP-RIOC/Services/IWeightProvider.cs @@ -0,0 +1,29 @@ +using MP.Core.DTO; + +namespace MP.RIOC.Services +{ + public interface IWeightProvider + { + #region Public Methods + + /// + /// Ritorna l'intero elenco dei weight attivi nel formato WeightDTO + /// + /// + Task> GetAllWeightsAsync(); + + /// + /// Ritorna la coppia (oldWeight, newWeight) per scegliere dove instradare il metodo tra i 2 sistemi API. + /// + (int oldWeight, int newWeight) GetWeightsFor(string method); + + /// + /// Aggiorna/Aggiuinge il valore del weight richiesto + /// + /// + /// + bool UpsertWeight(WeightDTO updRecord); + + #endregion Public Methods + } +} diff --git a/MP-RIOC/Services/InMemoryWeightProvider.cs b/MP-RIOC/Services/InMemoryWeightProvider.cs new file mode 100644 index 00000000..f4baf415 --- /dev/null +++ b/MP-RIOC/Services/InMemoryWeightProvider.cs @@ -0,0 +1,56 @@ +using MP.Core.DTO; +using System.Collections.Concurrent; + +namespace MP.RIOC.Services +{ + public class InMemoryWeightProvider : IWeightProvider + { + private readonly ConcurrentDictionary _map = new(); + private readonly int _defaultOld; + private readonly int _defaultNew; + + public InMemoryWeightProvider(IConfiguration config) + { + _defaultOld = config.GetValue("RouteMan:DefaultWeightOld", 100); + _defaultNew = config.GetValue("RouteMan:DefaultWeightNew", 0); + } + + public (int oldWeight, int newWeight) GetWeightsFor(string method) + { + if (string.IsNullOrEmpty(method)) method = "unknown"; + return _map.GetOrAdd(method, _ => (_defaultOld, _defaultNew)); + } + + public void SetWeights(string method, int oldWeight, int newWeight) + { + _map[method] = (Math.Clamp(oldWeight, 0, 100), Math.Clamp(newWeight, 0, 100)); + } + + public async Task> GetAllWeightsAsync() + { + var result = new List(); + await Task.Delay(1); + + foreach (var kvp in _map) + { + result.Add(new WeightDTO + { + Method = kvp.Key, + OldWeight = Math.Clamp(kvp.Value.oldW, 0, 100), + NewWeight = Math.Clamp(kvp.Value.newW, 0, 100) + }); + } + return result; + } + + public bool UpsertWeight(WeightDTO updRecord) + { + if (updRecord == null || string.IsNullOrEmpty(updRecord.Method)) + return false; + + _map[updRecord.Method] = (Math.Clamp(updRecord.OldWeight, 0, 100), Math.Clamp(updRecord.NewWeight, 0, 100)); + + return true; + } + } +} diff --git a/MP.IOC/Services/LuaScriptProvider.cs b/MP-RIOC/Services/LuaScriptProvider.cs similarity index 97% rename from MP.IOC/Services/LuaScriptProvider.cs rename to MP-RIOC/Services/LuaScriptProvider.cs index c7eb1e58..41951353 100644 --- a/MP.IOC/Services/LuaScriptProvider.cs +++ b/MP-RIOC/Services/LuaScriptProvider.cs @@ -1,7 +1,7 @@ using Microsoft.Extensions.Options; using MP.Core.Conf; -namespace MP.IOC.Services +namespace MP.RIOC.Services { public sealed class LuaScriptProvider { @@ -39,5 +39,4 @@ namespace MP.IOC.Services return script; } } - } diff --git a/MP.IOC/Services/MetricsCalcService.cs b/MP-RIOC/Services/MetricsCalcService.cs similarity index 99% rename from MP.IOC/Services/MetricsCalcService.cs rename to MP-RIOC/Services/MetricsCalcService.cs index b9918619..81c164c4 100644 --- a/MP.IOC/Services/MetricsCalcService.cs +++ b/MP-RIOC/Services/MetricsCalcService.cs @@ -1,8 +1,8 @@ -using NLog; +using NLog; using StackExchange.Redis; using System.Globalization; -namespace MP.IOC.Services +namespace MP.RIOC.Services { public class MetricsCalcService : BackgroundService { @@ -55,7 +55,7 @@ namespace MP.IOC.Services protected override async Task ExecuteAsync(CancellationToken stoppingToken) { - var interval = _config.GetValue("RouteMan:MetricCalcIntervalSeconds", 20); + var interval = _config.GetValue("RouteMan:MetricCalcIntervalSeconds", 30); while (!stoppingToken.IsCancellationRequested) { diff --git a/MP.IOC/Services/MetricsDbFlushService.cs b/MP-RIOC/Services/MetricsDbFlushService.cs similarity index 94% rename from MP.IOC/Services/MetricsDbFlushService.cs rename to MP-RIOC/Services/MetricsDbFlushService.cs index 4aef9eb7..ba6444b2 100644 --- a/MP.IOC/Services/MetricsDbFlushService.cs +++ b/MP-RIOC/Services/MetricsDbFlushService.cs @@ -1,10 +1,10 @@ -using MP.Data.DbModels.Utils; +using MP.Data.DbModels.Utils; using MP.Data.Services.Utils; using NLog; using StackExchange.Redis; using System.Globalization; -namespace MP.IOC.Services +namespace MP.RIOC.Services { public class MetricsDbFlushService : BackgroundService { @@ -27,8 +27,7 @@ namespace MP.IOC.Services protected override async Task ExecuteAsync(CancellationToken stoppingToken) { - //var interval = _config.GetValue("RouteMan:MetricFlushIntervalSeconds", 120); - var interval = _config.GetValue("RouteMan:MetricFlushIntervalSeconds", 300); + var interval = _config.GetValue("RouteMan:MetricFlushIntervalSeconds", 180); while (!stoppingToken.IsCancellationRequested) { @@ -97,6 +96,7 @@ namespace MP.IOC.Services $"{_redisBaseKey}:stats:days:*" }; + var batch = _db.CreateBatch(); foreach (var pattern in patternsToScan) { // Nota: KeyScanAsync/KeysAsync e' disponibile su IServer @@ -122,7 +122,12 @@ namespace MP.IOC.Services // Se fosse scaduta e abbiamo il permesso, segnamola per la cancellazione if (isExpired && deleteConfirmed) { + // 1. Segna la chiave Hash (Dati) per l'eliminazione keysToDelete.Add(sKey); + + // 2. CORREZIONE: Devi rimuovere il riferimento dal Sorted Set (Indice) + // Usiamo il batch per essere efficienti + _ = batch.SortedSetRemoveAsync(indexKey, statKey); } // Recupero dati dalla Hash @@ -162,6 +167,7 @@ namespace MP.IOC.Services } } } + batch.Execute(); } // --- FASE UPSERT DB --- @@ -219,6 +225,7 @@ namespace MP.IOC.Services $"{_redisBaseKey}:stats:hours:*" }; + var batch = _db.CreateBatch(); foreach (var pattern in patternsToScan) { // Nota: KeyScanAsync/KeysAsync e' disponibile su IServer @@ -244,7 +251,12 @@ namespace MP.IOC.Services // Se fosse scaduta e abbiamo il permesso, segnamola per la cancellazione if (isExpired && deleteConfirmed) { + // 1. Segna la chiave Hash (Dati) per l'eliminazione keysToDelete.Add(sKey); + + // 2. CORREZIONE: Devi rimuovere il riferimento dal Sorted Set (Indice) + // Usiamo il batch per essere efficienti + _ = batch.SortedSetRemoveAsync(indexKey, statKey); } // Recupero dati dalla Hash @@ -284,6 +296,7 @@ namespace MP.IOC.Services } } } + batch.Execute(); } // --- FASE UPSERT DB --- @@ -365,4 +378,4 @@ namespace MP.IOC.Services #endregion Private Methods } -} \ No newline at end of file +} diff --git a/MP.IOC/Services/PreserveBodyTransformer.cs b/MP-RIOC/Services/PreserveBodyTransformer.cs similarity index 98% rename from MP.IOC/Services/PreserveBodyTransformer.cs rename to MP-RIOC/Services/PreserveBodyTransformer.cs index c8d6ed33..2434f658 100644 --- a/MP.IOC/Services/PreserveBodyTransformer.cs +++ b/MP-RIOC/Services/PreserveBodyTransformer.cs @@ -1,8 +1,7 @@ using Yarp.ReverseProxy.Forwarder; -namespace MP.IOC.Services +namespace MP.RIOC.Services { - public class PreserveBodyTransformer : HttpTransformer { public override async ValueTask TransformRequestAsync(HttpContext httpContext, HttpRequestMessage proxyRequest, string destinationPrefix, CancellationToken cancellationToken) @@ -36,6 +35,4 @@ namespace MP.IOC.Services return base.TransformResponseAsync(httpContext, proxyResponse, cancellationToken); } } - - } diff --git a/MP-RIOC/Services/RedisWeightProvider.cs b/MP-RIOC/Services/RedisWeightProvider.cs new file mode 100644 index 00000000..e003c8e5 --- /dev/null +++ b/MP-RIOC/Services/RedisWeightProvider.cs @@ -0,0 +1,157 @@ +using MP.Core.DTO; +using StackExchange.Redis; + +namespace MP.RIOC.Services +{ + public class RedisWeightProvider : IWeightProvider + { + #region Public Constructors + + public RedisWeightProvider(IConnectionMultiplexer mux, IConfiguration config) + { + _config = config; + _db = mux.GetDatabase(); + _mux = mux; + _defaultOld = config.GetValue("RouteMan:DefaultWeightOld", 100); + _defaultNew = config.GetValue("RouteMan:DefaultWeightNew", 0); + _redisBaseKey = config.GetValue("ServerConf:RedisBaseKey") ?? "MP_IOC"; + _keyPrefix = $"{_redisBaseKey}:route_weight:"; + } + + #endregion Public Constructors + + #region Public Methods + + /// + /// Ritorna (oldWeight, newWeight) per il metodo. Se non esiste, crea la chiave con i default. + /// + public (int oldWeight, int newWeight) GetWeightsFor(string method) + { + if (string.IsNullOrEmpty(method)) method = "unknown"; + var key = _keyPrefix + method; + + // Leggi entrambi i campi + var oldVal = _db.HashGet(key, "old"); + var newVal = _db.HashGet(key, "new"); + + // Se entrambi mancanti, inizializza con default (usando HSet con When.NotExists per evitare overwrite) + if (oldVal.IsNull && newVal.IsNull) + { + // Imposta i campi singolarmente con When.NotExists per evitare overwrite + _db.HashSet(key, "old", _defaultOld, When.NotExists); + _db.HashSet(key, "new", _defaultNew, When.NotExists); + + // Rileggi per essere sicuri + oldVal = _db.HashGet(key, "old"); + newVal = _db.HashGet(key, "new"); + } + + // Se uno dei due manca, impostalo al default (non sovrascrive l'altro) + if (oldVal.IsNull) + { + _db.HashSet(key, "old", _defaultOld, When.NotExists); + oldVal = _defaultOld; + } + if (newVal.IsNull) + { + _db.HashSet(key, "new", _defaultNew, When.NotExists); + newVal = _defaultNew; + } + + if (!int.TryParse(oldVal.ToString(), out var oldW)) oldW = _defaultOld; + if (!int.TryParse(newVal.ToString(), out var newW)) newW = _defaultNew; + + // clamp 0..100 + oldW = Math.Clamp(oldW, 0, 100); + newW = Math.Clamp(newW, 0, 100); + + return (oldW, newW); + } + + // API per aggiornare i pesi a runtime (opzionale) + public void SetWeights(string method, int oldWeight, int newWeight) + { + var key = _keyPrefix + (string.IsNullOrEmpty(method) ? "unknown" : method); + _db.HashSet(key, new HashEntry[] { + new HashEntry("old", Math.Clamp(oldWeight,0,100)), + new HashEntry("new", Math.Clamp(newWeight,0,100)) + }); + } + + public async Task> GetAllWeightsAsync() + { + var result = new List(); + var server = _mux.GetServer(_mux.GetEndPoints().First()); + + if (server.IsReplica) + { + return result; + } + + await foreach (var key in server.KeysAsync(pattern: $"{_keyPrefix}*")) + { + var methodName = KeyToString(key.ToString()); + if (string.IsNullOrEmpty(methodName)) continue; + + var oldVal = _db.HashGet(key, "old"); + var newVal = _db.HashGet(key, "new"); + + int oldW = 100; + int newW = 0; + + if (!oldVal.IsNull && int.TryParse(oldVal.ToString(), out var parsedOld)) + oldW = Math.Clamp(parsedOld, 0, 100); + + if (!newVal.IsNull && int.TryParse(newVal.ToString(), out var parsedNew)) + newW = Math.Clamp(parsedNew, 0, 100); + + result.Add(new WeightDTO { Method = methodName, OldWeight = oldW, NewWeight = newW }); + } + + // riordino desc x NEW poi alfabetico... + result = result + .OrderByDescending(x => x.NewWeight) + .ThenBy(x => x.Method) + .ToList(); + + return result; + } + + public bool UpsertWeight(WeightDTO updRecord) + { + if (updRecord == null || string.IsNullOrEmpty(updRecord.Method)) + return false; + + var key = _keyPrefix + updRecord.Method; + _db.HashSet(key, new HashEntry[] { + new HashEntry("old", Math.Clamp(updRecord.OldWeight, 0, 100)), + new HashEntry("new", Math.Clamp(updRecord.NewWeight, 0, 100)) + }); + + return true; + } + + private string KeyToString(string key) + { + if (string.IsNullOrEmpty(key)) return ""; + var prefix = _keyPrefix ?? ""; + if (key.StartsWith(prefix)) + return key.Substring(prefix.Length); + return key; + } + + #endregion Public Methods + + #region Private Fields + + private static string _keyPrefix = "route_weight:"; + private static string _redisBaseKey = ""; + private readonly IConfiguration _config; + private readonly IDatabase _db; + private readonly IConnectionMultiplexer _mux; + private readonly int _defaultNew; + private readonly int _defaultOld; + + #endregion Private Fields + } +} diff --git a/MP.IOC/Services/RouteManager.cs b/MP-RIOC/Services/RouteManager.cs similarity index 82% rename from MP.IOC/Services/RouteManager.cs rename to MP-RIOC/Services/RouteManager.cs index 529996e6..3febe3c9 100644 --- a/MP.IOC/Services/RouteManager.cs +++ b/MP-RIOC/Services/RouteManager.cs @@ -2,10 +2,8 @@ using System.Diagnostics; using Yarp.ReverseProxy.Forwarder; -namespace MP.IOC.Services +namespace MP.RIOC.Services { - - public class RouteManager { private readonly IHttpForwarder _forwarder; @@ -14,6 +12,7 @@ namespace MP.IOC.Services private readonly RouteStatsManager _stats; private readonly IWeightProvider _weightProvider; private readonly IConfiguration _config; + private readonly ForwarderRequestConfig _forwarderConfig; public RouteManager( IHttpForwarder forwarder, @@ -29,7 +28,16 @@ namespace MP.IOC.Services _stats = stats; _weightProvider = weightProvider; _config = config; - _routePath = _config.GetValue("ServerConf:RoutePath") ?? "/api/RIOB"; + _routePath = _config.GetValue("ServerConf:RoutePath") ?? "/api/IOB"; + _forwarderConfig = new ForwarderRequestConfig + { + ActivityTimeout = TimeSpan.FromSeconds(30), + // Parse della versione (es. "1.1") + Version = Version.Parse(_config.GetValue("ServerConf:HttpVersion") ?? "1.1"), + // Policy per la versione + VersionPolicy = _config.GetValue("ServerConf:HttpVersionPolicy") + ?? HttpVersionPolicy.RequestVersionExact + }; } private string _routePath = ""; @@ -74,23 +82,8 @@ namespace MP.IOC.Services // Splitto per / var parts = pathOnly.Split('/', StringSplitOptions.RemoveEmptyEntries); - if (parts.Length > 0) - metodo = parts[0]; - - if (parts.Length > 1) - id = parts[1]; - -#if false - // splitto se ho /... - if (relativePath.Contains("/")) - { - metodo = relativePath.Substring(0, relativePath.IndexOf("/")); - } - else - { - metodo = relativePath; - } -#endif + if (parts.Length > 0) metodo = parts[0]; + if (parts.Length > 1) id = parts[1]; } Log.Debug($"Metodo: {metodo} | machineId: {id}"); @@ -101,8 +94,8 @@ namespace MP.IOC.Services // Costruisci destination base in base al target var destBase = pickNew - ? _config["ReverseProxy:Clusters:cluster-new:Destinations:new1:Address"] - : _config["ReverseProxy:Clusters:cluster-old:Destinations:old1:Address"]; + ? _config["ServerConf:NewApiUrl"] + : _config["ServerConf:OldApiUrl"]; if (string.IsNullOrEmpty(destBase)) { @@ -130,8 +123,7 @@ namespace MP.IOC.Services Log.Debug($"Forwarding to base {destBase} with forwarded path {context.Request.Path} | original PathBase:{originalPathBase} | Path={originalPath})"); - var requestOptions = new ForwarderRequestConfig { ActivityTimeout = TimeSpan.FromSeconds(100) }; - var error = await _forwarder.SendAsync(context, destBase, _httpClientInvoker, requestOptions, _transformer, context.RequestAborted); + var error = await _forwarder.SendAsync(context, destBase, _httpClientInvoker, _forwarderConfig, _transformer, context.RequestAborted); sw.Stop(); _stats.RecordDuration(sKey, sw.Elapsed); @@ -140,8 +132,11 @@ namespace MP.IOC.Services { var feat = context.GetForwarderErrorFeature(); Log.Error(feat?.Exception, "Forwarder error to {DestBase}", destBase); - context.Response.StatusCode = 502; - await context.Response.WriteAsync($"Forward error: {feat?.Exception?.Message}"); + if (!context.Response.HasStarted) + { + context.Response.StatusCode = 502; + await context.Response.WriteAsync($"Forward error: {feat?.Exception?.Message}"); + } } } finally @@ -169,5 +164,4 @@ namespace MP.IOC.Services return result; } } - } diff --git a/MP.IOC/Services/RouteStatsManager.cs b/MP-RIOC/Services/RouteStatsManager.cs similarity index 93% rename from MP.IOC/Services/RouteStatsManager.cs rename to MP-RIOC/Services/RouteStatsManager.cs index 2af2edee..9274826a 100644 --- a/MP.IOC/Services/RouteStatsManager.cs +++ b/MP-RIOC/Services/RouteStatsManager.cs @@ -1,6 +1,6 @@ -using System.Collections.Concurrent; +using System.Collections.Concurrent; -namespace MP.IOC.Services +namespace MP.RIOC.Services { public class RouteStats { @@ -9,6 +9,7 @@ namespace MP.IOC.Services public TimeSpan MaxDuration = TimeSpan.Zero; public TimeSpan MinDuration = TimeSpan.MaxValue; public ConcurrentDictionary StatusCodes = new(); + public TimeSpan AvgDuration => TotalDuration / (Count > 0 ? Count : 1); } public class RouteStatsManager diff --git a/MP-RIOC/appsettings.Development.json b/MP-RIOC/appsettings.Development.json new file mode 100644 index 00000000..b14a27c9 --- /dev/null +++ b/MP-RIOC/appsettings.Development.json @@ -0,0 +1,13 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "ServerConf": { + "useFactory": false, + "OldApiUrl": "http://localhost/MP/IO/IOB/", + "NewApiUrl": "http://localhost/MP/IOC/api/IOB/" + } +} diff --git a/MP-RIOC/appsettings.Production.json b/MP-RIOC/appsettings.Production.json new file mode 100644 index 00000000..7a752d3d --- /dev/null +++ b/MP-RIOC/appsettings.Production.json @@ -0,0 +1,26 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "CodApp": "MP.RIOC", + "ConnectionStrings": { + "MP.Data": "Server=localhost\\SQLEXPRESS;Database=MoonPro;User ID=steamware;Password=viadante16; integrated security=False; MultipleActiveResultSets=True; App=MP.RIOC;", + "MP.Utils": "Server=localhost\\SQLEXPRESS;Database=MoonPro_Utils; User ID=steamware;Password=viadante16; integrated security=False; App=MP.RIOC;", + "Redis": "localhost:6379,DefaultDatabase=5,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false", + "RedisAdmin": "localhost:6379,DefaultDatabase=5,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false,allowAdmin=true" + }, + "ServerConf": { + "useFactory": false, + "OldApiUrl": "http://maposrv.egalware.com/MP/IO/IOB/", + "NewApiUrl": "http://maposrv.egalware.com/MP/IOC/api/IOB/" + }, + "RedisScripts": { + "Scripts": { + "Update": "RedisScript/RedisUpdateScript_v5.lua" + } + } +} diff --git a/MP-RIOC/appsettings.json b/MP-RIOC/appsettings.json new file mode 100644 index 00000000..590b8fb4 --- /dev/null +++ b/MP-RIOC/appsettings.json @@ -0,0 +1,86 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Yarp": "Debug", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "NLog": { + "variables": { + "baseFileDir": "${basedir}/logs/", + "layout": "${longdate} | ${uppercase:${level}} | ${logger:shortName=false} | ${message}" + }, + "extensions": [ + { "assembly": "NLog.Extensions.Logging" }, + { "assembly": "NLog.Web.AspNetCore" } + ], + "throwConfigExceptions": true, + "targets": { + "async": true, + "logfile": { + "type": "File", + "fileName": "${basedir}/logs/${shortdate}.log", + "keepFileOpen": false, + "archiveEvery": "Day", + "archiveFileName": "${basedir}/logs/old/${shortdate}_{#}.log", + "archiveNumbering": "DateAndSequence", + "archiveAboveSize": "10240000", + "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" + } + ] + }, + "CodApp": "MP.RIOC", + "RouteMan": { + "MetricCalcIntervalSeconds": 20, + "MetricFlushIntervalSeconds": 60, + "DefaultWeightOld": 100, + "DefaultWeightNew": 0, + "DeleteExpiredMetrics": true + }, + "ServerConf": { + "RoutePath": "/api/IOB", + "HttpVersion": "1.1", + "HttpVersionPolicy": "RequestVersionExact", + "OldApiUrl": "http://iis01.egalware.com/MP/IO/IOB/", + "NewApiUrl": "http://iis01.egalware.com/MP/IOC/api/IOB/", + "BaseUrlIoc": "/MP/RIOC/", + "MpIoNS": "MoonPro:SQL2016DEV:MoonPro", + "RedisBaseKey": "MP-IOC", + "RedisWeight": true, + "SafePages": "Index", + "redisLongTimeCache": 60, + "redisShortTimeCache": 30, + "useFactory": true + }, + "RedisScripts": { + "Scripts": { + "Update": "RedisScript/RedisUpdateScript_v6.lua" + } + }, + "ConnectionStrings": { + "MP.Data": "Server=SQL2016DEV;Database=MoonPro; User ID=sa;Password=keyhammer16; integrated security=False; App=MP.IOC;", + "MP.Utils": "Server=SQL2016DEV;Database=MoonPro_Utils; User ID=sa;Password=keyhammer16; integrated security=False; App=MP.RIOC;", + "Redis": "redis.ufficio:26379,serviceName=devel,DefaultDatabase=5,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false", + "RedisAdmin": "redis.ufficio:26379,serviceName=devel,DefaultDatabase=5,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false,allowAdmin=true" + } +} diff --git a/MP-RIOC/compilerconfig.json b/MP-RIOC/compilerconfig.json new file mode 100644 index 00000000..445819db --- /dev/null +++ b/MP-RIOC/compilerconfig.json @@ -0,0 +1,6 @@ +[ + { + "outputFile": "Components/Layout/MainLayout.razor.css", + "inputFile": "Components/Layout/MainLayout.razor.less" + } +] \ No newline at end of file diff --git a/MP-RIOC/compilerconfig.json.defaults b/MP-RIOC/compilerconfig.json.defaults new file mode 100644 index 00000000..a5a10c08 --- /dev/null +++ b/MP-RIOC/compilerconfig.json.defaults @@ -0,0 +1,59 @@ +{ + "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 + }, + "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-RIOC/dotnet-tools.json b/MP-RIOC/dotnet-tools.json new file mode 100644 index 00000000..ce0aab73 --- /dev/null +++ b/MP-RIOC/dotnet-tools.json @@ -0,0 +1,13 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "dotnet-ef": { + "version": "10.0.7", + "commands": [ + "dotnet-ef" + ], + "rollForward": false + } + } +} \ No newline at end of file diff --git a/MP-RIOC/logs/.placeholder.file b/MP-RIOC/logs/.placeholder.file new file mode 100644 index 00000000..e69de29b diff --git a/MP-RIOC/post-build.ps1 b/MP-RIOC/post-build.ps1 new file mode 100644 index 00000000..446eede8 --- /dev/null +++ b/MP-RIOC/post-build.ps1 @@ -0,0 +1,32 @@ +param([string]$ProjectDir, [string]$ProjectPath); + +$FileMajMin = "..\MajMin.vers" +$FileVers = "Resources\VersNum.txt" +$FileManIn = "Resources\manifest-original.xml" +$FileManOut = "Resources\manifest.xml" +$FileCLogIn = "Resources\ChangeLog-original.html" +$FileCLogOut = "Resources\ChangeLog.html" +$MajMin = Get-Content $FileMajMin +$currentDate = get-date -format yyMM; +$currentTime = get-date -format dHH; +$find = "(.|\n)*?"; +$currRelNum = $MajMin + $currentDate +"." + $currentTime +$replace = "" + $MajMin + $currentDate +"." + $currentTime + ""; +$csproj = Get-Content $ProjectPath +$csprojUpdated = $csproj -replace $find, $replace + +Set-Content -Path $ProjectPath -Value $csprojUpdated +Set-Content -Path $FileVers -Value $currRelNum + +# replace x manifest +$manData = Get-Content $FileManIn +$manData = $manData -replace "1.0.0.0", $currRelNum +$manData = $manData -replace "{{DIRNAME}}", "MP-IOC" +$manData = $manData -replace "{{BRANCHNAME}}", "stable/LAST" +$manData = $manData -replace "{{PACKNAME}}", "MP.IOC" +Set-Content -Path $FileManOut -Value $manData + +# replace x ChangeLog +$clogData = Get-Content $FileCLogIn +$clogData = $clogData -replace "{{CURRENT-REL}}", $currRelNum +Set-Content -Path $FileCLogOut -Value $clogData diff --git a/MP.AppAuth/AppAuthContext.cs b/MP.AppAuth/AppAuthContext.cs index 35fedc43..7a770a8f 100644 --- a/MP.AppAuth/AppAuthContext.cs +++ b/MP.AppAuth/AppAuthContext.cs @@ -1,5 +1,6 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Options; using MP.AppAuth.Models; using NLog; using System; @@ -23,9 +24,23 @@ namespace MP.AppAuth { } + private DbContextOptions _options; public AppAuthContext(IConfiguration configuration) { _configuration = configuration; + string connStr = _configuration.GetConnectionString("MP.Land.Auth"); + if (string.IsNullOrEmpty(connStr)) + { + connStr = _configuration.GetConnectionString("MP.Land"); + } + if (string.IsNullOrEmpty(connStr)) + { + connStr = _configuration.GetConnectionString("MP.Data"); + } + _options = new DbContextOptionsBuilder() + .UseSqlServer(connStr) + .Options; + try { // se non ci fosse... crea o migra! @@ -39,6 +54,7 @@ namespace MP.AppAuth public AppAuthContext(DbContextOptions options) : base(options) { + _options = options; try { // se non ci fosse... crea o migra! diff --git a/MP.AppAuth/Controllers/AppAuthController.cs b/MP.AppAuth/Controllers/AppAuthController.cs index 24757db7..bd6047d5 100644 --- a/MP.AppAuth/Controllers/AppAuthController.cs +++ b/MP.AppAuth/Controllers/AppAuthController.cs @@ -1,4 +1,5 @@ -using Microsoft.Extensions.Configuration; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; using MP.AppAuth.Models; using NLog; using System; @@ -9,14 +10,14 @@ using System.Threading.Tasks; namespace MP.AppAuth.Controllers { - public class AppAuthController : IDisposable + public class AppAuthController { #region Public Constructors public AppAuthController(IConfiguration configuration) { _configuration = configuration; - dbCtx = new AppAuthContext(configuration); + Log.Info("Avviata classe AppAuthController"); } @@ -116,11 +117,6 @@ namespace MP.AppAuth.Controllers return dbResult; } - public void Dispose() - { - // Clear database context - dbCtx.Dispose(); - } /// /// Elenco completo permessi2funzione @@ -193,33 +189,7 @@ namespace MP.AppAuth.Controllers return dbResult; } - public void ResetController() - { - dbCtx = new AppAuthContext(_configuration); - Log.Info("Effettuato reset AppAuthController"); - } - - /// - /// Annulla modifiche su una specifica entity (cancel update) - /// - /// - /// - public bool RollBackEntity(object item) - { - bool answ = false; - try - { - if (dbCtx.Entry(item).State == Microsoft.EntityFrameworkCore.EntityState.Deleted || dbCtx.Entry(item).State == Microsoft.EntityFrameworkCore.EntityState.Modified) - { - dbCtx.Entry(item).Reload(); - } - } - catch (Exception exc) - { - Log.Error($"Eccezione in rollBackEntity{Environment.NewLine}{exc}"); - } - return answ; - } + /// /// Elenco Record x gestione Update @@ -259,7 +229,6 @@ namespace MP.AppAuth.Controllers #region Private Fields private static IConfiguration _configuration; - private static AppAuthContext dbCtx; private static Logger Log = LogManager.GetCurrentClassLogger(); #endregion Private Fields diff --git a/MP.AppAuth/Services/AppAuthService.cs b/MP.AppAuth/Services/AppAuthService.cs index cef52a0a..7ab866af 100644 --- a/MP.AppAuth/Services/AppAuthService.cs +++ b/MP.AppAuth/Services/AppAuthService.cs @@ -96,7 +96,7 @@ namespace MP.AppAuth.Services }; // conf DB - string connStr = _configuration.GetConnectionString("MP.Land"); + string connStr = _configuration.GetConnectionString("MP.Land.Auth"); if (string.IsNullOrEmpty(connStr)) { _logger.LogError("ConnString empty!"); @@ -431,10 +431,6 @@ namespace MP.AppAuth.Services public void Dispose() { // Clear database controller - if (dbController != null) - { - dbController.Dispose(); - } if (MpDbController != null) { MpDbController.Dispose(); diff --git a/MP.Data/Controllers/MpLandController.cs b/MP.Data/Controllers/MpLandController.cs index 956c460c..9a77ad18 100644 --- a/MP.Data/Controllers/MpLandController.cs +++ b/MP.Data/Controllers/MpLandController.cs @@ -19,7 +19,11 @@ namespace MP.Data.Controllers public MpLandController(IConfiguration configuration) { _configuration = configuration; - string connStr = _configuration.GetConnectionString("MP.Data"); + string connStr = _configuration.GetConnectionString("MP.Land"); + if(string.IsNullOrEmpty(connStr)) + { + connStr = _configuration.GetConnectionString("MP.Data"); + } options = new DbContextOptionsBuilder() .UseSqlServer(connStr) .Options; diff --git a/MP.Data/DataServiceCollectionExtensions.cs b/MP.Data/DataServiceCollectionExtensions.cs index 78eb73e2..2ff337b3 100644 --- a/MP.Data/DataServiceCollectionExtensions.cs +++ b/MP.Data/DataServiceCollectionExtensions.cs @@ -14,15 +14,6 @@ namespace MP.Data { public static IServiceCollection AddIocDataLayer(this IServiceCollection services) { - //// DbContextFactory: preferibile in Blazor Server e scenari concorrenti - //services.AddDbContextFactory(options => - // options.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString))); - - //// servizi preliminari - ////services.TryAddSingleton(redisConn); - //services.TryAddSingleton(); - //services.TryAddSingleton(); - // Repository Singleton services.TryAddSingleton(); @@ -40,14 +31,6 @@ namespace MP.Data services.TryAddScoped(); services.TryAddScoped(); - //// aggiunta servizi finali Singleton... - //services.TryAddSingleton(); - //services.TryAddSingleton(); - //services.TryAddSingleton(); - //services.TryAddSingleton(); - //services.TryAddSingleton(); - - return services; } } diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj index d1c88af3..0a714ad2 100644 --- a/MP.IOC/MP.IOC.csproj +++ b/MP.IOC/MP.IOC.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 8.16.2605.611 + 8.16.2605.811 @@ -33,8 +33,8 @@ + - @@ -48,12 +48,6 @@ Always - - Always - - - Always - diff --git a/MP.IOC/Program.cs b/MP.IOC/Program.cs index c0ccbfda..59a5e764 100644 --- a/MP.IOC/Program.cs +++ b/MP.IOC/Program.cs @@ -1,4 +1,3 @@ -using Microsoft.AspNetCore.Http.Extensions; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.OpenApi.Models; @@ -10,7 +9,6 @@ using MP.IOC.Services; using NLog; using NLog.Web; using StackExchange.Redis; -using System.Net; using System.Reflection; var builder = WebApplication.CreateBuilder(args); @@ -29,36 +27,11 @@ logger.Info($"Current ASPNETCORE_ENVIRONMENT: {env.EnvironmentName}"); ConfigurationManager configuration = builder.Configuration; // REDIS setup logger.Info("Config OK"); -string confRedis = configuration.GetConnectionString("Redis"); +string confRedis = configuration.GetConnectionString("Redis") ?? "localhost:6379"; string redisSrvAddr = confRedis.Substring(0, confRedis.IndexOf(":")); logger.Info("Setup REDIS OK"); -// YARP base config -builder.Services.AddReverseProxy().LoadFromConfig(builder.Configuration.GetSection("ReverseProxy")); -builder.Services.AddHttpForwarder(); - -// HttpMessageInvoker (SocketsHttpHandler) -builder.Services.AddSingleton(sp => -{ - var handler = new SocketsHttpHandler - { - AllowAutoRedirect = false, - UseCookies = false, - PooledConnectionLifetime = TimeSpan.FromMinutes(5), - AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate - }; - - // Accetta certificati non validi (dev only) - handler.SslOptions = new System.Net.Security.SslClientAuthenticationOptions - { - RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true - }; - - return new HttpMessageInvoker(handler); -}); -logger.Info("YARP reverse proxy configured"); - builder.Services.Configure( builder.Configuration.GetSection("RedisScripts")); logger.Info("RedisScript Provider configured"); @@ -82,13 +55,6 @@ builder.Services.AddDbContextFactory(options => // MP.Data Services Utils - Statistiche DB builder.Services.AddIocDataLayer(); -// base services -builder.Services.AddSingleton(); -builder.Services.AddSingleton(); -builder.Services.AddHostedService(); -builder.Services.AddHostedService(); -builder.Services.AddSingleton(); - // Registra i servizi per Blazor builder.Services.AddRazorComponents() .AddInteractiveServerComponents(); @@ -96,8 +62,6 @@ builder.Services.AddRazorComponents() //builder.Services.AddHealthChecks() // .AddSqlServer(builder.Configuration.GetConnectionString("CoreDb")); - - // generic controller builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle @@ -136,59 +100,14 @@ else } logger.Info($"Weight service configured | use Redis: {weightOnRedis}"); -// RouteManager registration (singleton) -builder.Services.AddSingleton(); -logger.Info("Singleton Route Manager registered"); var app = builder.Build(); -// Blocco per la migrazione automatica del DB Utils... -using (var scope = app.Services.CreateScope()) -{ - var services = scope.ServiceProvider; - try - { - var context = services.GetRequiredService(); - context.Database.Migrate(); - } - catch (Exception ex) - { - var migrateLogger = services.GetRequiredService>(); - migrateLogger.LogError(ex, "Si � verificato un errore durante l'aggiornamento del database."); - } -} - - // aggiunt base URL x routing corretto string baseUrl = configuration.GetValue("ServerConf:BaseUrlIoc") ?? "/MP/"; app.UsePathBase(baseUrl); -string routePath = configuration.GetValue("ServerConf:RoutePath") ?? "/api/RIOB"; -string fullPath = $"{baseUrl}{routePath}".Replace("//", "/"); logger.Info($"BaseUrl: {baseUrl}"); -app.Use(async (ctx, next) => -{ - logger.Debug($"Incoming request PathBase='{ctx.Request.PathBase}' Path='{ctx.Request.Path}' RawTarget='{ctx.Request.GetEncodedUrl()}'"); - await next(); -}); - - -// parametrizzare?!?!? -app.MapWhen(ctx => - ctx.Request.Path.StartsWithSegments(fullPath, StringComparison.OrdinalIgnoreCase) || - ctx.Request.Path.StartsWithSegments(routePath, StringComparison.OrdinalIgnoreCase) || - (ctx.Request.PathBase.HasValue && ctx.Request.Path.StartsWithSegments(routePath, StringComparison.OrdinalIgnoreCase)), - builder => - { - builder.Run(async ctx => - { - var routeManager = ctx.RequestServices.GetRequiredService(); - await routeManager.HandleAsync(ctx); - }); - }); - -logger.Info("App: route Mapped"); - // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment() || app.Environment.IsStaging()) diff --git a/MP.IOC/Properties/PublishProfiles/IIS01.pubxml b/MP.IOC/Properties/PublishProfiles/IIS01.pubxml index d7ddcd79..823f36eb 100644 --- a/MP.IOC/Properties/PublishProfiles/IIS01.pubxml +++ b/MP.IOC/Properties/PublishProfiles/IIS01.pubxml @@ -25,4 +25,10 @@ https://go.microsoft.com/fwlink/?LinkID=208121. net8.0 win-x64 + + + filePath + logs\\.*\.log$ + + \ No newline at end of file diff --git a/MP.IOC/Properties/PublishProfiles/IIS01.pubxml.user b/MP.IOC/Properties/PublishProfiles/IIS01.pubxml.user index 40aee328..15901b1b 100644 --- a/MP.IOC/Properties/PublishProfiles/IIS01.pubxml.user +++ b/MP.IOC/Properties/PublishProfiles/IIS01.pubxml.user @@ -6,7 +6,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121. AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAdCoESbxryUqXde3FfEOCTwAAAAACAAAAAAADZgAAwAAAABAAAAAFrH1vByj45Qn06hO/OH6tAAAAAASAAACgAAAAEAAAAIUK5NiEpc4lc11Op6/CLx8YAAAAMecN12fzIN9e3E8R/nu0ATe2PAsMy7M8FAAAAKbUyki2vkSFehjbpB8wCVVVa055 - True|2026-04-17T17:09:49.4900600Z||;True|2026-04-03T12:55:15.0251473+02:00||;True|2026-04-03T10:03:02.5833820+02:00||;True|2026-04-03T09:55:55.5274684+02:00||;True|2026-04-03T09:52:44.9063312+02:00||;False|2026-04-03T09:45:49.5943015+02:00||;True|2024-11-04T08:56:17.3071781+01:00||;True|2023-02-14T17:41:26.3850692+01:00||;True|2023-02-14T17:31:39.4933399+01:00||; + True|2026-05-08T09:26:08.1731328Z||;False|2026-05-08T11:06:51.2202890+02:00||;True|2026-05-08T10:37:55.0049896+02:00||;False|2026-05-08T10:37:05.1546068+02:00||;False|2026-05-08T10:36:33.0311629+02:00||;False|2026-05-08T10:35:55.7742437+02:00||;True|2026-04-17T19:09:49.4900600+02:00||;True|2026-04-03T12:55:15.0251473+02:00||;True|2026-04-03T10:03:02.5833820+02:00||;True|2026-04-03T09:55:55.5274684+02:00||;True|2026-04-03T09:52:44.9063312+02:00||;False|2026-04-03T09:45:49.5943015+02:00||;True|2024-11-04T08:56:17.3071781+01:00||;True|2023-02-14T17:41:26.3850692+01:00||;True|2023-02-14T17:31:39.4933399+01:00||; \ No newline at end of file diff --git a/MP.IOC/Resources/ChangeLog-original.html b/MP.IOC/Resources/ChangeLog-original.html index fa79ade6..cf07d7e9 100644 --- a/MP.IOC/Resources/ChangeLog-original.html +++ b/MP.IOC/Resources/ChangeLog-original.html @@ -25,7 +25,7 @@
\ No newline at end of file diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html index f22519c1..4ba1f793 100644 --- a/MP.IOC/Resources/ChangeLog.html +++ b/MP.IOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-IOC -

Versione: 8.16.2605.611

+

Versione: 8.16.2605.811


Note di rilascio:
  • @@ -25,7 +25,7 @@ diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt index a09c6432..ddc2c22a 100644 --- a/MP.IOC/Resources/VersNum.txt +++ b/MP.IOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.611 +8.16.2605.811 diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml index 08c9065b..bb27fee8 100644 --- a/MP.IOC/Resources/manifest.xml +++ b/MP.IOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.611 + 8.16.2605.811 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.Production.json b/MP.IOC/appsettings.Production.json index 5b315b32..787c7891 100644 --- a/MP.IOC/appsettings.Production.json +++ b/MP.IOC/appsettings.Production.json @@ -5,23 +5,6 @@ "Microsoft.AspNetCore": "Warning" } }, - "ReverseProxy": { - "Routes": [ - { - "RouteId": "route-man-r-iob", - "ClusterId": "cluster-placeholder", - "Match": { "Path": "/api/RIOB/{**catch-all}" } - } - ], - "Clusters": { - "cluster-old": { - "Destinations": { "old1": { "Address": "https://maposrv.egalware.com/MP/IO/IOB/" } } - }, - "cluster-new": { - "Destinations": { "new1": { "Address": "https://maposrv.egalware.com/MP/IOC/api/IOB/" } } - } - } - }, "AllowedHosts": "*", "CodApp": "MP.IOC", "ConnectionStrings": { @@ -34,10 +17,5 @@ }, "ServerConf": { "useFactory": false - }, - "RedisScripts": { - "Scripts": { - "Update": "RedisScript/RedisUpdateScript_v5.lua" - } } } diff --git a/MP.IOC/appsettings.json b/MP.IOC/appsettings.json index d7c5727c..e947a8ce 100644 --- a/MP.IOC/appsettings.json +++ b/MP.IOC/appsettings.json @@ -14,8 +14,6 @@ "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" } @@ -26,6 +24,7 @@ "logfile": { "type": "File", "fileName": "${basedir}/logs/${shortdate}.log", + "keepFileOpen": false, "archiveEvery": "Day", "archiveFileName": "${basedir}/logs/old/${shortdate}_{#}.log", "archiveNumbering": "DateAndSequence", @@ -54,23 +53,7 @@ }, "AllowedHosts": "*", "CodApp": "MP.IOC", - "ReverseProxy": { - "Routes": [ - { - "RouteId": "route-man-r-iob", - "ClusterId": "cluster-placeholder", - "Match": { "Path": "/api/RIOB/{**catch-all}" } - } - ], - "Clusters": { - "cluster-old": { - "Destinations": { "old1": { "Address": "https://iis01.egalware.com/MP/IO/IOB/" } } - }, - "cluster-new": { - "Destinations": { "new1": { "Address": "https://iis01.egalware.com/MP/IOC/api/IOB/" } } - } - } - }, + "RouteMan": { "MetricCalcIntervalSeconds": 10, "MetricFlushIntervalSeconds": 60, diff --git a/MP.Land/MP.Land.csproj b/MP.Land/MP.Land.csproj index 4b406421..4f1a232f 100644 --- a/MP.Land/MP.Land.csproj +++ b/MP.Land/MP.Land.csproj @@ -3,7 +3,7 @@ net8.0 MP.Land - 8.16.2605.0411 + 8.16.2605.0811 Debug;Release;Debug_LiManDebug en True diff --git a/MP.Land/Pages/IobList.razor.cs b/MP.Land/Pages/IobList.razor.cs index 87e6ca55..90157bb1 100644 --- a/MP.Land/Pages/IobList.razor.cs +++ b/MP.Land/Pages/IobList.razor.cs @@ -173,18 +173,6 @@ namespace MP.Land.Pages return answ; } -#if false - protected Core.Objects.IOB_data CurrIobInfo(string idxMacc) - { - Core.Objects.IOB_data answ = new Core.Objects.IOB_data(); - if (DictIobInfo.ContainsKey(idxMacc)) - { - answ = DictIobInfo[idxMacc]; - } - return answ; - } -#endif - protected void DataInit() { isLoading = true; @@ -219,17 +207,6 @@ namespace MP.Land.Pages return answ; } -#if false - protected string IobExeTrim(string IdxMacchina) - { - string answ = MacIobConf(IdxMacchina, "IobExe"); - if (!string.IsNullOrEmpty(answ) && answ.Contains(",")) - { - answ = answ.Substring(0, answ.IndexOf(',')); - } - return answ; - } -#endif protected override async Task OnInitializedAsync() { diff --git a/MP.Land/Pages/UserQr.razor.cs b/MP.Land/Pages/UserQr.razor.cs index 49f50c64..6d121f15 100644 --- a/MP.Land/Pages/UserQr.razor.cs +++ b/MP.Land/Pages/UserQr.razor.cs @@ -143,11 +143,9 @@ namespace MP.Land.Pages private async void OnFilterUpdated() { isLoading = true; - await Task.Delay(1); await InvokeAsync(StateHasChanged); ListRecords = null; currPage = 1; - await Task.Delay(1); await ReloadData(); } @@ -158,7 +156,6 @@ namespace MP.Land.Pages await InvokeAsync(StateHasChanged); ListRecords = null; currPage = 1; - await Task.Delay(1); await ReloadData(); } @@ -166,11 +163,9 @@ namespace MP.Land.Pages { isLoading = true; // importante altrimenti NON mostra update UI - await Task.Delay(1); SearchRecords = await DataService.AnagOperByGroupList(groupName, AppMService.SearchVal); ListRecords = SearchRecords.Skip((currPage - 1) * numRecord).Take(numRecord).ToList(); totalCount = SearchRecords.Count(); - await Task.Delay(1); isLoading = false; StateHasChanged(); } diff --git a/MP.Land/Resources/ChangeLog.html b/MP.Land/Resources/ChangeLog.html index 01aed9ae..65e63b56 100644 --- a/MP.Land/Resources/ChangeLog.html +++ b/MP.Land/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo Tablet MAPO - DotNet6 -

    Versione: 8.16.2605.0411

    +

    Versione: 8.16.2605.0811


    Note di rilascio:
      diff --git a/MP.Land/Resources/VersNum.txt b/MP.Land/Resources/VersNum.txt index af1dc925..3249ffa8 100644 --- a/MP.Land/Resources/VersNum.txt +++ b/MP.Land/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.0411 +8.16.2605.0811 diff --git a/MP.Land/Resources/manifest.xml b/MP.Land/Resources/manifest.xml index d230416a..e201bc34 100644 --- a/MP.Land/Resources/manifest.xml +++ b/MP.Land/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.0411 + 8.16.2605.0811 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/appsettings.json b/MP.Land/appsettings.json index b3be2a6d..09dcc181 100644 --- a/MP.Land/appsettings.json +++ b/MP.Land/appsettings.json @@ -58,6 +58,7 @@ "ConnectionStrings": { "DefaultConnection": "Server=SQL2016DEV;Database=MoonPro;Trusted_Connection=True;MultipleActiveResultSets=true", "MP.All": "Server=SQL2016DEV;Database=MoonPro;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=MP.Land;", + "MP.Data": "Server=SQL2016DEV;Database=MoonPro;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=MP.Land;", "MP.Flux": "Server=SQL2016DEV;Database=MoonPro_FluxData;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=MP.Land;", "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;",