hrms-api-backend/BMA.EHR.Insignia/Program.cs

266 lines
11 KiB
C#
Raw Normal View History

2023-07-19 10:25:54 +07:00
using BMA.EHR.Application;
2023-09-08 12:48:17 +07:00
using BMA.EHR.Application.Repositories.Reports;
2023-07-19 10:25:54 +07:00
using BMA.EHR.Domain.Middlewares;
using BMA.EHR.Infrastructure;
using BMA.EHR.Infrastructure.Persistence;
using BMA.EHR.Insignia.Service;
2023-09-08 12:48:17 +07:00
using BMA.EHR.Insignia.Service.Filters;
2025-08-28 12:33:18 +07:00
using BMA.EHR.Insignia.Service.Services;
using Hangfire;
using Hangfire.Common;
2023-09-08 12:48:17 +07:00
using Hangfire.MySql;
2023-07-19 10:25:54 +07:00
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.AspNetCore.Mvc.Versioning;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Logging;
using Microsoft.IdentityModel.Tokens;
using Serilog;
using Serilog.Exceptions;
using Serilog.Sinks.Elasticsearch;
using System.Text;
2023-09-08 12:48:17 +07:00
using System.Transactions;
2023-07-19 10:25:54 +07:00
var builder = WebApplication.CreateBuilder(args);
{
var issuer = builder.Configuration["Jwt:Issuer"];
var key = builder.Configuration["Jwt:Key"];
IdentityModelEventSource.ShowPII = true;
builder.Services.AddHttpContextAccessor();
builder.Services.AddApiVersioning(opt =>
{
opt.DefaultApiVersion = new ApiVersion(1, 0);
opt.AssumeDefaultVersionWhenUnspecified = true;
opt.ReportApiVersions = true;
opt.ApiVersionReader = ApiVersionReader.Combine(new UrlSegmentApiVersionReader(),
new HeaderApiVersionReader("x-api-version"),
new MediaTypeApiVersionReader("x-api-version"));
});
builder.Services.AddVersionedApiExplorer(setup =>
{
setup.GroupNameFormat = "'v'VVV";
setup.SubstituteApiVersionInUrl = true;
});
builder.Services.AddEndpointsApiExplorer();
// Authorization
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(opt =>
{
opt.RequireHttpsMetadata = false; //false for dev
opt.Authority = issuer;
opt.TokenValidationParameters = new()
{
ValidateIssuer = true,
ValidateAudience = false,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = issuer,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key))
};
});
builder.Services.AddAuthorization();
// use serilog
2025-03-26 12:24:34 +07:00
//ConfigureLogs();
//builder.Host.UseSerilog();
2023-07-19 10:25:54 +07:00
// Add config CORS
builder.Services.AddCors(options => options.AddDefaultPolicy(builder =>
{
builder
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.SetIsOriginAllowedToAllowWildcardSubdomains();
}));
// Add services to the container.
builder.Services.AddApplication();
builder.Services.AddPersistence(builder.Configuration);
builder.Services.AddLeaveApplication();
builder.Services.AddLeavePersistence(builder.Configuration);
2023-07-19 10:25:54 +07:00
2025-08-28 12:33:18 +07:00
builder.Services.AddSingleton<IBackgroundTaskQueue, BackgroundTaskQueue>();
builder.Services.AddHostedService<InsigniaRequestProcessService>();
2024-07-07 09:59:37 +07:00
2024-07-06 11:04:12 +07:00
2023-07-19 10:25:54 +07:00
builder.Services.AddControllers(options =>
{
options.SuppressAsyncSuffixInActionNames = false;
})
.AddNewtonsoftJson(x => x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
builder.Services.AddSwaggerGen();
builder.Services.ConfigureOptions<ConfigureSwaggerOptions>();
2023-09-08 12:48:17 +07:00
// Register DbContext
var defaultConnection = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDBContext>(options =>
2024-07-07 09:59:37 +07:00
options.UseMySql(defaultConnection, ServerVersion.AutoDetect(defaultConnection)), ServiceLifetime.Transient);
2023-07-19 10:25:54 +07:00
builder.Services.AddHealthChecks();
2023-09-08 12:48:17 +07:00
// Add Hangfire services.
builder.Services.AddHangfire(configuration => configuration
.SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UseStorage(
new MySqlStorage(
defaultConnection,
new MySqlStorageOptions
{
TransactionIsolationLevel = IsolationLevel.ReadCommitted,
QueuePollInterval = TimeSpan.FromSeconds(15),
JobExpirationCheckInterval = TimeSpan.FromHours(1),
CountersAggregateInterval = TimeSpan.FromMinutes(5),
PrepareSchemaIfNecessary = true,
DashboardJobListLimit = 50000,
TransactionTimeout = TimeSpan.FromMinutes(1),
InvisibilityTimeout = TimeSpan.FromHours(3),
TablesPrefix = "Hangfire_Insignia"
2023-09-08 12:48:17 +07:00
})));
builder.Services.AddHangfireServer(options =>
{
options.ServerName = "Insignia-Server"; // ← ระบุชื่อ server
options.WorkerCount = 5; // ←
options.Queues = new[] { "insignia","default" }; // ← worker จะรันเฉพาะ queue "insignia"
});
2024-07-07 09:59:37 +07:00
// RabbitMQ
//builder.Services.AddTransient<RabbitMQConsumer>(provider =>
//{
// var serviceScopeFactory = provider.GetRequiredService<IServiceScopeFactory>();
// var userRepo = provider.GetRequiredService<UserProfileRepository>();
// var insigniaRepo = provider.GetRequiredService<InsigniaPeriodsRepository>();
// var httpContext = provider.GetRequiredService<IHttpContextAccessor>();
// var config = provider.GetRequiredService<IConfiguration>();
// return new RabbitMQConsumer(userRepo, insigniaRepo, httpContext, serviceScopeFactory, config);
//});
2023-07-19 10:25:54 +07:00
}
var app = builder.Build();
{
var apiVersionDescriptionProvider = app.Services.GetRequiredService<IApiVersionDescriptionProvider>();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI(options =>
{
foreach (var description in apiVersionDescriptionProvider.ApiVersionDescriptions)
{
options.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json",
description.GroupName.ToUpperInvariant());
}
});
}
app.MapHealthChecks("/health");
2024-07-07 09:59:37 +07:00
2023-07-19 10:25:54 +07:00
app.UseHttpsRedirection();
app.UseCors();
app.UseMiddleware<CombinedErrorHandlerAndLoggingMiddleware>();
2023-07-19 10:25:54 +07:00
app.UseAuthentication();
app.UseAuthorization();
app.UseDefaultFiles();
app.UseStaticFiles();
app.MapControllers();
// app.UseMiddleware<ErrorHandlerMiddleware>();
// app.UseMiddleware<RequestLoggingMiddleware>();
2023-09-08 12:48:17 +07:00
app.UseHangfireDashboard("/hangfire", new DashboardOptions()
{
Authorization = new[] { new CustomAuthorizeFilter() }
});
var manager = new RecurringJobManager();
if (manager != null)
{
2023-09-08 15:23:41 +07:00
manager.AddOrUpdate("แจ้งเตือนรอบเครื่องราชฯ", Job.FromExpression<InsigniaReportRepository>(x => x.NotifyInsignia()), Cron.Daily(Int32.Parse(builder.Configuration["KeycloakCron:Hour"]), Int32.Parse(builder.Configuration["KeycloakCron:Minute"])), TimeZoneInfo.Local);
manager.AddOrUpdate("ล็อกข้อมูลรอบเครื่องราชฯ", Job.FromExpression<InsigniaReportRepository>(x => x.LockInsignia()), Cron.Daily(Int32.Parse(builder.Configuration["KeycloakCron:Hour"]), Int32.Parse(builder.Configuration["KeycloakCron:Minute"])), TimeZoneInfo.Local);
2025-11-11 09:51:18 +07:00
//manager.AddOrUpdate("คำนวนผู้ได้รับเครื่องราชฯ", () => CalculateInsigniaRequestBkkByType("officer"), Cron.Daily(Int32.Parse(builder.Configuration["KeycloakCron:Hour"]), Int32.Parse(builder.Configuration["KeycloakCron:Minute"])), TimeZoneInfo.Local);
2025-11-11 05:43:02 +07:00
//manager.AddOrUpdate("คำนวนผู้ได้รับเครื่องราชฯ Employee", Job.FromExpression<InsigniaReportRepository>(x => x.CalInsigniaRequestBkkByType("employee")), Cron.Daily(Int32.Parse(builder.Configuration["KeycloakCron:Hour"]), Int32.Parse(builder.Configuration["KeycloakCron:Minute"])), TimeZoneInfo.Local);
}
2023-07-19 10:25:54 +07:00
2025-11-11 05:43:02 +07:00
RecurringJob.AddOrUpdate<InsigniaReportRepository>(
"คำนวนผู้ได้รับเครื่องราชฯ",
2025-11-11 09:51:18 +07:00
x => x.CalculateInsigniaRequestBkkByType("officer"),
Cron.Daily(Int32.Parse(builder.Configuration["KeycloakCron:Hour"]) - 5,
2025-11-11 05:43:02 +07:00
Int32.Parse(builder.Configuration["KeycloakCron:Minute"])),
new RecurringJobOptions
{
TimeZone = TimeZoneInfo.Local,
QueueName = "insignia" // ← กำหนด queue
}
2025-11-11 05:43:02 +07:00
);
2025-11-11 09:51:18 +07:00
2025-11-11 05:43:02 +07:00
RecurringJob.AddOrUpdate<InsigniaReportRepository>(
"คำนวนผู้ได้รับเครื่องราชฯ Employee",
2025-11-11 09:51:18 +07:00
x => x.CalculateInsigniaRequestBkkByType("employee"),
Cron.Daily(Int32.Parse(builder.Configuration["KeycloakCron:Hour"]) - 4,
2025-11-11 05:43:02 +07:00
Int32.Parse(builder.Configuration["KeycloakCron:Minute"])),
new RecurringJobOptions
{
TimeZone = TimeZoneInfo.Local,
QueueName = "insignia" // ← กำหนด queue
}
2025-11-11 05:43:02 +07:00
);
2023-07-19 10:25:54 +07:00
// apply migrations
await using var scope = app.Services.CreateAsyncScope();
await using var db = scope.ServiceProvider.GetRequiredService<ApplicationDBContext>();
await db.Database.MigrateAsync();
2024-07-07 09:59:37 +07:00
//var rabbitMQConsumer = app.Services.GetRequiredService<RabbitMQConsumer>();
//rabbitMQConsumer.StartReceiving();
2024-07-06 11:04:12 +07:00
2025-11-11 05:43:02 +07:00
2023-07-19 10:25:54 +07:00
app.Run();
}
2025-11-11 09:51:18 +07:00
2025-11-11 05:43:02 +07:00
2023-07-19 10:25:54 +07:00
void ConfigureLogs()
{
var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile(
$"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json",
optional: true)
.Build();
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.MinimumLevel.Error()
.WriteTo.Console()
.Enrich.WithExceptionDetails()
.WriteTo.Elasticsearch(ConfigureElasticSink(configuration, environment ?? ""))
.Enrich.WithProperty("Environment", environment)
.ReadFrom.Configuration(configuration)
.CreateLogger();
}
ElasticsearchSinkOptions ConfigureElasticSink(IConfigurationRoot configuration, string environment)
{
return new ElasticsearchSinkOptions(new Uri(configuration["ElasticConfiguration:Uri"] ?? ""))
{
AutoRegisterTemplate = true,
IndexFormat = "bma-ehr-log-index",
//IndexFormat = $"{Assembly.GetExecutingAssembly()?.GetName()?.Name?.ToLower().Replace(".", "-")}-{environment?.ToLower().Replace(".", "-")}"
2023-07-19 10:25:54 +07:00
};
}