using Microsoft.AspNetCore.Http.Extensions; using Microsoft.EntityFrameworkCore; using Microsoft.OpenApi.Models; using MP.Core.Conf; using MP.Data; using MP.IOC.Components; using MP.IOC.Data; using MP.IOC.Services; using NLog; using NLog.Web; using StackExchange.Redis; 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.IOC | 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"); // YARP base config builder.Services.AddReverseProxy().LoadFromConfig(builder.Configuration.GetSection("ReverseProxy")); builder.Services.AddHttpForwarder(); // HttpMessageInvoker (SocketsHttpHandler) builder.Services.AddSingleton(sp => { var handler = new SocketsHttpHandler { AllowAutoRedirect = false, UseCookies = false, PooledConnectionLifetime = TimeSpan.FromMinutes(5), AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }; // Accetta certificati non validi (dev only) handler.SslOptions = new System.Net.Security.SslClientAuthenticationOptions { RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true }; return new HttpMessageInvoker(handler); }); logger.Info("YARP reverse proxy configured"); builder.Services.Configure( builder.Configuration.GetSection("RedisScripts")); logger.Info("RedisScript Provider configured"); // MP.Data Services Utils - Statistiche DB builder.Services.AddIocDataLayer(); // base services builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddHostedService(); builder.Services.AddHostedService(); builder.Services.AddSingleton(); // Registra i servizi per Blazor builder.Services.AddRazorComponents() .AddInteractiveServerComponents(); // Aggiungi Health Checks //builder.Services.AddHealthChecks() // .AddSqlServer(builder.Configuration.GetConnectionString("CoreDb")); // MP.Data DbContext for Stats repositories string utilsConnString = builder.Configuration.GetConnectionString("MP.Utils") ?? "Server=localhost;Database=MoonPro_Utils; integrated security=True; MultipleActiveResultSets=True; App=MP.IOC;"; builder.Services.AddDbContextFactory(options => options.UseSqlServer(utilsConnString)); // generic controller builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); //builder.Services.AddSwaggerGen(); builder.Services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "EgaWare's Mapo Rest API", Version = $"v1 | {assemblyVersion}", Description = $"API documentation for v1 | AssemblyVersion {assemblyVersion}" }); }); // avvio oggetto shared x redis... var redisMux = ConnectionMultiplexer.Connect(confRedis); builder.Services.AddSingleton(redisMux); // oggetto principale accesso dati 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(redisMux); 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"); var app = builder.Build(); // Blocco per la migrazione automatica del DB Utils... using (var scope = app.Services.CreateScope()) { var services = scope.ServiceProvider; try { var context = services.GetRequiredService(); context.Database.Migrate(); } catch (Exception ex) { var migrateLogger = services.GetRequiredService>(); migrateLogger.LogError(ex, "Si � verificato un errore durante l'aggiornamento del database."); } } // aggiunt base URL x routing corretto string baseUrl = configuration.GetValue("ServerConf:BaseUrlIoc") ?? "/MP/"; app.UsePathBase(baseUrl); string routePath = configuration.GetValue("ServerConf:RoutePath") ?? "/api/RIOB"; string fullPath = $"{baseUrl}{routePath}".Replace("//", "/"); logger.Info($"BaseUrl: {baseUrl}"); app.Use(async (ctx, next) => { logger.Debug($"Incoming request PathBase='{ctx.Request.PathBase}' Path='{ctx.Request.Path}' RawTarget='{ctx.Request.GetEncodedUrl()}'"); await next(); }); // parametrizzare?!?!? app.MapWhen(ctx => ctx.Request.Path.StartsWithSegments(fullPath, StringComparison.OrdinalIgnoreCase) || ctx.Request.Path.StartsWithSegments(routePath, StringComparison.OrdinalIgnoreCase) || (ctx.Request.PathBase.HasValue && ctx.Request.Path.StartsWithSegments(routePath, StringComparison.OrdinalIgnoreCase)), builder => { builder.Run(async ctx => { var routeManager = ctx.RequestServices.GetRequiredService(); await routeManager.HandleAsync(ctx); }); }); logger.Info("App: route Mapped"); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment() || app.Environment.IsStaging()) { app.UseSwagger(); //app.UseSwaggerUI(); app.UseSwaggerUI(c => { c.SwaggerEndpoint($"{baseUrl}swagger/v1/swagger.json", "EgalWare's MAPO API v1"); }); } logger.Info("Added swagger"); app.UseHttpsRedirection(); app.UseAuthorization(); // aggiunta x index.html app.UseDefaultFiles(); app.UseStaticFiles(); app.UseAntiforgery(); // Mappatura delle API app.MapControllers(); // Mappatura della Dashboard Blazor app.MapRazorComponents() .AddInteractiveServerRenderMode(); //app.MapHealthChecks("/health"); logger.Info("Run App"); app.Run();