2023-07-12 21:50:11 +07:00
using BMA.EHR.Application ;
using BMA.EHR.Domain.Middlewares ;
using BMA.EHR.Infrastructure ;
using BMA.EHR.Infrastructure.Persistence ;
using BMA.EHR.Report.Service ;
using Microsoft.AspNetCore.Authentication.JwtBearer ;
using Microsoft.AspNetCore.Mvc ;
using Microsoft.AspNetCore.Mvc.ApiExplorer ;
using Microsoft.AspNetCore.Mvc.Versioning ;
using Microsoft.EntityFrameworkCore ;
2023-08-28 11:02:28 +07:00
using Microsoft.Extensions.DependencyInjection.Extensions ;
2023-07-12 21:50:11 +07:00
using Microsoft.IdentityModel.Logging ;
using Microsoft.IdentityModel.Tokens ;
using Serilog ;
using Serilog.Exceptions ;
using Serilog.Sinks.Elasticsearch ;
using System.Reflection ;
using System.Text ;
2023-08-28 11:02:28 +07:00
using Telerik.Reporting.Cache.File ;
using Telerik.Reporting.Services ;
using Telerik.WebReportDesigner.Services ;
2023-07-12 21:50:11 +07:00
var builder = WebApplication . CreateBuilder ( args ) ;
{
var issuer = builder . Configuration [ "Jwt:Issuer" ] ;
var key = builder . Configuration [ "Jwt:Key" ] ;
IdentityModelEventSource . ShowPII = true ;
2023-08-24 12:14:01 +07:00
builder . Services . AddTransient < GenericReportGenerator > ( ) ;
2023-07-12 21:50:11 +07:00
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
ConfigureLogs ( ) ;
builder . Host . UseSerilog ( ) ;
// 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 . AddControllers ( options = >
{
options . SuppressAsyncSuffixInActionNames = false ;
} )
. AddNewtonsoftJson ( x = > x . SerializerSettings . ReferenceLoopHandling = Newtonsoft . Json . ReferenceLoopHandling . Ignore ) ;
builder . Services . AddSwaggerGen ( ) ;
builder . Services . ConfigureOptions < ConfigureSwaggerOptions > ( ) ;
builder . Services . AddHealthChecks ( ) ;
2023-08-28 11:02:28 +07:00
// For Telerik Report Designer
builder . Services . TryAddSingleton < IReportServiceConfiguration > ( sp = >
new ReportServiceConfiguration
{
ReportingEngineConfiguration = ResolveSpecificReportingConfiguration ( sp . GetService < IWebHostEnvironment > ( ) ) ,
HostAppId = "ReportingCoreApp" ,
Storage = new FileStorage ( ) ,
ReportSourceResolver = new TypeReportSourceResolver ( ) . AddFallbackResolver
( new UriReportSourceResolver ( Path . Combine ( sp . GetService < IWebHostEnvironment > ( ) . ContentRootPath , "Reports" ) ) )
} ) ;
builder . Services . TryAddSingleton < IReportDesignerServiceConfiguration > ( sp = > new ReportDesignerServiceConfiguration
{
DefinitionStorage = new FileDefinitionStorage ( Path . Combine ( sp . GetService < IWebHostEnvironment > ( ) . ContentRootPath , "Reports" ) , new [ ] { "Resources" , "Shared Data Sources" } ) ,
ResourceStorage = new ResourceStorage ( Path . Combine ( sp . GetService < IWebHostEnvironment > ( ) . ContentRootPath , "Reports" , "Resources" ) ) ,
SharedDataSourceStorage = new FileSharedDataSourceStorage ( Path . Combine ( sp . GetService < IWebHostEnvironment > ( ) . ContentRootPath , "Reports" , "Shared Data Sources" ) ) ,
SettingsStorage = new FileSettingsStorage ( Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . ApplicationData ) , "Telerik Reporting" ) )
} ) ;
2023-07-12 21:50:11 +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" ) ;
2023-08-28 11:02:28 +07:00
2023-07-12 21:50:11 +07:00
app . UseHttpsRedirection ( ) ;
app . UseCors ( ) ;
app . UseAuthentication ( ) ;
app . UseAuthorization ( ) ;
app . UseDefaultFiles ( ) ;
app . UseStaticFiles ( ) ;
app . MapControllers ( ) ;
2023-07-13 14:16:15 +07:00
app . UseMiddleware < ErrorHandlerMiddleware > ( ) ;
2023-07-12 21:50:11 +07:00
// apply migrations
await using var scope = app . Services . CreateAsyncScope ( ) ;
await using var db = scope . ServiceProvider . GetRequiredService < ApplicationDBContext > ( ) ;
await db . Database . MigrateAsync ( ) ;
app . Run ( ) ;
}
2023-08-28 11:02:28 +07:00
static IConfiguration ResolveSpecificReportingConfiguration ( IWebHostEnvironment environment )
{
var reportingConfigFileName = Path . Combine ( environment . ContentRootPath , "appsettings.json" ) ;
return new ConfigurationBuilder ( )
. AddJsonFile ( reportingConfigFileName , true )
. Build ( ) ;
}
2023-07-12 21:50:11 +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 = $"{Assembly.GetExecutingAssembly()?.GetName()?.Name?.ToLower().Replace(" . ", " - ")}-{environment?.ToLower().Replace(" . ", " - ")}"
} ;
}