Adding
This commit is contained in:
@@ -0,0 +1,396 @@
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Newtonsoft.Json;
|
||||
using MassTransit;
|
||||
using LCU.Library.Internal.Configuration;
|
||||
using LCU.Library.Internal.LcuMassTransit;
|
||||
using LCU.Library.Internal.LcuMassTransitModels;
|
||||
using LCU.Library.Internal.Logging;
|
||||
using LCU.Library.Internal.Logging.Middleware;
|
||||
using LCU.Library.Internal.Logging.Models;
|
||||
using LCU.Api.Internal.Dispatcher.Configurations;
|
||||
using LCU.Api.Internal.Dispatcher.Consumers;
|
||||
using LCU.Api.Internal.Dispatcher.HostedServices;
|
||||
using LCU.Api.Internal.Dispatcher.Models;
|
||||
using LCU.Api.Internal.Dispatcher.Services;
|
||||
using LCU.Api.Internal.Dispatcher.Services.DispatcherOperationServices;
|
||||
using LCU.Api.Internal.Dispatcher.Services.QueueServices;
|
||||
using LCU.Api.Internal.DispatcherLib.Persistence;
|
||||
using LCU.Api.Internal.DispatcherLib.Repositories;
|
||||
using LCU.Api.Internal.DispatcherSharedLib;
|
||||
using System.Collections.Generic;
|
||||
using LCU.Library.Internal.ApiSecurity.Constants;
|
||||
using LCU.Library.Internal.ApiSecurity;
|
||||
using LCU.Library.Internal.LcuHttpClient;
|
||||
using LCU.Api.Internal.Dispatcher.DataAccess;
|
||||
|
||||
string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
|
||||
ApiConfiguration _apiConfiguration;
|
||||
|
||||
var builder = BuildBuilder(args);
|
||||
BuildServicesAndConfigurations(builder);
|
||||
BuildAppAndRun(builder);
|
||||
|
||||
WebApplicationBuilder BuildBuilder(string[] args)
|
||||
{
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
builder.Configuration.AddJsonFile("/app/config/environment-appsettings/appsettings.json", optional: true, reloadOnChange: true);
|
||||
builder.Configuration.AddJsonFile("/app/config/workload-appsettings/appsettings.json", optional: true, reloadOnChange: true);
|
||||
builder.Configuration.AddJsonFile("/vault/secrets/dispatcher-api-database-connection.json", optional: true, reloadOnChange: true);
|
||||
builder.Configuration.AddJsonFile("/vault/secrets/dispatcher-api-seq-api-key.json", optional: true, reloadOnChange: true);
|
||||
builder.Configuration.AddJsonFile("/vault/secrets/dispatcher-api-rabbitmq-username.json", optional: true, reloadOnChange: true);
|
||||
builder.Configuration.AddJsonFile("/vault/secrets/dispatcher-api-rabbitmq-password.json", optional: true, reloadOnChange: true);
|
||||
builder.Configuration.AddJsonFile("/vault/secrets/dispatcher-api-external-api-key-set.json", optional: true, reloadOnChange: true);
|
||||
builder.Host.UseSerilog();
|
||||
return builder;
|
||||
}
|
||||
|
||||
void BuildServicesAndConfigurations(WebApplicationBuilder builder)
|
||||
{
|
||||
var services = builder.Services;
|
||||
var configuration = builder.Configuration;
|
||||
services.AddControllers();
|
||||
services.AddEndpointsApiExplorer();
|
||||
services.AddSwaggerGen();
|
||||
services.AddHttpClient();
|
||||
|
||||
_apiConfiguration = configuration.Bind<ApiConfiguration>(services, "Primary");
|
||||
|
||||
var connectionsConfiguration = configuration.Bind<ConnectionsConfiguration>(services);
|
||||
|
||||
var loggerConfiguration = new LoggingConfiguration(_apiConfiguration.AppName,
|
||||
_apiConfiguration.SeqApiKey,
|
||||
_apiConfiguration.SeqUrl);
|
||||
var lcuLogging = new LcuLogging(loggerConfiguration);
|
||||
lcuLogging.UseLcuLogging();
|
||||
|
||||
var connectionConfiguration = MassTransitConfigurationSetUp.AddConnectionConfiguration(ref services, configuration);
|
||||
//debugging
|
||||
Console.WriteLine(JsonConvert.SerializeObject(connectionConfiguration));
|
||||
|
||||
var receiveEndpointConfigurations = new ReceiveEndpointConfigurations()
|
||||
{
|
||||
ExecutionReceiveEndpoint = MassTransitConfigurationSetUp.GetReceiveEndpointConfiguration(configuration,
|
||||
"ExecutionReceiveEndpoint"),
|
||||
CompletionReceiveEndpoint = MassTransitConfigurationSetUp.GetReceiveEndpointConfiguration(configuration,
|
||||
"CompletionReceiveEndpoint"),
|
||||
DetermineOperationReceiveEndpoint = MassTransitConfigurationSetUp.GetReceiveEndpointConfiguration(configuration,
|
||||
"DetermineOperationReceiveEndpoint"),
|
||||
JobFailureReceiveEndpoint = MassTransitConfigurationSetUp.GetReceiveEndpointConfiguration(configuration,
|
||||
"JobFailureReceiveEndpoint"),
|
||||
SendErroredJobAlertReceiveEndpoint = MassTransitConfigurationSetUp.GetReceiveEndpointConfiguration(configuration,
|
||||
"SendErroredJobAlertReceiveEndpoint")
|
||||
};
|
||||
services.AddSingleton(receiveEndpointConfigurations);
|
||||
//debugging
|
||||
Console.WriteLine(JsonConvert.SerializeObject(receiveEndpointConfigurations));
|
||||
|
||||
services.AddCors(options =>
|
||||
{
|
||||
options.AddPolicy(MyAllowSpecificOrigins,
|
||||
builder =>
|
||||
{
|
||||
builder.WithOrigins(
|
||||
_apiConfiguration.CorsAllowedOrigins
|
||||
).AllowAnyHeader().AllowAnyMethod();
|
||||
});
|
||||
});
|
||||
|
||||
services.AddDbContextPool<AppDbContext>(options =>
|
||||
{
|
||||
options.UseSqlServer(
|
||||
connectionsConfiguration.Sql.DispatcherDb,
|
||||
sqlServerOptionsAction: sqlOptions =>
|
||||
{
|
||||
sqlOptions.EnableRetryOnFailure(
|
||||
maxRetryCount: connectionsConfiguration.Sql.SQLOptions.MaxRetryCount,
|
||||
maxRetryDelay: connectionsConfiguration.Sql.SQLOptions.MaxRetryDelay,
|
||||
errorNumbersToAdd: connectionsConfiguration.Sql.SQLOptions.ErrorNumbersToAdd
|
||||
);
|
||||
sqlOptions.CommandTimeout(connectionsConfiguration.Sql.SQLOptions.CommandTimeout);
|
||||
}
|
||||
);
|
||||
options.EnableDetailedErrors(connectionsConfiguration.Sql.SQLOptions.EnableDetailedErrors);
|
||||
});
|
||||
|
||||
AddMassTransitServices(ref services, connectionConfiguration, receiveEndpointConfigurations, _apiConfiguration);
|
||||
services.AddDispatcherServices(configuration);
|
||||
services.AddLCUHttpServices();
|
||||
AddServices(services);
|
||||
AddRepositories(services);
|
||||
AddHostedServices(services);
|
||||
|
||||
services.AddSwaggerGen(c =>
|
||||
{
|
||||
c.SwaggerDoc("v1", new OpenApiInfo { Title = $"{_apiConfiguration.AppName}", Version = "v1" });
|
||||
|
||||
//Add Security Entry Fields In Swagger
|
||||
c.AddSecurityRequirement(new OpenApiSecurityRequirement
|
||||
{
|
||||
{
|
||||
new OpenApiSecurityScheme
|
||||
{
|
||||
Reference = new OpenApiReference
|
||||
{
|
||||
Id = HeaderKeys.ApiKey, // Must match the "AddSecurityDefinition"
|
||||
Type = ReferenceType.SecurityScheme
|
||||
}
|
||||
},
|
||||
new List<string>()
|
||||
}
|
||||
});
|
||||
|
||||
c.AddSecurityRequirement(new OpenApiSecurityRequirement
|
||||
{
|
||||
{
|
||||
new OpenApiSecurityScheme
|
||||
{
|
||||
Reference = new OpenApiReference
|
||||
{
|
||||
Id = HeaderKeys.Client, // Must match the "AddSecurityDefinition"
|
||||
Type = ReferenceType.SecurityScheme
|
||||
}
|
||||
},
|
||||
new List<string>()
|
||||
}
|
||||
});
|
||||
|
||||
c.AddSecurityDefinition(HeaderKeys.ApiKey,
|
||||
new OpenApiSecurityScheme
|
||||
{
|
||||
Description = HeaderKeys.ApiKey,
|
||||
In = ParameterLocation.Header,
|
||||
Name = HeaderKeys.ApiKey,
|
||||
Type = SecuritySchemeType.ApiKey,
|
||||
Scheme = "apikey"
|
||||
});
|
||||
|
||||
c.AddSecurityDefinition(HeaderKeys.Client,
|
||||
new OpenApiSecurityScheme
|
||||
{
|
||||
Description = HeaderKeys.Client,
|
||||
In = ParameterLocation.Header,
|
||||
Name = HeaderKeys.Client,
|
||||
Type = SecuritySchemeType.ApiKey,
|
||||
Scheme = "apikey"
|
||||
});
|
||||
});
|
||||
|
||||
builder.Services.AddApiKeySecurity(builder.Configuration);
|
||||
}
|
||||
|
||||
void AddMassTransitServices(ref IServiceCollection services,
|
||||
ConnectionConfiguration connectionConfiguration,
|
||||
ReceiveEndpointConfigurations receiveEndpointConfigurations,
|
||||
ApiConfiguration apiConfiguration)
|
||||
{
|
||||
services.AddMassTransit(x =>
|
||||
{
|
||||
x.AddConsumer<ExecutionConsumer>();
|
||||
x.AddConsumer<CompletionConsumer>();
|
||||
x.AddConsumer<DetermineOperationConsumer>();
|
||||
x.AddConsumer<JobFailureConsumer>();
|
||||
x.AddConsumer<SendErroredJobAlertConsumer>();
|
||||
|
||||
x.UsingRabbitMq((context, cfg) =>
|
||||
{
|
||||
cfg.Host(connectionConfiguration.HostUrl, "/", host =>
|
||||
{
|
||||
host.Username(connectionConfiguration.UserName);
|
||||
host.Password(connectionConfiguration.Password);
|
||||
});
|
||||
|
||||
if (apiConfiguration.FeatureFlags.RunExecutionConsumer)
|
||||
{
|
||||
cfg.ReceiveEndpoint(receiveEndpointConfigurations.ExecutionReceiveEndpoint.ReceiveEndpoint, e =>
|
||||
{
|
||||
e.ConfigureConsumer<ExecutionConsumer>(context);
|
||||
e.SetQuorumQueue();
|
||||
e.PrefetchCount = receiveEndpointConfigurations.CompletionReceiveEndpoint.PrefetchLimit;
|
||||
});
|
||||
}
|
||||
|
||||
if (apiConfiguration.FeatureFlags.RunCompletionConsumer)
|
||||
{
|
||||
cfg.ReceiveEndpoint(receiveEndpointConfigurations.CompletionReceiveEndpoint.ReceiveEndpoint, e =>
|
||||
{
|
||||
e.ConfigureConsumer<CompletionConsumer>(context);
|
||||
e.SetQuorumQueue();
|
||||
e.PrefetchCount = receiveEndpointConfigurations.CompletionReceiveEndpoint.PrefetchLimit;
|
||||
});
|
||||
}
|
||||
|
||||
if (apiConfiguration.FeatureFlags.RunDetermineOperationConsumer)
|
||||
{
|
||||
cfg.ReceiveEndpoint(receiveEndpointConfigurations.DetermineOperationReceiveEndpoint.ReceiveEndpoint, e =>
|
||||
{
|
||||
e.ConfigureConsumer<DetermineOperationConsumer>(context);
|
||||
e.SetQuorumQueue();
|
||||
e.PrefetchCount = receiveEndpointConfigurations.DetermineOperationReceiveEndpoint.PrefetchLimit;
|
||||
});
|
||||
}
|
||||
|
||||
if (apiConfiguration.FeatureFlags.RunJobFailureConsumer)
|
||||
{
|
||||
cfg.ReceiveEndpoint(receiveEndpointConfigurations.JobFailureReceiveEndpoint.ReceiveEndpoint, e =>
|
||||
{
|
||||
e.ConfigureConsumer<JobFailureConsumer>(context);
|
||||
e.SetQuorumQueue();
|
||||
e.PrefetchCount = receiveEndpointConfigurations.JobFailureReceiveEndpoint.PrefetchLimit;
|
||||
});
|
||||
}
|
||||
|
||||
if (apiConfiguration.FeatureFlags.RunSendErroredJobAlertConsumer)
|
||||
{
|
||||
cfg.ReceiveEndpoint(receiveEndpointConfigurations.SendErroredJobAlertReceiveEndpoint.ReceiveEndpoint, e =>
|
||||
{
|
||||
e.ConfigureConsumer<SendErroredJobAlertConsumer>(context, cons =>
|
||||
{
|
||||
cons.Options<BatchOptions>(options => options
|
||||
.SetMessageLimit(200)
|
||||
.SetTimeLimit(5000)
|
||||
.SetConcurrencyLimit(1));
|
||||
});
|
||||
e.SetQuorumQueue();
|
||||
e.PrefetchCount = receiveEndpointConfigurations.SendErroredJobAlertReceiveEndpoint.PrefetchLimit;
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
services.AddMassTransitHostedService();
|
||||
}
|
||||
|
||||
void AddServices(IServiceCollection services)
|
||||
{
|
||||
services.AddScoped<IEnvironmentView, EnvironmentView>();
|
||||
|
||||
AddDispatcherOperationServices(services);
|
||||
AddQueueServices(services);
|
||||
services.AddScoped<IJobService, JobService>();
|
||||
services.AddScoped<IJobTagService, JobTagService>();
|
||||
services.AddScoped<ITagService, TagService>();
|
||||
services.AddScoped<IWorkItemService, WorkItemService>();
|
||||
services.AddScoped<IWorkItemExecutionService, WorkItemExecutionService>();
|
||||
services.AddScoped<IExecutionMessageService, ExecutionMessageService>();
|
||||
services.AddScoped<IJobErrorRecipientService, JobErrorRecipientService>();
|
||||
services.AddScoped<INotificationService, NotificationService>();
|
||||
services.AddScoped<ICleanUpJobSettingService, CleanUpJobSettingService>();
|
||||
services.AddScoped<ICleanUpJobTagService, CleanUpJobTagService>();
|
||||
}
|
||||
|
||||
void AddDispatcherOperationServices(IServiceCollection services)
|
||||
{
|
||||
services.AddScoped<IJobScheduleService, JobScheduleService>();
|
||||
services.AddScoped<IBatchErroredJobsService, BatchErroredJobsService>();
|
||||
services.AddScoped<IIngestionService, IngestionService>();
|
||||
services.AddScoped<IExecutionService, ExecutionService>();
|
||||
services.AddScoped<ICompletionService, CompletionService>();
|
||||
|
||||
services.AddScoped<ICleanUpJobsService, CleanUpJobsService>();
|
||||
services.AddScoped<IDetermineOperationService, DetermineOperationService >();
|
||||
services.AddScoped<IJobFailureService, JobFailureService >();
|
||||
services.AddScoped<ISendErroredJobAlertService, SendErroredJobAlertService >();
|
||||
}
|
||||
|
||||
void AddQueueServices(IServiceCollection services)
|
||||
{
|
||||
services.AddScoped<IQueueExecutionService, QueueExecutionService>();
|
||||
services.AddScoped<IQueueCompletionService, QueueCompletionService>();
|
||||
services.AddScoped<IQueueSendErroredJobAlertService, QueueSendErroredJobAlertService>();
|
||||
services.AddScoped<IQueueDetermineOperationService, QueueDetermineOperationService>();
|
||||
services.AddScoped<IQueueJobFailureService, QueueJobFailureService>();
|
||||
}
|
||||
|
||||
void AddRepositories(IServiceCollection services)
|
||||
{
|
||||
services.AddScoped<IUnitOfWork, UnitOfWork>();
|
||||
services.AddScoped<IJobRepository, JobRepository>();
|
||||
services.AddScoped<IJobErrorRecipientRepository, JobErrorRecipientRepository>();
|
||||
services.AddScoped<IJobTagRepository, JobTagRepository>();
|
||||
services.AddScoped<ITagRepository, TagRepository>();
|
||||
services.AddScoped<IWorkItemRepository, WorkItemRepository>();
|
||||
services.AddScoped<IWorkItemExecutionRepository, WorkItemExecutionRepository>();
|
||||
services.AddScoped<IExecutionMessageRepository, ExecutionMessageRepository>();
|
||||
services.AddScoped<ICleanUpJobSettingRepository, CleanUpJobSettingRepository>();
|
||||
services.AddScoped<ICleanUpJobTagRepository, CleanUpJobTagRepository>();
|
||||
services.AddScoped<INotificationsApiDao, NotificationsApiDao>();
|
||||
}
|
||||
|
||||
void AddHostedServices(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<ICleanUpJobsHostedService, CleanUpJobsHostedService>();
|
||||
services.AddSingleton<IBatchErroredJobsHostedService, BatchErroredJobsHostedService>();
|
||||
services.AddSingleton<IJobSchedulerHostedService, JobSchedulerHostedService>();
|
||||
}
|
||||
|
||||
void BuildAppAndRun(WebApplicationBuilder builder)
|
||||
{
|
||||
var app = builder.Build();
|
||||
|
||||
if (_apiConfiguration.FeatureFlags.RunCleanUpJobsHostedService)
|
||||
{
|
||||
var service = app.Services.GetRequiredService<ICleanUpJobsHostedService>();
|
||||
service.StartAsync().Wait();
|
||||
}
|
||||
|
||||
if (_apiConfiguration.FeatureFlags.RunJobSchedulerHostedService)
|
||||
{
|
||||
var service = app.Services.GetRequiredService<IJobSchedulerHostedService>();
|
||||
service.StartAsync().Wait();
|
||||
}
|
||||
|
||||
if (_apiConfiguration.FeatureFlags.RunBatchErroredJobsHostedService)
|
||||
{
|
||||
var service = app.Services.GetRequiredService<IBatchErroredJobsHostedService>();
|
||||
service.StartAsync().Wait();
|
||||
}
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
|
||||
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];
|
||||
if (!String.IsNullOrWhiteSpace(serverUrl))
|
||||
{
|
||||
swaggerDoc.Servers = new List<OpenApiServer>()
|
||||
{
|
||||
new() { Description = serverUrl, Url = serverUrl }
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
app.UseSwaggerUI(c =>
|
||||
{
|
||||
c.RoutePrefix = "swagger";
|
||||
c.SwaggerEndpoint("v1/swagger.json", "LCU.Api.Internal.Dispatcher v1");
|
||||
});
|
||||
app.UseMiddleware<RequestResponseLoggingMiddleware>();
|
||||
app.UseSerilogRequestLogging(options =>
|
||||
{
|
||||
options.EnrichDiagnosticContext = RequestResponseLoggingMiddleware.RequestDataParser.EnrichFromRequest;
|
||||
});
|
||||
|
||||
app.UseRouting();
|
||||
app.UseCors(MyAllowSpecificOrigins);
|
||||
app.UseHttpsRedirection();
|
||||
app.UseAuthorization();
|
||||
app.MapControllers();
|
||||
app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
|
||||
|
||||
app.Run();
|
||||
}
|
||||
Reference in New Issue
Block a user