using MP.RIOC.Services; 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"); string redisSrvAddr = confRedis.Substring(0, confRedis.IndexOf(":")); logger.Info("Setup REDIS OK"); // 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(15), // 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(); // 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();