Merge branch 'Release/TestFix_CICD_RIOC_01'
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<RootNamespace>MP.RIOC</RootNamespace>
|
||||
<Version>8.16.2605.812</Version>
|
||||
<Version>8.16.2605.906</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>MP.RIOC Dashboard</title>
|
||||
<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; }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<body>
|
||||
<i>Modulo MP-RIOC </i>
|
||||
<h4>Versione: 8.16.2605.812</h4>
|
||||
<h4>Versione: 8.16.2605.906</h4>
|
||||
<br /> Note di rilascio:
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
@@ -1 +1 @@
|
||||
8.16.2605.812
|
||||
8.16.2605.906
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>8.16.2605.812</version>
|
||||
<version>8.16.2605.906</version>
|
||||
<url>https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/MP.RIOC.zip</url>
|
||||
<changelog>https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
|
||||
@@ -6,13 +6,7 @@ namespace MP.RIOC.Services
|
||||
{
|
||||
public class RouteManager
|
||||
{
|
||||
private readonly IHttpForwarder _forwarder;
|
||||
private readonly HttpMessageInvoker _httpClientInvoker;
|
||||
private readonly PreserveBodyTransformer _transformer;
|
||||
private readonly RouteStatsManager _stats;
|
||||
private readonly IWeightProvider _weightProvider;
|
||||
private readonly IConfiguration _config;
|
||||
private readonly ForwarderRequestConfig _forwarderConfig;
|
||||
#region Public Constructors
|
||||
|
||||
public RouteManager(
|
||||
IHttpForwarder forwarder,
|
||||
@@ -40,59 +34,43 @@ namespace MP.RIOC.Services
|
||||
};
|
||||
}
|
||||
|
||||
private string _routePath = "";
|
||||
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Methods
|
||||
|
||||
public async Task HandleAsync(HttpContext context)
|
||||
{
|
||||
var sw = Stopwatch.StartNew();
|
||||
var routePrefix = new PathString(_routePath);
|
||||
var fullPrefix = context.Request.PathBase.Add(routePrefix);
|
||||
|
||||
string relativePath;
|
||||
string query = context.Request.QueryString.HasValue ? context.Request.QueryString.Value : "";
|
||||
|
||||
if (context.Request.Path.StartsWithSegments(fullPrefix, out var remaining))
|
||||
// 1. ESTRAZIONE PATH SEMPLIFICATA
|
||||
// Se la richiesta è /api/IOB/metodo, 'remaining' sarà /metodo
|
||||
if (!context.Request.Path.StartsWithSegments(routePrefix, out var remaining))
|
||||
{
|
||||
relativePath = remaining.Value.TrimStart('/');
|
||||
}
|
||||
else if (context.Request.Path.StartsWithSegments(routePrefix, out remaining))
|
||||
{
|
||||
relativePath = remaining.Value.TrimStart('/');
|
||||
}
|
||||
else
|
||||
{
|
||||
var fullPath = (context.Request.PathBase + context.Request.Path).Value ?? "";
|
||||
var idx = fullPath.IndexOf("/RIOB/", StringComparison.OrdinalIgnoreCase);
|
||||
relativePath = idx >= 0 ? fullPath[(idx + "/RIOB/".Length)..] : fullPath.TrimStart('/');
|
||||
// Se non inizia con il prefisso, è una chiamata errata al router
|
||||
context.Response.StatusCode = 404;
|
||||
return;
|
||||
}
|
||||
|
||||
Log.Debug($"PathBase={context.Request.PathBase} | Path={context.Request.Path} | relativePath={relativePath}");
|
||||
// Togliamo lo slash iniziale per avere il metodo pulito
|
||||
string relativePath = remaining.Value.TrimStart('/');
|
||||
|
||||
// Procedo a calcolare metodo e ID...
|
||||
// 2. LOGICA METODO / ID (Per statistiche)
|
||||
string metodo = "/";
|
||||
string id = "ALL";
|
||||
if (!string.IsNullOrEmpty(relativePath))
|
||||
{
|
||||
// Rimuovo eventuale query string
|
||||
var pathOnly = relativePath.Split('?')[0];
|
||||
|
||||
// Splitto per /
|
||||
var parts = pathOnly.Split('/', StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
if (parts.Length > 0) metodo = parts[0];
|
||||
if (parts.Length > 1) id = parts[1];
|
||||
}
|
||||
|
||||
Log.Debug($"Metodo: {metodo} | machineId: {id}");
|
||||
|
||||
// 3. DECISIONE TARGET
|
||||
var (oldW, newW) = _weightProvider.GetWeightsFor(metodo);
|
||||
var pickNew = DecideByWeights(oldW, newW);
|
||||
var target = pickNew ? "IOC" : "IO";
|
||||
var targetLabel = pickNew ? "IOC" : "IO";
|
||||
|
||||
// Costruisci destination base in base al target
|
||||
var destBase = pickNew
|
||||
? _config["ServerConf:NewApiUrl"]
|
||||
: _config["ServerConf:OldApiUrl"];
|
||||
@@ -104,25 +82,23 @@ namespace MP.RIOC.Services
|
||||
return;
|
||||
}
|
||||
|
||||
if (!destBase.EndsWith("/")) destBase += "/";
|
||||
// salva path originale per ripristino
|
||||
// 4. PREPARAZIONE FORWARDING
|
||||
var originalPath = context.Request.Path;
|
||||
var originalPathBase = context.Request.PathBase;
|
||||
|
||||
try
|
||||
{
|
||||
string sKey = $"{target}|{metodo}|{id}";
|
||||
|
||||
// Registra scelta
|
||||
string sKey = $"{targetLabel}|{metodo}|{id}";
|
||||
_stats.Record(sKey);
|
||||
|
||||
// imposta la Path che vogliamo che YARP appenda al destBase
|
||||
// Assicuriamoci che la destinazione finisca con / e il path inizi senza /
|
||||
// per evitare il "doppio slash" (es. .../api/IOB//metodo)
|
||||
if (!destBase.EndsWith("/")) destBase += "/";
|
||||
|
||||
context.Request.Path = new PathString("/" + relativePath);
|
||||
// opzionale: se vuoi che PathBase sia vuoto per il backend, impostalo così
|
||||
context.Request.PathBase = PathString.Empty;
|
||||
|
||||
Log.Debug($"Forwarding to base {destBase} with forwarded path {context.Request.Path} | original PathBase:{originalPathBase} | Path={originalPath})");
|
||||
|
||||
// Esecuzione
|
||||
var error = await _forwarder.SendAsync(context, destBase, _httpClientInvoker, _forwarderConfig, _transformer, context.RequestAborted);
|
||||
|
||||
sw.Stop();
|
||||
@@ -131,22 +107,40 @@ namespace MP.RIOC.Services
|
||||
if (error != ForwarderError.None)
|
||||
{
|
||||
var feat = context.GetForwarderErrorFeature();
|
||||
Log.Error(feat?.Exception, "Forwarder error to {DestBase}", destBase);
|
||||
Log.Error(feat?.Exception, "Forwarder error to {DestBase} for {Method}", destBase, metodo);
|
||||
|
||||
if (!context.Response.HasStarted)
|
||||
{
|
||||
context.Response.StatusCode = 502;
|
||||
await context.Response.WriteAsync($"Forward error: {feat?.Exception?.Message}");
|
||||
await context.Response.WriteAsync($"Forward error: {feat?.Exception?.Message ?? error.ToString()}");
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
// ripristina i path originali per non rompere la pipeline successiva
|
||||
context.Request.Path = originalPath;
|
||||
context.Request.PathBase = originalPathBase;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
private readonly IConfiguration _config;
|
||||
private readonly IHttpForwarder _forwarder;
|
||||
private readonly ForwarderRequestConfig _forwarderConfig;
|
||||
private readonly HttpMessageInvoker _httpClientInvoker;
|
||||
private readonly RouteStatsManager _stats;
|
||||
private readonly PreserveBodyTransformer _transformer;
|
||||
private readonly IWeightProvider _weightProvider;
|
||||
private string _routePath = "";
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private bool DecideByWeights(int oldW, int newW)
|
||||
{
|
||||
bool result = false;
|
||||
@@ -163,5 +157,7 @@ namespace MP.RIOC.Services
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,5 @@
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"ServerConf": {
|
||||
"useFactory": false,
|
||||
"OldApiUrl": "http://localhost/MP/IO/IOB/",
|
||||
"NewApiUrl": "http://localhost/MP/IOC/api/IOB/"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,8 +61,8 @@
|
||||
"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/",
|
||||
"OldApiUrl": "https://iis01.egalware.com/MP/IO/IOB/",
|
||||
"NewApiUrl": "https://iis01.egalware.com/MP/IOC/api/IOB/",
|
||||
"BaseUrlIoc": "/MP/RIOC/",
|
||||
"MpIoNS": "MoonPro:SQL2016DEV:MoonPro",
|
||||
"RedisBaseKey": "MP-IOC",
|
||||
|
||||
@@ -21,9 +21,9 @@ 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 "{{DIRNAME}}", "MP-RIOC"
|
||||
$manData = $manData -replace "{{BRANCHNAME}}", "stable/LAST"
|
||||
$manData = $manData -replace "{{PACKNAME}}", "MP.IOC"
|
||||
$manData = $manData -replace "{{PACKNAME}}", "MP.RIOC"
|
||||
Set-Content -Path $FileManOut -Value $manData
|
||||
|
||||
# replace x ChangeLog
|
||||
|
||||
Reference in New Issue
Block a user