Merge branch 'Release/AddRIoc_01'
This commit is contained in:
+98
-3
@@ -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
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
<PackageVersion Include="Blazored.LocalStorage" Version="4.5.0" />
|
||||
<PackageVersion Include="Blazored.SessionStorage" Version="2.4.0" />
|
||||
<PackageVersion Include="DiffMatchPatch" Version="1.0.3" />
|
||||
<PackageVersion Include="EgwCoreLib.Razor" Version="1.5.2605.412" />
|
||||
<PackageVersion Include="EgwCoreLib.Utils" Version="1.5.2605.412" />
|
||||
<PackageVersion Include="EgwCoreLib.Razor" Version="1.5.2605.511" />
|
||||
<PackageVersion Include="EgwCoreLib.Utils" Version="1.5.2605.511" />
|
||||
<PackageVersion Include="MailKit" Version="4.16.0" />
|
||||
<PackageVersion Include="Majorsoft.Blazor.Components.Debounce" Version="1.5.0" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Authentication.Negotiate" Version="8.0.25" />
|
||||
@@ -28,15 +28,16 @@
|
||||
<PackageVersion Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="6.0.17" />
|
||||
<PackageVersion Include="MongoDB.Driver" Version="2.19.0" />
|
||||
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageVersion Include="NLog" Version="6.1.2" />
|
||||
<PackageVersion Include="NLog" Version="6.1.3" />
|
||||
<PackageVersion Include="NLog.Targets.OpenTelemetryProtocol" Version="1.2.6" />
|
||||
<PackageVersion Include="NLog.Web.AspNetCore" Version="6.1.2" />
|
||||
<PackageVersion Include="NLog.Web.AspNetCore" Version="6.1.3" />
|
||||
<PackageVersion Include="OpenTelemetry.Exporter.Console" Version="1.15.3" />
|
||||
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.15.3" />
|
||||
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.15.3" />
|
||||
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.15.2" />
|
||||
<PackageVersion Include="OpenTelemetry.Instrumentation.SqlClient" Version="1.15.2" />
|
||||
<PackageVersion Include="OpenTelemetry.Instrumentation.StackExchangeRedis" Version="1.15.0-beta.1" />
|
||||
<PackageVersion Include="Snappier" Version="1.3.1" />
|
||||
<PackageVersion Include="System.Text.Encodings.Web" Version="8.0.0" />
|
||||
<PackageVersion Include="RestSharp" Version="112.0.0" />
|
||||
<PackageVersion Include="SharpZipLib" Version="1.4.2" />
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
@MP_RIOC_HostAddress = http://localhost:5290
|
||||
|
||||
GET {{MP_RIOC_HostAddress}}/weatherforecast/
|
||||
Accept: application/json
|
||||
|
||||
###
|
||||
@@ -0,0 +1,5 @@
|
||||
<Solution>
|
||||
<Project Path="../MP.Core/MP.Core.csproj" />
|
||||
<Project Path="../MP.Data/MP.Data.csproj" />
|
||||
<Project Path="MP.RIOC.csproj" />
|
||||
</Solution>
|
||||
@@ -0,0 +1,46 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<RootNamespace>MP.RIOC</RootNamespace>
|
||||
<Version>8.16.2605.812</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Remove="compilerconfig.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NLog" />
|
||||
<PackageReference Include="NLog.Web.AspNetCore" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" />
|
||||
<PackageReference Include="Yarp.ReverseProxy" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\MP.Core\MP.Core.csproj" />
|
||||
<ProjectReference Include="..\MP.Data\MP.Data.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="compilerconfig.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="logs\.placeholder.file">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="RedisScript\RedisUpdateScript_v5.lua">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="RedisScript\RedisUpdateScript_v6.lua">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||
<Exec Command="powershell.exe -ExecutionPolicy Unrestricted -NoProfile -NonInteractive -File $(ProjectDir)\post-build.ps1 -ProjectDir $(ProjectDir) -ProjectPath $(ProjectPath)" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -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);
|
||||
}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>MP.RIOC Dashboard</title>
|
||||
<style>
|
||||
body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: #f0f2f5; padding: 30px; color: #333; }
|
||||
.card { background: white; padding: 25px; border-radius: 12px; box-shadow: 0 4px 15px rgba(0,0,0,0.1); max-width: 900px; margin: auto; }
|
||||
h1 { color: #0056b3; margin-top: 0; }
|
||||
table { width: 100%; border-collapse: collapse; margin-top: 20px; }
|
||||
th, td { text-align: left; padding: 12px; border-bottom: 1px solid #eee; }
|
||||
th { background-color: #f8f9fa; color: #666; text-transform: uppercase; font-size: 0.85em; }
|
||||
.tag { padding: 4px 8px; border-radius: 4px; font-size: 0.8em; font-weight: bold; }
|
||||
.tag-ioc { background: #e3f2fd; color: #0d47a1; }
|
||||
.tag-io { background: #fff3e0; color: #e65100; }
|
||||
.latency { font-family: monospace; font-weight: bold; }
|
||||
.d-flex { display: flex !important; }
|
||||
.justify-content-between { justify-content: space-between !important; }
|
||||
.align-items-center { align-items: center !important; }
|
||||
.flex-column { flex-direction: column !important; }
|
||||
.text-end { text-align: right !important; }
|
||||
.px-0 { padding-left: 0 !important; padding-right: 0 !important; }
|
||||
/* Miglioramento per l'intestazione custom */
|
||||
.header-container {
|
||||
border-bottom: 2px solid #0056b3;
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
h1 { margin: 0; font-size: 2.5em; color: #0056b3; line-height: 1; }
|
||||
h2 { margin: 0; font-size: 1.8em; color: #333; line-height: 1; }
|
||||
h3 { margin: 5px 0 0 0; font-size: 1em; color: #666; font-weight: normal; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="card">
|
||||
<div class="d-flex justify-content-between align-items-center header-container">
|
||||
<div class="px-0">
|
||||
<h1>MAPO MES</h1>
|
||||
<div>Live Dashboard</div>
|
||||
</div>
|
||||
<div class="px-0 text-end">
|
||||
<h2>MP-RIOC</h2>
|
||||
<h3>Router I/O Controller</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div class="px-0">
|
||||
Stato: <span style="color:green">● Online</span>
|
||||
</div>
|
||||
<div class="px-0 text-end">
|
||||
Versione: @System.Reflection.Assembly.GetExecutingAssembly().GetName().Version
|
||||
</div>
|
||||
</div>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Target | Metodo | ID</th>
|
||||
<th class="text-end">Chiamate</th>
|
||||
<th class="text-end">Latenza Media</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var stat in metrics)
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
@if(stat.Key.StartsWith("IOC")) { <span class="tag tag-ioc">NEW</span> }
|
||||
else { <span class="tag tag-io">OLD</span> }
|
||||
@stat.Key
|
||||
</td>
|
||||
<td class="text-end">@stat.Value.Count</td>
|
||||
<td class="latency text-end">@(stat.Value.AvgDuration)ms</td>
|
||||
</tr>
|
||||
}
|
||||
@if (!metrics.Any())
|
||||
{
|
||||
<tr>
|
||||
<td colspan="3" style="text-align:center; padding: 40px; color: #999;">Nessun dato raccolto al momento.</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="text-end" style="margin-top: 20px; font-size: 0.8em; color: #999;">
|
||||
Ultimo aggiornamento: @DateTime.Now.ToString("HH:mm:ss")
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,12 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
|
||||
namespace MP.RIOC.Pages
|
||||
{
|
||||
public class IndexModel : PageModel
|
||||
{
|
||||
public void OnGet()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<RedisScriptsConfig>(
|
||||
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<MoonProContext>(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<MoonPro_UtilsContext>(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<IConnectionMultiplexer>(redisMux);
|
||||
|
||||
// Registrazione dei servizi custom
|
||||
builder.Services.AddSingleton<PreserveBodyTransformer>();
|
||||
builder.Services.AddSingleton<RouteStatsManager>();
|
||||
builder.Services.AddHostedService<MetricsCalcService>();
|
||||
builder.Services.AddHostedService<MetricsDbFlushService>();
|
||||
builder.Services.AddSingleton<LuaScriptProvider>();
|
||||
|
||||
logger.Info("Standard service configured");
|
||||
|
||||
// WeightProvider: Redis/Memory da config
|
||||
var weightOnRedis = builder.Configuration.GetValue<bool>("ServerConf:RedisWeight", false);
|
||||
if (weightOnRedis)
|
||||
{
|
||||
builder.Services.AddSingleton<IWeightProvider, RedisWeightProvider>();
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.Services.AddSingleton<IWeightProvider, InMemoryWeightProvider>();
|
||||
}
|
||||
logger.Info($"Weight service configured | use Redis: {weightOnRedis}");
|
||||
|
||||
// RouteManager registration (singleton)
|
||||
builder.Services.AddSingleton<RouteManager>();
|
||||
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<MoonPro_UtilsContext>();
|
||||
context.Database.Migrate();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var migrateLogger = services.GetRequiredService<ILogger<Program>>();
|
||||
migrateLogger.LogError(ex, "Si � verificato un errore durante l'aggiornamento del database.");
|
||||
}
|
||||
}
|
||||
|
||||
// 1. Configurazione Base Path
|
||||
string baseUrl = configuration.GetValue<string>("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<string>("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<RouteManager>();
|
||||
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();
|
||||
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<WebPublishMethod>MSDeploy</WebPublishMethod>
|
||||
<LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
|
||||
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
|
||||
<LastUsedPlatform>Any CPU</LastUsedPlatform>
|
||||
<SiteUrlToLaunchAfterPublish>https://iis01.egalware.com/MP/RIOC/</SiteUrlToLaunchAfterPublish>
|
||||
<ExcludeApp_Data>false</ExcludeApp_Data>
|
||||
<ProjectGuid>b9188473-f4ae-4f9f-be2d-70edaace0db9</ProjectGuid>
|
||||
<SelfContained>false</SelfContained>
|
||||
<MSDeployServiceURL>https://iis01.egalware.com:8172/MsDeploy.axd</MSDeployServiceURL>
|
||||
<DeployIisAppPath>Default Web Site/MP/RIOC</DeployIisAppPath>
|
||||
<RemoteSitePhysicalPath />
|
||||
<SkipExtraFilesOnServer>false</SkipExtraFilesOnServer>
|
||||
<MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
|
||||
<EnableMSDeployBackup>true</EnableMSDeployBackup>
|
||||
<EnableMsDeployAppOffline>true</EnableMsDeployAppOffline>
|
||||
<UserName>jenkins</UserName>
|
||||
<_SavePWD>true</_SavePWD>
|
||||
<_TargetId>IISWebDeploy</_TargetId>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<MsDeploySkipRules Include="SkipLogFiles">
|
||||
<ObjectName>filePath</ObjectName>
|
||||
<AbsolutePath>logs\\.*\.log$</AbsolutePath>
|
||||
</MsDeploySkipRules>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<History>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||;</History>
|
||||
<LastFailureDetails />
|
||||
<TimeStampOfAssociatedLegacyPublishXmlFile />
|
||||
<EncryptedPassword>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAlmCNMQ0J1UqPM+RugOqtLgAAAAACAAAAAAAQZgAAAAEAACAAAABmDmKQdTOJuzYQ2FFyU+1htQ8H/TQ+IM9D7RchZs6pvgAAAAAOgAAAAAIAACAAAABeb+XK2KUWpsQ2fiYxFKeezXYyZloQPjo9Qkmjbf+FlyAAAAAR+ckV3KTLXMIMyW4f5PBdp6Uxv5tWJ5LldbO4N+tXYUAAAACJwytTC9fJKy3wyHTlSVYRd/OdBUQ8pCweu3wSK3CGvcpgwT+VFYooELXfzgEV8l6P6FrAdGoF0gt9O3yyn1X4</EncryptedPassword>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<WebPublishMethod>MSDeploy</WebPublishMethod>
|
||||
<LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
|
||||
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
|
||||
<LastUsedPlatform>Any CPU</LastUsedPlatform>
|
||||
<SiteUrlToLaunchAfterPublish>https://iis03.egalware.com/MP/RIOC/</SiteUrlToLaunchAfterPublish>
|
||||
<ExcludeApp_Data>false</ExcludeApp_Data>
|
||||
<ProjectGuid>b9188473-f4ae-4f9f-be2d-70edaace0db9</ProjectGuid>
|
||||
<SelfContained>false</SelfContained>
|
||||
<MSDeployServiceURL>https://iis03.egalware.com:8172/MsDeploy.axd</MSDeployServiceURL>
|
||||
<DeployIisAppPath>Default Web Site/MP/RIOC</DeployIisAppPath>
|
||||
<RemoteSitePhysicalPath />
|
||||
<SkipExtraFilesOnServer>false</SkipExtraFilesOnServer>
|
||||
<MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
|
||||
<EnableMSDeployBackup>true</EnableMSDeployBackup>
|
||||
<EnableMsDeployAppOffline>true</EnableMsDeployAppOffline>
|
||||
<UserName>jenkins</UserName>
|
||||
<_SavePWD>true</_SavePWD>
|
||||
<_TargetId>IISWebDeploy</_TargetId>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<WebPublishMethod>MSDeploy</WebPublishMethod>
|
||||
<LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
|
||||
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
|
||||
<LastUsedPlatform>Any CPU</LastUsedPlatform>
|
||||
<SiteUrlToLaunchAfterPublish>https://iis04.egalware.com/MP/RIOC/</SiteUrlToLaunchAfterPublish>
|
||||
<ExcludeApp_Data>false</ExcludeApp_Data>
|
||||
<ProjectGuid>b9188473-f4ae-4f9f-be2d-70edaace0db9</ProjectGuid>
|
||||
<SelfContained>false</SelfContained>
|
||||
<MSDeployServiceURL>https://iis04.egalware.com:8172/MsDeploy.axd</MSDeployServiceURL>
|
||||
<DeployIisAppPath>Default Web Site/MP/RIOC</DeployIisAppPath>
|
||||
<RemoteSitePhysicalPath />
|
||||
<SkipExtraFilesOnServer>false</SkipExtraFilesOnServer>
|
||||
<MSDeployPublishMethod>WMSVC</MSDeployPublishMethod>
|
||||
<EnableMSDeployBackup>true</EnableMSDeployBackup>
|
||||
<EnableMsDeployAppOffline>true</EnableMsDeployAppOffline>
|
||||
<UserName>jenkins</UserName>
|
||||
<_SavePWD>true</_SavePWD>
|
||||
<_TargetId>IISWebDeploy</_TargetId>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<WebPublishMethod>Package</WebPublishMethod>
|
||||
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
|
||||
<LastUsedPlatform>Any CPU</LastUsedPlatform>
|
||||
<SiteUrlToLaunchAfterPublish />
|
||||
<LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
|
||||
<ExcludeApp_Data>false</ExcludeApp_Data>
|
||||
<ProjectGuid>f3794272-87ad-7c42-2528-6b119dbbc4d5</ProjectGuid>
|
||||
<DesktopBuildPackageLocation>bin\publish\MP.RIOC.zip</DesktopBuildPackageLocation>
|
||||
<PackageAsSingleFile>true</PackageAsSingleFile>
|
||||
<DeployIisAppPath>Default Web Site/MP/RIOC</DeployIisAppPath>
|
||||
<_TargetId>IISWebDeployPackage</_TargetId>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<SelfContained>false</SelfContained>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<TimeStampOfAssociatedLegacyPublishXmlFile />
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<body>
|
||||
<i>Modulo MP-RIOC </i>
|
||||
<h4>Versione: {{CURRENT-REL}}</h4>
|
||||
<br /> Note di rilascio:
|
||||
<ul>
|
||||
<li>
|
||||
<b>Ultime modifiche:</b>
|
||||
<ul>{{LAST-CHANGES}}</ul>
|
||||
</li>
|
||||
<li>
|
||||
<b>v.8.16.* →</b>
|
||||
<ul>
|
||||
<li>Ottimizzazioni varie x Redis</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<b>v.8.16.* →</b>
|
||||
<ul>
|
||||
<li>Prima release dotNet 8.0 router</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<div>
|
||||
<div style="float: left;">
|
||||
<img src="logoSteamware.png" />
|
||||
</div>
|
||||
<div style="float: right;">
|
||||
<a href="https://www.steamware.net/IOT" target="_blank">© Steamware 2006-2026</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
@@ -0,0 +1,31 @@
|
||||
<body>
|
||||
<i>Modulo MP-RIOC </i>
|
||||
<h4>Versione: 8.16.2605.812</h4>
|
||||
<br /> Note di rilascio:
|
||||
<ul>
|
||||
<li>
|
||||
<b>Ultime modifiche:</b>
|
||||
<ul>{{LAST-CHANGES}}</ul>
|
||||
</li>
|
||||
<li>
|
||||
<b>v.8.16.* →</b>
|
||||
<ul>
|
||||
<li>Ottimizzazioni varie x Redis</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<b>v.8.16.* →</b>
|
||||
<ul>
|
||||
<li>Prima release dotNet 8.0 router</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<div>
|
||||
<div style="float: left;">
|
||||
<img src="logoSteamware.png" />
|
||||
</div>
|
||||
<div style="float: right;">
|
||||
<a href="https://www.steamware.net/IOT" target="_blank">© Steamware 2006-2026</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
@@ -0,0 +1 @@
|
||||
8.16.2605.812
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.3 KiB |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>1.0.0.0</version>
|
||||
<url>https://nexus.steamware.net/repository/SWS/{{DIRNAME}}/{{BRANCHNAME}}/{{PACKNAME}}.zip</url>
|
||||
<changelog>https://nexus.steamware.net/repository/SWS/{{DIRNAME}}/{{BRANCHNAME}}/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
</item>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>8.16.2605.812</version>
|
||||
<url>https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip</url>
|
||||
<changelog>https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
</item>
|
||||
@@ -0,0 +1,29 @@
|
||||
using MP.Core.DTO;
|
||||
|
||||
namespace MP.RIOC.Services
|
||||
{
|
||||
public interface IWeightProvider
|
||||
{
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Ritorna l'intero elenco dei weight attivi nel formato WeightDTO
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<List<WeightDTO>> GetAllWeightsAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Ritorna la coppia (oldWeight, newWeight) per scegliere dove instradare il metodo tra i 2 sistemi API.
|
||||
/// </summary>
|
||||
(int oldWeight, int newWeight) GetWeightsFor(string method);
|
||||
|
||||
/// <summary>
|
||||
/// Aggiorna/Aggiuinge il valore del weight richiesto
|
||||
/// </summary>
|
||||
/// <param name=""></param>
|
||||
/// <returns></returns>
|
||||
bool UpsertWeight(WeightDTO updRecord);
|
||||
|
||||
#endregion Public Methods
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
using MP.Core.DTO;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace MP.RIOC.Services
|
||||
{
|
||||
public class InMemoryWeightProvider : IWeightProvider
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, (int oldW, int newW)> _map = new();
|
||||
private readonly int _defaultOld;
|
||||
private readonly int _defaultNew;
|
||||
|
||||
public InMemoryWeightProvider(IConfiguration config)
|
||||
{
|
||||
_defaultOld = config.GetValue<int>("RouteMan:DefaultWeightOld", 100);
|
||||
_defaultNew = config.GetValue<int>("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<List<WeightDTO>> GetAllWeightsAsync()
|
||||
{
|
||||
var result = new List<WeightDTO>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<int>("RouteMan:MetricCalcIntervalSeconds", 20);
|
||||
var interval = _config.GetValue<int>("RouteMan:MetricCalcIntervalSeconds", 30);
|
||||
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
+18
-5
@@ -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<int>("RouteMan:MetricFlushIntervalSeconds", 120);
|
||||
var interval = _config.GetValue<int>("RouteMan:MetricFlushIntervalSeconds", 300);
|
||||
var interval = _config.GetValue<int>("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
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-4
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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<int>("RouteMan:DefaultWeightOld", 100);
|
||||
_defaultNew = config.GetValue<int>("RouteMan:DefaultWeightNew", 0);
|
||||
_redisBaseKey = config.GetValue<string>("ServerConf:RedisBaseKey") ?? "MP_IOC";
|
||||
_keyPrefix = $"{_redisBaseKey}:route_weight:";
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Ritorna (oldWeight, newWeight) per il metodo. Se non esiste, crea la chiave con i default.
|
||||
/// </summary>
|
||||
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<List<WeightDTO>> GetAllWeightsAsync()
|
||||
{
|
||||
var result = new List<WeightDTO>();
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -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<string>("ServerConf:RoutePath") ?? "/api/RIOB";
|
||||
_routePath = _config.GetValue<string>("ServerConf:RoutePath") ?? "/api/IOB";
|
||||
_forwarderConfig = new ForwarderRequestConfig
|
||||
{
|
||||
ActivityTimeout = TimeSpan.FromSeconds(30),
|
||||
// Parse della versione (es. "1.1")
|
||||
Version = Version.Parse(_config.GetValue<string>("ServerConf:HttpVersion") ?? "1.1"),
|
||||
// Policy per la versione
|
||||
VersionPolicy = _config.GetValue<HttpVersionPolicy?>("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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<int, long> StatusCodes = new();
|
||||
public TimeSpan AvgDuration => TotalDuration / (Count > 0 ? Count : 1);
|
||||
}
|
||||
|
||||
public class RouteStatsManager
|
||||
@@ -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/"
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
[
|
||||
{
|
||||
"outputFile": "Components/Layout/MainLayout.razor.css",
|
||||
"inputFile": "Components/Layout/MainLayout.razor.less"
|
||||
}
|
||||
]
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"version": 1,
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"dotnet-ef": {
|
||||
"version": "10.0.7",
|
||||
"commands": [
|
||||
"dotnet-ef"
|
||||
],
|
||||
"rollForward": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 = "<Version>(.|\n)*?</Version>";
|
||||
$currRelNum = $MajMin + $currentDate +"." + $currentTime
|
||||
$replace = "<Version>" + $MajMin + $currentDate +"." + $currentTime + "</Version>";
|
||||
$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
|
||||
@@ -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<AppAuthContext> _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<AppAuthContext>()
|
||||
.UseSqlServer(connStr)
|
||||
.Options;
|
||||
|
||||
try
|
||||
{
|
||||
// se non ci fosse... crea o migra!
|
||||
@@ -39,6 +54,7 @@ namespace MP.AppAuth
|
||||
|
||||
public AppAuthContext(DbContextOptions<AppAuthContext> options) : base(options)
|
||||
{
|
||||
_options = options;
|
||||
try
|
||||
{
|
||||
// se non ci fosse... crea o migra!
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Annulla modifiche su una specifica entity (cancel update)
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <returns></returns>
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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<MoonProContext>()
|
||||
.UseSqlServer(connStr)
|
||||
.Options;
|
||||
|
||||
@@ -14,15 +14,6 @@ namespace MP.Data
|
||||
{
|
||||
public static IServiceCollection AddIocDataLayer(this IServiceCollection services)
|
||||
{
|
||||
//// DbContextFactory: preferibile in Blazor Server e scenari concorrenti
|
||||
//services.AddDbContextFactory<DataLayerContext>(options =>
|
||||
// options.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString)));
|
||||
|
||||
//// servizi preliminari
|
||||
////services.TryAddSingleton<IConnectionMultiplexer>(redisConn);
|
||||
//services.TryAddSingleton<IRedisService, RedisService>();
|
||||
//services.TryAddSingleton<IRedisSubscriptionManager, RedisSubscriptionManager>();
|
||||
|
||||
// Repository Singleton
|
||||
services.TryAddSingleton<IMtcSetupRepository, MtcSetupRepository>();
|
||||
|
||||
@@ -40,14 +31,6 @@ namespace MP.Data
|
||||
services.TryAddScoped<IStatsAggrService, StatsAggrService>();
|
||||
services.TryAddScoped<IStatsDetailService, StatsDetailService>();
|
||||
|
||||
//// aggiunta servizi finali Singleton...
|
||||
//services.TryAddSingleton<IImageCacheService, ImageCacheService>();
|
||||
//services.TryAddSingleton<IConfigDataService, ConfigDataService>();
|
||||
//services.TryAddSingleton<ICalcRequestService, CalcRequestService>();
|
||||
//services.TryAddSingleton<IFileService, FileService>();
|
||||
//services.TryAddSingleton<IProdService, ProdService>();
|
||||
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Version>8.16.2605.611</Version>
|
||||
<Version>8.16.2605.811</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -33,8 +33,8 @@
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components" />
|
||||
<PackageReference Include="NLog" />
|
||||
<PackageReference Include="NLog.Web.AspNetCore" />
|
||||
<PackageReference Include="Snappier" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" />
|
||||
<PackageReference Include="Yarp.ReverseProxy" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -48,12 +48,6 @@
|
||||
<None Update="post-build.ps1">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="RedisScript\RedisUpdateScript_v5.lua">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="RedisScript\RedisUpdateScript_v6.lua">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
+1
-82
@@ -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<RedisScriptsConfig>(
|
||||
builder.Configuration.GetSection("RedisScripts"));
|
||||
logger.Info("RedisScript Provider configured");
|
||||
@@ -82,13 +55,6 @@ builder.Services.AddDbContextFactory<MoonPro_UtilsContext>(options =>
|
||||
// MP.Data Services Utils - Statistiche DB
|
||||
builder.Services.AddIocDataLayer();
|
||||
|
||||
// base services
|
||||
builder.Services.AddSingleton<PreserveBodyTransformer>();
|
||||
builder.Services.AddSingleton<RouteStatsManager>();
|
||||
builder.Services.AddHostedService<MetricsCalcService>();
|
||||
builder.Services.AddHostedService<MetricsDbFlushService>();
|
||||
builder.Services.AddSingleton<LuaScriptProvider>();
|
||||
|
||||
// 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<RouteManager>();
|
||||
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<MoonPro_UtilsContext>();
|
||||
context.Database.Migrate();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var migrateLogger = services.GetRequiredService<ILogger<Program>>();
|
||||
migrateLogger.LogError(ex, "Si � verificato un errore durante l'aggiornamento del database.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// aggiunt base URL x routing corretto
|
||||
string baseUrl = configuration.GetValue<string>("ServerConf:BaseUrlIoc") ?? "/MP/";
|
||||
app.UsePathBase(baseUrl);
|
||||
string routePath = configuration.GetValue<string>("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<RouteManager>();
|
||||
await routeManager.HandleAsync(ctx);
|
||||
});
|
||||
});
|
||||
|
||||
logger.Info("App: route Mapped");
|
||||
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
if (app.Environment.IsDevelopment() || app.Environment.IsStaging())
|
||||
|
||||
@@ -25,4 +25,10 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<MsDeploySkipRules Include="SkipLogFiles">
|
||||
<ObjectName>filePath</ObjectName>
|
||||
<AbsolutePath>logs\\.*\.log$</AbsolutePath>
|
||||
</MsDeploySkipRules>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -6,7 +6,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
<PropertyGroup>
|
||||
<TimeStampOfAssociatedLegacyPublishXmlFile />
|
||||
<EncryptedPassword>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAdCoESbxryUqXde3FfEOCTwAAAAACAAAAAAADZgAAwAAAABAAAAAFrH1vByj45Qn06hO/OH6tAAAAAASAAACgAAAAEAAAAIUK5NiEpc4lc11Op6/CLx8YAAAAMecN12fzIN9e3E8R/nu0ATe2PAsMy7M8FAAAAKbUyki2vkSFehjbpB8wCVVVa055</EncryptedPassword>
|
||||
<History>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||;</History>
|
||||
<History>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||;</History>
|
||||
<LastFailureDetails />
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -25,7 +25,7 @@
|
||||
<img src="logoSteamware.png" />
|
||||
</div>
|
||||
<div style="float: right;">
|
||||
<a href="https://www.steamware.net/IOT" target="_blank">© Steamware 2006-2023</a>
|
||||
<a href="https://www.steamware.net/IOT" target="_blank">© Steamware 2006-2026</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
@@ -1,6 +1,6 @@
|
||||
<body>
|
||||
<i>Modulo MP-IOC </i>
|
||||
<h4>Versione: 8.16.2605.611</h4>
|
||||
<h4>Versione: 8.16.2605.811</h4>
|
||||
<br /> Note di rilascio:
|
||||
<ul>
|
||||
<li>
|
||||
@@ -25,7 +25,7 @@
|
||||
<img src="logoSteamware.png" />
|
||||
</div>
|
||||
<div style="float: right;">
|
||||
<a href="https://www.steamware.net/IOT" target="_blank">© Steamware 2006-2023</a>
|
||||
<a href="https://www.steamware.net/IOT" target="_blank">© Steamware 2006-2026</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -1 +1 @@
|
||||
8.16.2605.611
|
||||
8.16.2605.811
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>8.16.2605.611</version>
|
||||
<version>8.16.2605.811</version>
|
||||
<url>https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip</url>
|
||||
<changelog>https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-19
@@ -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,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<RootNamespace>MP.Land</RootNamespace>
|
||||
<Version>8.16.2605.0411</Version>
|
||||
<Version>8.16.2605.0811</Version>
|
||||
<Configurations>Debug;Release;Debug_LiManDebug</Configurations>
|
||||
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
|
||||
<RunAnalyzersDuringBuild>True</RunAnalyzersDuringBuild>
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<body>
|
||||
<i>Modulo Tablet MAPO - DotNet6</i>
|
||||
<h4>Versione: 8.16.2605.0411</h4>
|
||||
<h4>Versione: 8.16.2605.0811</h4>
|
||||
<br />
|
||||
Note di rilascio:
|
||||
<ul>
|
||||
|
||||
@@ -1 +1 @@
|
||||
8.16.2605.0411
|
||||
8.16.2605.0811
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>8.16.2605.0411</version>
|
||||
<version>8.16.2605.0811</version>
|
||||
<url>https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/MP.Land.zip</url>
|
||||
<changelog>https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
|
||||
@@ -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;",
|
||||
|
||||
Reference in New Issue
Block a user