using Blazored.LocalStorage; using Blazored.SessionStorage; using HealthChecks.UI.Client; using MagMan.Core; using MagMan.Core.Services; using MagMan.Data; using MagMan.Data.Admin; using MagMan.Data.Admin.Services; using MagMan.Data.Tenant; using MagMan.Data.Tenant.Services; using MagMan.UI.Areas.Identity; using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Diagnostics.HealthChecks; using Microsoft.AspNetCore.HttpOverrides; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Localization; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Diagnostics.HealthChecks; using StackExchange.Redis; using System.Globalization; var builder = WebApplication.CreateBuilder(args); // REDIS setup var redisConnString = builder.Configuration.GetConnectionString("Redis"); string connStringRedis = redisConnString ?? "localhost:6379, DefaultDatabase=14, connectTimeout=5000, syncTimeout=5000, asyncTimeout=5000, abortConnect=false, ssl=false"; string redisSrvAddr = "127.0.0.1"; if (connStringRedis.IndexOf(":") >= 0) { redisSrvAddr = connStringRedis.Substring(0, connStringRedis.IndexOf(":")); } // avvio oggetto shared x redis... var redisMultiplexer = ConnectionMultiplexer.Connect(connStringRedis); // Add services x accesso dati builder.Services.AddSingleton(redisMultiplexer); // init info x DB string dbServerAddr = builder.Configuration["DbConfig:Server"]; string nKey = builder.Configuration["DbConfig:nKey"]; string sKey = builder.Configuration["DbConfig:sKey"]; MagMan.Data.Admin.DbConfig.InitDb(dbServerAddr); string admConnStr = MagMan.Data.Admin.DbConfig.CONNECTION_STRING; // inizializzo il DB e creo (se necessario) l'utente MagMan.Data.Admin.DbConfig.CheckUser(nKey, sKey); // migrazione Db x gestione multitenant MagMan.Data.Admin.DbConfig.ExecMigrationMultiTenant(); string connStringDB = MagMan.Data.Admin.DbConfig.CONNECTION_STRING; /* * Healthchecks * vedere qui: https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks?tab=readme-ov-file * * bug aperto: https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/issues/410, tamponato con conf su kestrel.service: specificato localhost/ip reale prima della porta.. * * ExecStart=/usr/bin/dotnet /var/www/magman/MagMan.UI.dll --urls "http://10.74.82.92:5005" * * */ // abilitazione blobale healthCheck... bool enabHealth = builder.Configuration.GetValue("OptConf:EnableHealth"); if (enabHealth) { builder.Services.AddHealthChecks() .AddMySql(connStringDB, "MySql instance") .AddAsyncCheck($"DB PING ({dbServerAddr})", () => MagMan.UI.Health.Checks.PingCheck(dbServerAddr)) .AddAsyncCheck($"Redis PING ({redisSrvAddr})", () => MagMan.UI.Health.Checks.PingCheck(redisSrvAddr)) // 512 MB max allocated memory .AddProcessAllocatedMemoryHealthCheck(512, "Max Process memory (<512MB)", failureStatus: HealthStatus.Degraded) // 2025.09.23 problemi con sentinel... commentato! //.AddRedis(connStringRedis, "Redis", failureStatus: HealthStatus.Degraded) //.AddRedis(builder.Configuration.GetConnectionString("Redis"), "Redis", failureStatus: HealthStatus.Degraded) .AddAsyncCheck($"MySql Identity", () => MagMan.UI.Health.Checks.DbIdentity(MagMan.Data.Admin.DbConfig.DATABASE_NAME)) .AddAsyncCheck($"MySql Customers", () => MagMan.UI.Health.Checks.CustomersCount()) ; builder.Services.AddHealthChecksUI(s => { s.AddHealthCheckEndpoint("MagMan_Services", "health"); s.SetEvaluationTimeInSeconds(60); s.SetMinimumSecondsBetweenFailureNotifications(120); s.SetApiMaxActiveRequests(5); s.SetHeaderText("MagMan Health Check Status"); }) .AddInMemoryStorage(); } // cookie applicazione da 14 gg (defaul) a 30 builder.Services.ConfigureApplicationCookie(o => { o.ExpireTimeSpan = TimeSpan.FromDays(30); o.SlidingExpiration = true; }); // token di sicurezza dati a 3h builder.Services.Configure(o => o.TokenLifespan = TimeSpan.FromHours(3)); // setup MySql var serverVersion = MagMan.Data.Admin.DbConfig.MysqlServerVersion(admConnStr); builder.Services.AddDbContext(options => options.UseMySql(connStringDB, serverVersion)); builder.Services.AddDefaultIdentity(options => options.SignIn.RequireConfirmedAccount = true) .AddRoles() .AddEntityFrameworkStores(); // Add services to the container. builder.Services.AddRazorPages(); builder.Services.AddServerSideBlazor(); // servizi dati builder.Services.AddSingleton(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddBlazoredLocalStorage(); builder.Services.AddBlazoredSessionStorage(); // gestione email builder.Services.Configure(builder.Configuration.GetSection(nameof(MailKitMailSettings))); builder.Services.AddScoped(); builder.Services.AddHttpContextAccessor(); // servizi auth builder.Services.AddScoped>(); #if false builder.Services.AddDatabaseDeveloperPageExceptionFilter(); # endif builder.Services.AddSingleton(builder.Configuration); var app = builder.Build(); // aggiunt base URL x routing corretto app.UsePathBase(builder.Configuration["OptConf:BaseUrl"]); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); // cultura IT... var supportedCultures = new[]{ new CultureInfo("it-IT") }; app.UseRequestLocalization(new RequestLocalizationOptions { DefaultRequestCulture = new RequestCulture("it-IT"), SupportedCultures = supportedCultures, FallBackToParentCultures = false }); CultureInfo.DefaultThreadCurrentCulture = CultureInfo.CreateSpecificCulture("it-IT"); // fix forwarders app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto }); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); endpoints.MapBlazorHub(); if (enabHealth) { endpoints.MapHealthChecksUI(); endpoints.MapHealthChecks("/health", new HealthCheckOptions { Predicate = _ => true, ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse }); } endpoints.MapFallbackToPage("/_Host"); }); app.Run();