using ReserveManagementSystemApi.Services; using ReserveManagementSystemApi.HostedService; using ReserveManagementSystemApi.ServiceClients; using ReserveManagementSystemApi.Configurations; using ReserveManagementSystemLib.Configuration; using ReserveManagementSystemLib.Persistence; using ReserveManagementSystemLib.Repositories; using MassTransit; using Microsoft.OpenApi.Models; using Microsoft.Extensions.FileProviders; using Newtonsoft.Json; using LCU.Library.Internal.LcuHttpClient; using LCU.Library.Internal.ApiSecurity; using LCU.Library.Internal.Logging.Models; using LCU.Library.Internal.Logging; using LCU.Library.Internal.Logging.Middleware; using LCU.Library.Internal.Configuration; using LCU.Library.Internal.LcuMassTransit; using LCU.Library.Internal.LcuMassTransitModels; using ReserveManagementSystemApi.Consumers; using ReserveManagementSystemApi.Services.QueueServices; using LCU.Library.Internal.Status; namespace ReserveManagementSystemApi { public class Program { public static string MyAllowSpecificOrigins { get; private set; } static void Main(string[] args) { MyAllowSpecificOrigins = "_myAllowSpecificOrigins"; WebApplicationBuilder builder = BuildBuilder(args); BuildServicesAndConfigurations(builder); BuildAppAndRun(builder); } public static WebApplicationBuilder BuildBuilder(string[] args) { var builder = WebApplication.CreateBuilder(args); builder.Configuration.AddJsonFile("/app/config/environment-appsettings/appsettings.json", true, true); builder.Configuration.AddJsonFile("/app/config/workload-appsettings/appsettings.json", true, true); builder.Configuration.AddJsonFile("/vault/secrets/reserve-management-system-seq-api-key.json", true, true); builder.Configuration.AddJsonFile("/vault/secrets/reserve-management-system-rms-database-connection.json", true, true); builder.Configuration.AddJsonFile("/vault/secrets/reserve-management-system-connection-configuration-queue-username.json", true, true); builder.Configuration.AddJsonFile("/vault/secrets/reserve-management-system-connection-configuration-queue-password.json", true, true); builder.Configuration.AddJsonFile("/vault/secrets/reserve-management-system-api-security-configuration-internal-api-key-set.json", true, true); builder.Host.UseSerilog(); return builder; } public static void BuildServicesAndConfigurations(WebApplicationBuilder builder) { var services = builder.Services; var configuration = builder.Configuration; services.AddControllers(); services.AddEndpointsApiExplorer(); services.AddLCUHttpServices(); var apiConfiguration = configuration.Bind(services, "Primary"); services.AddCors(options => { options.AddPolicy(MyAllowSpecificOrigins, builder => { builder.WithOrigins(apiConfiguration.CorsAllowedOrigins).AllowAnyHeader() .AllowAnyMethod(); }); }); services.AddDbContext(options => { options.UseSqlServer(configuration.GetSection("SqlConnectionConfiguration").GetSection("ConnectionString").Value); }); var connectionConfiguration = MassTransitConfigurationSetUp.AddConnectionConfiguration(ref services, configuration); Log.Debug(JsonConvert.SerializeObject(connectionConfiguration)); var receiveEndpointConfigurations = new ReceiveEndpointConfigurations() { RmsActiveLoanReceiveEndpoint = MassTransitConfigurationSetUp.GetReceiveEndpointConfiguration(configuration, "RmsActiveLoanReceiveEndpoint") }; services.AddSingleton(receiveEndpointConfigurations); Log.Debug(JsonConvert.SerializeObject(receiveEndpointConfigurations)); AddMassTransitServices(ref services, connectionConfiguration, receiveEndpointConfigurations, apiConfiguration); AddQueueServices(services); var loggerConfiguration = new LoggingConfiguration(apiConfiguration.AppName, apiConfiguration.SeqApiKey, apiConfiguration.SeqUrl); var lcuLogging = new LcuLogging(loggerConfiguration); lcuLogging.UseLcuLogging(); var rmsApiConfiguration = configuration.Bind(services, "RmsApiConfiguration"); var coreApiConfiguration = configuration.Bind(services, "CoreApiConfiguration"); services.AddApiKeySecurity(configuration); services.AddLCUStatusServices(); //Services services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); //Service Clients services.AddScoped(); //Repositories services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); //HostedServices if (apiConfiguration.FeatureFlags.EnableImportExportActive) { services.AddHostedService(); } if (apiConfiguration.FeatureFlags.EnableImportExportClosed) { services.AddHostedService(); } services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = $"{apiConfiguration.AppName}", Version = "v1", Contact = new OpenApiContact { Name = "SpecFlow Tests", Url = new Uri("/Specs/index.html", UriKind.Relative) } }); }); } public static void BuildAppAndRun(WebApplicationBuilder builder) { var app = builder.Build(); app.UseSwagger(c => { c.PreSerializeFilters.Add((swaggerDoc, request) => { const string prefixHeader = "X-Forwarded-Prefix"; if (!request.Headers.ContainsKey(prefixHeader)) return; var serverUrl = request.Headers[prefixHeader]; swaggerDoc.Servers = new List() { new() { Description = serverUrl, Url = serverUrl } }; }); }); app.UseSwaggerUI(c => { c.RoutePrefix = "swagger"; c.SwaggerEndpoint("v1/swagger.json", "ReserveManagementSystemApi v1"); }); if (app.Environment.IsDevelopment()) { app.UseDeveloperExceptionPage(); } var specsFolder = Path.Combine(Directory.GetCurrentDirectory(), "Specs"); if (Directory.Exists(specsFolder)) { app.UseFileServer(new FileServerOptions() { FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "Specs")), RequestPath = new PathString("/Specs"), EnableDefaultFiles = true }); } app.UseMiddleware(); app.UseSerilogRequestLogging(options => { options.EnrichDiagnosticContext = RequestResponseLoggingMiddleware.RequestDataParser.EnrichFromRequest; }); app.UseAuthentication(); app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); app.Run(); } public static void AddMassTransitServices(ref IServiceCollection services, ConnectionConfiguration connectionConfiguration, ReceiveEndpointConfigurations receiveEndpointConfigurations, ApiConfiguration apiConfiguration) { services.AddMassTransit(x => { x.AddConsumer(); x.UsingRabbitMq((context, cfg) => { cfg.Host(connectionConfiguration.HostUrl, "/", host => { host.Username(connectionConfiguration.UserName); host.Password(connectionConfiguration.Password); }); cfg.UseTimeout(t => t.Timeout = TimeSpan.FromSeconds(420)); if (apiConfiguration.FeatureFlags.RunRmsActiveLoanConsumer) { cfg.ReceiveEndpoint(receiveEndpointConfigurations.RmsActiveLoanReceiveEndpoint.ReceiveEndpoint, e => { e.ConfigureConsumer(context); e.SetQuorumQueue(); e.PrefetchCount = receiveEndpointConfigurations.RmsActiveLoanReceiveEndpoint.PrefetchLimit; e.UseTimeout(t => t.Timeout = TimeSpan.FromSeconds(420)); }); } }); }); services.AddMassTransitHostedService(); } public static void AddQueueServices(IServiceCollection services) { services.AddScoped(); } } }