From 585c5c8537eb21dfc9f16108548e63d9ced3d971 Mon Sep 17 00:00:00 2001 From: ivarlovlie Date: Mon, 24 Oct 2022 12:29:23 +0800 Subject: feat: Before move to FastEndpoints --- code/api/src/Program.cs | 379 ++++++++++++++++++++++++------------------------ 1 file changed, 191 insertions(+), 188 deletions(-) (limited to 'code/api/src/Program.cs') diff --git a/code/api/src/Program.cs b/code/api/src/Program.cs index 9a6bc3f..aa7cae3 100644 --- a/code/api/src/Program.cs +++ b/code/api/src/Program.cs @@ -13,10 +13,8 @@ global using System.Text.Json; global using System.Text.Json.Serialization; global using IOL.GreatOffice.Api.Data.Database; global using IOL.GreatOffice.Api.Data.Exceptions; -global using IOL.GreatOffice.Api.Data.Dtos; global using IOL.GreatOffice.Api.Data.Enums; global using IOL.GreatOffice.Api.Data.Models; -global using IOL.GreatOffice.Api.Data.Results; global using IOL.Helpers; global using Microsoft.OpenApi.Models; global using Microsoft.AspNetCore.Authentication.Cookies; @@ -48,189 +46,194 @@ namespace IOL.GreatOffice.Api; public static class Program { - public static WebApplicationBuilder CreateAppBuilder(string[] args) { - var builder = WebApplication.CreateBuilder(args); - builder.Services.AddLogging(); - builder.Services.AddHttpClient(); - builder.Services.AddMemoryCache(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddTransient(); - var vaultService = builder.Services.BuildServiceProvider().GetRequiredService(); - var configuration = vaultService.GetCurrentAppConfiguration(); - var logger = new LoggerConfiguration() - .Enrich.FromLogContext() - .ReadFrom.Configuration(builder.Configuration) - .WriteTo.Console(); - - if (!builder.Environment.IsDevelopment() && configuration.SEQ_API_KEY.HasValue() && configuration.SEQ_API_URL.HasValue()) { - logger.WriteTo.Seq(configuration.SEQ_API_URL, apiKey: configuration.SEQ_API_KEY); - } - - Log.Logger = logger.CreateLogger(); - Log.Information("Starting web host, " - + JsonSerializer.Serialize(configuration.GetPublicVersion(), - new JsonSerializerOptions() { - WriteIndented = true - })); - builder.Host.UseSerilog(Log.Logger); - builder.WebHost.ConfigureKestrel(kestrel => { - kestrel.AddServerHeader = false; - }); - - if (builder.Environment.IsDevelopment()) { - builder.Services.AddCors(); - } - - if (builder.Environment.IsProduction()) { - builder.Services.Configure(options => { - options.ForwardedHeaders = ForwardedHeaders.XForwardedProto; - }); - } - - builder.Services - .AddDataProtection() - .ProtectKeysWithCertificate(configuration.CERT1()) - .PersistKeysToDbContext(); - - builder.Services.Configure(JsonSettings.Default); - builder.Services.AddQuartz(options => { - options.UsePersistentStore(o => { - o.UsePostgres(builder.Configuration.GetQuartzDatabaseConnectionString(vaultService.GetCurrentAppConfiguration)); - o.UseSerializer(); - }); - options.UseMicrosoftDependencyInjectionJobFactory(); - options.RegisterJobs(); - }); - - builder.Services.AddQuartzHostedService(options => { - options.WaitForJobsToComplete = true; - }); - - builder.Services.AddAuthentication(options => { - options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; - options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme; - }) - .AddCookie(options => { - options.Cookie.Name = "go_session"; - options.Cookie.HttpOnly = true; - options.Cookie.IsEssential = true; - options.SlidingExpiration = true; - options.Events.OnRedirectToAccessDenied = - options.Events.OnRedirectToLogin = c => { - c.Response.StatusCode = StatusCodes.Status401Unauthorized; - return Task.FromResult(null); - }; - }) - .AddScheme(AppConstants.BASIC_AUTH_SCHEME, default); - - builder.Services.AddDbContext(options => { - options.UseNpgsql(builder.Configuration.GetAppDatabaseConnectionString(vaultService.GetCurrentAppConfiguration), - npgsqlDbContextOptionsBuilder => { - npgsqlDbContextOptionsBuilder.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery); - npgsqlDbContextOptionsBuilder.EnableRetryOnFailure(5, TimeSpan.FromSeconds(10), default); - }) - .UseSnakeCaseNamingConvention(); - if (builder.Environment.IsDevelopment()) { - options.EnableSensitiveDataLogging(); - } - }); - - builder.Services.AddApiVersioning(options => { - options.ApiVersionReader = new UrlSegmentApiVersionReader(); - options.ReportApiVersions = true; - options.AssumeDefaultVersionWhenUnspecified = false; - }); - builder.Services.AddVersionedApiExplorer(options => { - options.SubstituteApiVersionInUrl = true; - }); - builder.Services.AddSwaggerGen(options => { - options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, Assembly.GetExecutingAssembly().GetName().Name + ".xml")); - options.UseApiEndpoints(); - options.OperationFilter(); - options.SwaggerDoc(ApiSpecV1.Document.VersionName, ApiSpecV1.Document.OpenApiInfo); - options.AddSecurityDefinition("Basic", - new OpenApiSecurityScheme { - Name = "Authorization", - Type = SecuritySchemeType.ApiKey, - Scheme = "Basic", - BearerFormat = "Basic", - In = ParameterLocation.Header, - Description = - "Enter your token in the text input below.\r\n\r\nExample: \"Basic 12345abcdef\"", - }); - - options.AddSecurityRequirement(new OpenApiSecurityRequirement { - { - new OpenApiSecurityScheme { - Reference = new OpenApiReference { - Type = ReferenceType.SecurityScheme, - Id = "Basic" - } - }, - Array.Empty() - } - }); - }); - - builder.Services - .AddControllers() - .AddJsonOptions(JsonSettings.Default); - - return builder; - } - - public static WebApplication CreateWebApplication(WebApplicationBuilder builder) { - var app = builder.Build(); - - if (app.Environment.IsDevelopment()) { - app.UseDeveloperExceptionPage(); - app.UseCors(cors => { - cors.AllowAnyMethod(); - cors.AllowAnyHeader(); - cors.SetIsOriginAllowed((origin) => true); - cors.AllowCredentials(); - }); - } - - if (app.Environment.IsProduction()) { - app.UseForwardedHeaders(); - } - - app.UseDefaultFiles() - .UseStaticFiles() - .UseRouting() - .UseSerilogRequestLogging() - .UseStatusCodePages() - .UseAuthentication() - .UseAuthorization() - .UseSwagger() - .UseSwaggerUI(options => { - options.SwaggerEndpoint(ApiSpecV1.Document.SwaggerPath, ApiSpecV1.Document.VersionName); - options.DocumentTitle = AppConstants.API_NAME; - }) - .UseEndpoints(endpoints => { - endpoints.MapControllers(); - }); - return app; - } - - public static int Main(string[] args) { - try { - CreateWebApplication(CreateAppBuilder(args)).Run(); - return 0; - } catch (Exception ex) { - // This is subject to change in future .net versions, see https://github.com/dotnet/runtime/issues/60600. - if (ex.GetType().Name.Equals("StopTheHostException", StringComparison.Ordinal)) { - throw; - } - - Log.Fatal(ex, "Unhandled exception"); - return 1; - } finally { - Log.Information("Shut down complete, flusing logs..."); - Log.CloseAndFlush(); - } - } -} + public static WebApplicationBuilder CreateAppBuilder(string[] args) { + var builder = WebApplication.CreateBuilder(args); + builder.Services.AddLogging(); + builder.Services.AddHttpClient(); + builder.Services.AddMemoryCache(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddTransient(); + var vaultService = builder.Services.BuildServiceProvider().GetRequiredService(); + var configuration = vaultService.GetCurrentAppConfiguration(); + var logger = new LoggerConfiguration() + .Enrich.FromLogContext() + .ReadFrom.Configuration(builder.Configuration) + .WriteTo.Console(); + + if (!builder.Environment.IsDevelopment() && configuration.SEQ_API_KEY.HasValue() && configuration.SEQ_API_URL.HasValue()) { + logger.WriteTo.Seq(configuration.SEQ_API_URL, apiKey: configuration.SEQ_API_KEY); + } + + Log.Logger = logger.CreateLogger(); + Log.Information("Starting web host, " + + JsonSerializer.Serialize(configuration.GetPublicVersion(), + new JsonSerializerOptions() { + WriteIndented = true + })); + builder.Host.UseSerilog(Log.Logger); + builder.WebHost.ConfigureKestrel(kestrel => { kestrel.AddServerHeader = false; }); + + if (builder.Environment.IsDevelopment()) { + builder.Services.AddCors(); + } + + if (builder.Environment.IsProduction()) { + builder.Services.Configure(options => { options.ForwardedHeaders = ForwardedHeaders.XForwardedProto; }); + } + + builder.Services.AddLocalization(options => { + options.ResourcesPath = "Resources"; + }); + builder.Services.AddRequestLocalization(options => { + var supportedCultures = new[] {"en-gb", "no-nb"}; + options.SetDefaultCulture(supportedCultures[0]) + .AddSupportedCultures(supportedCultures) + .AddSupportedUICultures(supportedCultures); + options.ApplyCurrentCultureToResponseHeaders = true; + }); + + builder.Services + .AddDataProtection() + .ProtectKeysWithCertificate(configuration.CERT1()) + .PersistKeysToDbContext(); + + builder.Services.Configure(JsonSettings.Default); + builder.Services.AddQuartz(options => { + options.UsePersistentStore(o => { + o.UsePostgres(builder.Configuration.GetQuartzDatabaseConnectionString(vaultService.GetCurrentAppConfiguration)); + o.UseSerializer(); + }); + options.UseMicrosoftDependencyInjectionJobFactory(); + options.RegisterJobs(); + }); + + builder.Services.AddQuartzHostedService(options => { options.WaitForJobsToComplete = true; }); + + builder.Services.AddAuthentication(options => { + options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; + options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme; + }) + .AddCookie(options => { + options.Cookie.Name = "go_session"; + options.Cookie.HttpOnly = true; + options.Cookie.IsEssential = true; + options.SlidingExpiration = true; + options.Events.OnRedirectToAccessDenied = + options.Events.OnRedirectToLogin = c => { + c.Response.StatusCode = StatusCodes.Status401Unauthorized; + return Task.FromResult(null); + }; + }) + .AddScheme(AppConstants.BASIC_AUTH_SCHEME, default); + + builder.Services.AddDbContext(options => { + options.UseNpgsql(builder.Configuration.GetAppDatabaseConnectionString(vaultService.GetCurrentAppConfiguration), + npgsqlDbContextOptionsBuilder => { + npgsqlDbContextOptionsBuilder.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery); + npgsqlDbContextOptionsBuilder.EnableRetryOnFailure(5, TimeSpan.FromSeconds(10), default); + }) + .UseSnakeCaseNamingConvention(); + if (builder.Environment.IsDevelopment()) { + options.EnableSensitiveDataLogging(); + } + }); + + builder.Services.AddApiVersioning(options => { + options.ApiVersionReader = new UrlSegmentApiVersionReader(); + options.ReportApiVersions = true; + options.AssumeDefaultVersionWhenUnspecified = false; + }); + builder.Services.AddVersionedApiExplorer(options => { options.SubstituteApiVersionInUrl = true; }); + builder.Services.AddSwaggerGen(options => { + options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, Assembly.GetExecutingAssembly().GetName().Name + ".xml")); + options.UseApiEndpoints(); + options.OperationFilter(); + options.SwaggerDoc(ApiSpecV1.Document.VersionName, ApiSpecV1.Document.OpenApiInfo); + options.AddSecurityDefinition("Basic", + new OpenApiSecurityScheme { + Name = "Authorization", + Type = SecuritySchemeType.ApiKey, + Scheme = "Basic", + BearerFormat = "Basic", + In = ParameterLocation.Header, + Description = + "Enter your token in the text input below.\r\n\r\nExample: \"Basic 12345abcdef\"", + }); + + options.AddSecurityRequirement(new OpenApiSecurityRequirement { + { + new OpenApiSecurityScheme { + Reference = new OpenApiReference { + Type = ReferenceType.SecurityScheme, + Id = "Basic" + } + }, + Array.Empty() + } + }); + }); + + builder.Services + .AddControllers() + .AddDataAnnotationsLocalization() + .AddJsonOptions(JsonSettings.Default); + + return builder; + } + + public static WebApplication CreateWebApplication(WebApplicationBuilder builder) { + var app = builder.Build(); + + if (app.Environment.IsDevelopment()) { + app.UseDeveloperExceptionPage(); + app.UseCors(cors => { + cors.AllowAnyMethod(); + cors.AllowAnyHeader(); + cors.SetIsOriginAllowed(_ => true); + cors.AllowCredentials(); + }); + } + + if (app.Environment.IsProduction()) { + app.UseForwardedHeaders(); + } + + + app.UseDefaultFiles() + .UseStaticFiles() + .UseRequestLocalization() + .UseRouting() + .UseSerilogRequestLogging() + .UseStatusCodePages() + .UseAuthentication() + .UseAuthorization() + .UseSwagger() + .UseSwaggerUI(options => { + options.SwaggerEndpoint(ApiSpecV1.Document.SwaggerPath, ApiSpecV1.Document.VersionName); + options.DocumentTitle = AppConstants.API_NAME; + }) + .UseEndpoints(endpoints => { endpoints.MapControllers(); }); + return app; + } + + public static int Main(string[] args) { + try { + CreateWebApplication(CreateAppBuilder(args)).Run(); + return 0; + } catch (Exception ex) { + // This is subject to change in future .net versions, see https://github.com/dotnet/runtime/issues/60600. + if (ex.GetType().Name.Equals("StopTheHostException", StringComparison.Ordinal)) { + throw; + } + + Log.Fatal(ex, "Unhandled exception"); + return 1; + } + finally { + Log.Information("Shut down complete, flusing logs..."); + Log.CloseAndFlush(); + } + } +} \ No newline at end of file -- cgit v1.3