using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; using Serilog; using Yarp.ReverseProxy.Configuration; using Yarp.ReverseProxy.LoadBalancing; using YarpGateway.Config; using YarpGateway.Data; using YarpGateway.DynamicProxy; using YarpGateway.LoadBalancing; using YarpGateway.Middleware; using YarpGateway.Services; using StackExchange.Redis; var builder = WebApplication.CreateBuilder(args); builder.Host.UseSerilog( (context, services, configuration) => configuration .ReadFrom.Configuration(context.Configuration) .ReadFrom.Services(services) .Enrich.FromLogContext() ); builder.Services.Configure(builder.Configuration.GetSection("Jwt")); builder.Services.Configure(builder.Configuration.GetSection("Redis")); builder.Services.AddSingleton(sp => sp.GetRequiredService>().Value); builder.Services.AddDbContextFactory(options => options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")) ); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(sp => { var config = sp.GetRequiredService(); var connectionOptions = ConfigurationOptions.Parse(config.ConnectionString); connectionOptions.AbortOnConnectFail = false; connectionOptions.ConnectRetry = 3; connectionOptions.ConnectTimeout = 5000; connectionOptions.SyncTimeout = 3000; connectionOptions.DefaultDatabase = config.Database; var connection = ConnectionMultiplexer.Connect(connectionOptions); connection.ConnectionFailed += (sender, e) => { Serilog.Log.Error(e.Exception, "Redis connection failed"); }; connection.ConnectionRestored += (sender, e) => { Serilog.Log.Information("Redis connection restored"); }; return connection; }); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(sp => sp.GetRequiredService()); var corsSettings = builder.Configuration.GetSection("Cors"); builder.Services.AddCors(options => { var allowAnyOrigin = corsSettings.GetValue("AllowAnyOrigin"); var allowedOrigins = corsSettings.GetSection("AllowedOrigins").Get() ?? Array.Empty(); options.AddPolicy("AllowFrontend", policy => { if (allowAnyOrigin) { policy.AllowAnyOrigin(); } else { policy.WithOrigins(allowedOrigins); } policy.AllowAnyHeader() .AllowAnyMethod() .AllowCredentials(); }); }); builder.Services.AddControllers(); var app = builder.Build(); app.UseCors("AllowFrontend"); app.UseMiddleware(); app.UseMiddleware(); app.MapControllers(); app.MapReverseProxy(); await app.Services.GetRequiredService().InitializeAsync(); try { Log.Information("Starting YARP Gateway"); app.Run(); } catch (Exception ex) { Log.Fatal(ex, "Application terminated unexpectedly"); } finally { Log.CloseAndFlush(); }