using FluentStorage; using FluentValidation; using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.HttpOverrides; using Microsoft.AspNetCore.Localization; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Diagnostics; using MudBlazor.Services; using Serilog; using Serilog.Extensions.Logging; using Somnia.GuestLog; using Somnia.GuestLog.Components; using Somnia.GuestLog.Infrastructure; using Somnia.GuestLog.Models.Configuration; using Somnia.GuestLog.Models.DTOs; using Somnia.GuestLog.Services; using Somnia.GuestLog.Services.AddressQuery; using Somnia.GuestLog.Services.Entity; using Somnia.GuestLog.Services.SpainCodigoMunicipio; using Somnia.GuestLog.Services.StayExport; using Somnia.GuestLog.Utils; using Somnia.GuestLog.Validators; var builder = WebApplication.CreateBuilder(args); //Load config files. builder.Configuration.AddJsonFile("Config/log_Config.json", optional: false, reloadOnChange: false); builder.Configuration.AddEnvironmentVariables("SOMNIA_"); //Create and configure Logger (Serilog) var serilog = new LoggerConfiguration() .ReadFrom.Configuration(builder.Configuration) .CreateLogger(); builder.Services.AddSerilog(serilog); var logger = new SerilogLoggerFactory(serilog).CreateLogger(); logger.LogInformation("\n\n\n -------------- Starting {appName} {appVersion} --------------", AppSettings.AppName, AppSettings.AppVersion); if (!builder.Environment.IsDevelopment()) { string dataProtectionPath = builder.Configuration.GetValue("DataProtectionDir", defaultValue: "/SomniaGuestLog/dataprotection"); builder.Services.AddDataProtection() .PersistKeysToFileSystem(new DirectoryInfo(dataProtectionPath)) .SetApplicationName("SomniaGuestLog"); } builder.Services.Configure(options => { options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost; }); var connectionStringGuestLog = builder.Configuration.GetConnectionString("DbSomniaGuestLog") ?? throw new InvalidOperationException("Connection string 'DbSomniaGuestLog' not found."); builder.Services.AddDbContextFactory(options => { options.UseNpgsql(connectionStringGuestLog) .UseLazyLoadingProxies() .ConfigureWarnings(w => w.Log((CoreEventId.NavigationLazyLoading, LogLevel.Warning))); // The following options help with debugging, but should // be changed or removed for production. if (builder.Environment.IsDevelopment()) { options.EnableSensitiveDataLogging() .EnableDetailedErrors(); } }); builder.Services.AddDatabaseDeveloperPageExceptionFilter(); // Add MudBlazor services builder.Services.AddMudServices(c => { c.SnackbarConfiguration.PositionClass = MudBlazor.Defaults.Classes.Position.TopCenter; c.SnackbarConfiguration.ShowTransitionDuration = 300; c.SnackbarConfiguration.HideTransitionDuration = 500; c.SnackbarConfiguration.VisibleStateDuration = 10000; }); // Add components services to the container. builder.Services.AddRazorComponents() .AddInteractiveServerComponents(); builder.Services.AddLocalization(); builder.Services.AddHttpClient(); // Add Validation Services builder.Services.AddSingleton, GuestDocumentDTOValidator>(); builder.Services.AddSingleton, GuestDocIdDTOValidator>(); builder.Services.AddSingleton, StayEntryDTOValidator>(); builder.Services.AddSingleton, StayExportParamsDTOValidator>(); // Add Entity Services builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); // Add Services builder.Services.AddSingleton(); builder.Services.AddScoped(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); // Add Factories (and it's services) builder.Services.AddFactoryDI(); builder.Services.AddFactoryDI(); // Add Options config builder.Services.AddOptions() .Bind(builder.Configuration.GetSection(AddressQueryConfig.SectionName)); builder.Services.AddOptions() .Bind(builder.Configuration.GetSection(StayExportConfig.SectionName)); builder.Services.AddOptions() .Bind(builder.Configuration.GetSection(StayExportSpainParteViajerosConfig.SectionName)); var app = builder.Build(); app.UseForwardedHeaders(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseMigrationsEndPoint(); } else { app.UseExceptionHandler("/Error", createScopeForErrors: true); // 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.UseStatusCodePagesWithReExecute("/not-found", createScopeForStatusCodePages: true); app.UseHttpsRedirection(); app.UseAntiforgery(); string[] supportedCultures = ["en-US", "es-ES"]; var localizationOptions = new RequestLocalizationOptions() .SetDefaultCulture(supportedCultures[0]) .AddSupportedCultures(supportedCultures) .AddSupportedUICultures(supportedCultures); localizationOptions.RequestCultureProviders = [ new QueryStringRequestCultureProvider(), new CookieRequestCultureProvider() ]; app.UseRequestLocalization(localizationOptions); app.MapStaticAssets(); app.MapRazorComponents() .AddInteractiveServerRenderMode(); //Activate S3 storage. AwsS3Storage.Use(); //Run database migrations bool runMigrationsOnStartup = builder.Configuration.GetValue("RunDatabaseMigrationOnStartup", defaultValue: true); if (runMigrationsOnStartup) { logger.LogInformation("Running database migrations..."); using var scope = app.Services.CreateScope(); var db = scope.ServiceProvider.GetRequiredService(); await db.Database.MigrateAsync(); logger.LogInformation("Database migrations OK"); } app.Run();