157 lines
5.0 KiB
C#

using CommandDotNet.Execution;
using EnvelopeGenerator.Application.ThirdPartyModules.Queries;
using EnvelopeGenerator.DependencyInjection;
using EnvelopeGenerator.Finalizer.Job;
using EnvelopeGenerator.Finalizer.Models;
using EnvelopeGenerator.Infrastructure;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Quartz;
using Quartz.AspNetCore;
using Quartz.Impl;
using Quartzmon;
using Serilog;
// Load Serilog from appsettings.json
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(new ConfigurationBuilder()
.AddJsonFile("appsettings.Logging.json", optional: false, reloadOnChange: true)
.Build())
.CreateLogger();
try
{
Log.Information("Application is starting...");
var builder = WebApplication.CreateBuilder(args);
#region Logging
builder.Logging.ClearProviders();
builder.Logging.AddSerilog();
#endregion
#region Configuration
var config = builder.Configuration;
Directory
.GetFiles(builder.Environment.ContentRootPath, "appsettings.*.json", SearchOption.TopDirectoryOnly)
.Where(file => Path.GetFileName(file) != $"appsettings.Development.json")
.Where(file => Path.GetFileName(file) != $"appsettings.migration.json")
.ToList()
.ForEach(file => config.AddJsonFile(file, true, true));
#endregion
#region Web API Services
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
#endregion
#region Quartz
builder.Services.AddQuartz(q =>
{
var name = $"{typeof(FinishEnvelopeJob).FullName}";
var jobKey = new JobKey(name);
q.AddJob<FinishEnvelopeJob>(opts => opts.WithIdentity(jobKey));
var expression = config[nameof(FinishEnvelopeJob) + ":CronExpression"];
if (string.IsNullOrWhiteSpace(expression))
throw new InvalidOperationException(
"Cron expression for the Worker job is not configured. " +
"Please provide a valid cron schedule in the configuration under " +
$"'{nameof(FinishEnvelopeJob)}:CronExpression'.");
q.AddTrigger(opts => opts
.ForJob(jobKey)
.WithIdentity(name + "-trigger")
.WithCronSchedule(expression));
});
builder.Services.AddQuartzServer(options =>
{
options.WaitForJobsToComplete = true;
});
builder.Services.AddQuartzmon();
builder.Services.AddSingleton(provider =>
provider.GetRequiredService<ISchedulerFactory>().GetScheduler().Result
);
#endregion
#region Add DB Context, EG Inf. and Services
var cnnStrName = "Default";
var connStr = config.GetConnectionString(cnnStrName)
?? throw new InvalidOperationException($"Connection string '{cnnStrName}' is missing in the application configuration.");
builder.Services.AddEnvelopeGenerator(egOptions => egOptions
.AddLocalization()
.AddDistributedSqlServerCache(options =>
{
options.ConnectionString = connStr;
options.SchemaName = "dbo";
options.TableName = "TBDD_CACHE";
})
.AddInfrastructure(opt =>
{
opt.AddDbTriggerParams(config);
opt.AddDbContext((provider, options) =>
{
var logger = provider.GetRequiredService<ILogger<EGDbContext>>();
var useInMemoryDb = config.GetValue<bool>("UseInMemoryDb");
var dbCtxOpt = useInMemoryDb ? options.UseInMemoryDatabase("EGInMemoryDb") : options.UseSqlServer(connStr);
dbCtxOpt.LogTo(log => logger.LogInformation("{log}", log), LogLevel.Trace)
.EnableSensitiveDataLogging()
.EnableDetailedErrors();
});
})
.AddServices(config)
);
#endregion Add DB Context, EG Inf. and Services
builder.Services.AddOptions<GdPictureOptions>()
.Configure((GdPictureOptions opt, IServiceProvider sp) =>
{
var licenseKey = "GDPICTURE";
using var scope = sp.CreateScope();
var mediator = scope.ServiceProvider.GetRequiredService<IMediator>();
opt.License = config["GdPictureLicenseKey"]
?? mediator.ReadThirdPartyModuleLicenseAsync(licenseKey).GetAwaiter().GetResult()
?? throw new InvalidOperationException($"License record not found for key: {licenseKey}");
});
var app = builder.Build();
#region Web API Middleware
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseQuartzmon(new QuartzmonOptions()
{
Scheduler = app.Services.GetRequiredService<IScheduler>(),
VirtualPathRoot = "/quartz"
});
app.MapControllers();
#endregion
app.Run();
Log.Information("The worker was stopped.");
}
catch (Exception ex)
{
Log.Fatal(ex, "Worker could not be started!");
}
finally
{
Log.CloseAndFlush();
}