Files
2026-02-25 19:40:38 +01:00

254 lines
9.2 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Microsoft.AspNetCore.Authentication.Negotiate;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.FileProviders;
using Microsoft.JSInterop;
using MP.AppAuth.Services;
using MP.Data.Services;
using MP.SPEC.Components;
using MP.SPEC.Data;
using MP.SPEC.Services;
using NLog;
using NLog.Targets;
using NLog.Targets.OpenTelemetryProtocol;
using NLog.Web;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
using StackExchange.Redis;
var builder = WebApplication.CreateBuilder(args);
/*--------------------
* Note migrazione startup.cs --> program.cs:
*
* - https://stackoverflow.com/questions/69722872/asp-net-core-6-how-to-access-ConfMan-during-startup
* - https://docs.microsoft.com/en-us/aspnet/core/migration/50-to-60?view=aspnetcore-5.0&tabs=visual-studio#where-do-i-put-state-that-was-stored-as-fields-in-my-program-or-startup-class
*
* */
ConfigurationManager configuration = builder.Configuration;
var logger = LogManager.Setup()
.LoadConfigurationFromAppSettings()
.GetCurrentClassLogger();
logger.Info("Program.cs: startup");
// REDIS setup
logger.Info("Setup REDIS");
string connStringRedis = configuration.GetConnectionString("Redis") ?? "localhost:6379";
//string connStringRedis = ConfMan.GetConnectionString("RedisAdmin");
string redisSrvAddr = connStringRedis.Substring(0, connStringRedis.IndexOf(":"));
// avvio oggetto shared x redis...
var redisMultiplexer = ConnectionMultiplexer.Connect(connStringRedis);
// ====================================================================
// Setup Tracing e Telemetria...
// ====================================================================
// 1. Leggiamo la configurazione
var otelEnabled = builder.Configuration.GetValue<bool>("Otel:EnableTracing", false);
var otelEndpoint = builder.Configuration["Otel:Endpoint"];
var otelDsn = builder.Configuration["Otel:Dsn"];
if (otelEnabled)
{
// ====================================================================
// SETUP OPENTELEMETRY BASE (Genera gli oggetti Activity)
// Questo gira per i Livelli 1, 2 e 3.
// ====================================================================
var appVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? "1.0.0";
builder.Services.AddOpenTelemetry()
.WithTracing(tracerProviderBuilder =>
{
tracerProviderBuilder
.SetResourceBuilder(OpenTelemetry.Resources.ResourceBuilder.CreateDefault()
.AddService(serviceName: "MAPO.SPEC", serviceVersion: appVersion))
.AddSource("MP.DATA.Tracer")
.AddAspNetCoreInstrumentation(options => { options.Filter = ctx => !ctx.Request.Path.StartsWithSegments("/health"); })
.AddSqlClientInstrumentation(options => { options.RecordException = true; })
.AddRedisInstrumentation(redisMultiplexer);
// ====================================================================
// ESPORTAZIONE DI RETE (Solo Livelli 1 e 2)
// ====================================================================
if (!string.IsNullOrWhiteSpace(otelEndpoint))
{
tracerProviderBuilder.AddOtlpExporter(options =>
{
options.Endpoint = new Uri(otelEndpoint);
if (!string.IsNullOrWhiteSpace(otelDsn))
{
options.Headers = $"uptrace-dsn={otelDsn}";
}
options.Protocol = OpenTelemetry.Exporter.OtlpExportProtocol.Grpc;
});
}
// Se otelEndpoint è vuoto (Livello 3), le tracce nascono e muoiono in RAM.
});
// ====================================================================
// ESPORTAZIONE NLOG REALTIME (Solo Livelli 1 e 2)
// ====================================================================
if (!string.IsNullOrWhiteSpace(otelEndpoint))
{
var otlpTarget = new OtlpTarget
{
Name = "UptraceRealtime",
Endpoint = otelEndpoint,
ServiceName = "MP.DATA.Tracer"
};
if (!string.IsNullOrWhiteSpace(otelDsn))
{
otlpTarget.Headers = $"uptrace-dsn={otelDsn}";
}
var config = LogManager.Configuration ?? new NLog.Config.LoggingConfiguration();
config.AddTarget(otlpTarget);
config.AddRule(NLog.LogLevel.Info, NLog.LogLevel.Fatal, otlpTarget);
LogManager.Configuration = config;
LogManager.ReconfigExistingLoggers();
logger.Info($"🚀 NLog & OTel attivi e in invio verso: {otelEndpoint}");
}
else
{
logger.Info("️ OTel attivo (Local mode). Esportazione di rete disabilitata.");
}
}
else
{
// ====================================================================
// LIVELLO 4: TUTTO SPENTO
// ====================================================================
logger.Info("⏸️ Telemetria e Tracing completamente disabilitati.");
}
// Add services to the container.
logger.Info("Setup Auth");
builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
.AddNegotiate();
builder.Services.AddAuthorization(options =>
{
// By default, all incoming requests will be authorized according to the default policy.
options.FallbackPolicy = options.DefaultPolicy;
});
// redis replliminare
builder.Services.AddSingleton<IConnectionMultiplexer>(redisMultiplexer);
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton<MpDataService>();
builder.Services.AddSingleton<ListSelectDataSrv>();
builder.Services.AddSingleton<IOApiService>();
builder.Services.AddSingleton<AppAuthService>();
builder.Services.AddScoped<MsgServiceSpec>();
builder.Services.AddSingleton<SharedMemService>();
builder.Services.AddSingleton<TabDataService>();
builder.Services.AddSingleton<TabDataFeeder>();
#if false
builder.Services.AddBlazoredLocalStorage();
builder.Services.AddBlazoredSessionStorage();
#endif
// aggiunta helper local/session storage service
builder.Services.AddScoped<ISessionStorageService, SessionStorageService>();
builder.Services.AddScoped<ILocalStorageService, LocalStorageService>();
//builder.Services.AddScoped<SessionStorageService>();
//builder.Services.AddScoped<LocalStorageService>();
//builder.Services.AddScoped<ISessionStorageService>(sp =>
// new SessionStorageService(sp.GetRequiredService<IJSRuntime>()));
//builder.Services.AddScoped<ILocalStorageService>(sp =>
// new LocalStorageService(sp.GetRequiredService<IJSRuntime>()));
builder.Services.AddHttpClient();
logger.Info("Aggiunti services");
var app = builder.Build();
logger.Info("Build App");
// aggiunt base URL x routing corretto
app.UsePathBase(configuration.GetValue<string>("SpecialConf:AppUrl"));
// 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();
// gestione static files: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/static-files?view=aspnetcore-8.0
string BasePathOdlReturn = configuration.GetValue<string>("ServerConf:BasePathOdlReturn") ?? configuration.GetValue<string>("OptConf:BasePathOdlReturn") ?? "";
if (!string.IsNullOrEmpty(BasePathOdlReturn))
{
// preparo mappings opzionali se presenti in conf...
var provider = new FileExtensionContentTypeProvider();
// vedere https://code-maze.com/dotnet-appsettings-json-content-to-dictionary/
var mimeSection = configuration.GetSection("ServerConf:MimeMappings");
if (mimeSection != null)
{
var mimeDict = mimeSection
.AsEnumerable()
.Where(x => !string.IsNullOrWhiteSpace(x.Value))
.ToDictionary(x => x.Key.Replace("ServerConf:MimeMappings:", ""), x => x.Value);
// se ne ho trovati
if (mimeDict != null && mimeDict.Count > 0)
{
// li aggiungo! vedere
// https://thechrisgreen.com/2022/05/add-a-mime-type-to-an-asp-net-core-net-6-app/
// https://harrybellamy.com/posts/getting-mime-types-from-file-extensions-in-net-core/
foreach (var item in mimeDict)
{
// Add new mappings
provider.Mappings[item.Key] = item.Value;
}
}
}
// verifico esista folder
if (Directory.Exists(BasePathOdlReturn))
{
// gestione cartella x file ritornati x ODL
app.UseStaticFiles(new StaticFileOptions
{
ContentTypeProvider = provider,
FileProvider = new PhysicalFileProvider(BasePathOdlReturn),
RequestPath = "/RET_DATA",
});
}
}
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
//app.MapBlazorHub();
//app.MapFallbackToPage("/_Host");
logger.Info("Run App");
app.Run();