11using System . Configuration ;
2+ using System . Diagnostics . CodeAnalysis ;
23using System . Reflection ;
3- using Azure . Messaging . ServiceBus ;
44using Azure . Storage . Blobs ;
55using EPR . Calculator . API ;
66using EPR . Calculator . API . Data ;
77using EPR . Calculator . API . Exceptions ;
8+ using EPR . Calculator . API . Extensions ;
89using EPR . Calculator . API . HealthCheck ;
910using EPR . Calculator . API . Services ;
1011using EPR . Calculator . API . Services . Abstractions ;
1920using Microsoft . Extensions . Azure ;
2021using Microsoft . Identity . Web ;
2122
23+ [ assembly: SuppressMessage (
24+ "SonarAnalyzer.CSharp" ,
25+ "S5122:Make sure this permissive CORS policy is safe here" ,
26+ Justification = "Pre-existing behaviour." ) ]
27+
28+ const string corsPolicy = "AllowAllOrigins" ;
29+
2230var builder = WebApplication . CreateBuilder ( args ) ;
23- var environmentName = builder . Environment . EnvironmentName ? . ToLower ( ) ?? string . Empty ;
31+ builder . Configuration . AddUserSecrets ( Assembly . GetExecutingAssembly ( ) , optional : true ) ;
2432
25- // Add services to the container .
33+ // Framework services.
2634// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
35+ builder . Services . AddControllers ( ) ;
2736builder . Services . AddEndpointsApiExplorer ( ) ;
37+ builder . Services . AddSwaggerGen ( ) ;
2838builder . Services . AddApplicationInsightsTelemetry ( ) ;
2939builder . Services . AddHealthChecks ( ) ;
30- builder . Services . AddSwaggerGen ( ) ;
31- builder . Services . AddControllers ( ) ;
40+ builder . Services . AddExceptionHandler < GlobalExceptionHandler > ( ) ;
41+ builder . Services . AddProblemDetails ( ) ;
42+
43+ // Authentication and authorisation.
44+ builder . Services . AddAuthentication ( JwtBearerDefaults . AuthenticationScheme )
45+ . AddMicrosoftIdentityWebApi ( builder . Configuration . GetSection ( "AzureAd" ) ) ;
46+
47+ builder . Services . AddAuthorizationBuilder ( )
48+ . SetFallbackPolicy ( new AuthorizationPolicyBuilder ( )
49+ . RequireAuthenticatedUser ( )
50+ . RequireRole ( CommonResources . SASuperUserRole )
51+ . Build ( ) ) ;
52+
53+ builder . Services . AddCors ( options => options . AddPolicy (
54+ corsPolicy ,
55+ policy => policy
56+ . AllowAnyOrigin ( )
57+ . AllowAnyHeader ( )
58+ . AllowAnyMethod ( ) ) ) ;
59+
60+ // Validation.
3261builder . Services . AddFluentValidationAutoValidation ( ) ;
3362builder . Services . AddFluentValidationClientsideAdapters ( ) ;
63+ builder . Services . AddValidatorsFromAssemblyContaining < CreateDefaultParameterSettingValidator > ( ) ;
3464builder . Services . AddScoped < ICreateDefaultParameterDataValidator , CreateDefaultParameterDataValidator > ( ) ;
3565builder . Services . AddScoped < ILapcapDataValidator , LapcapDataValidator > ( ) ;
3666builder . Services . AddScoped < ICalcRelativeYearRequestDtoDataValidator , CalcRelativeYearRequestDtoDataValidator > ( ) ;
67+ builder . Services . AddScoped < ICalculatorRunStatusDataValidator , CalculatorRunStatusDataValidator > ( ) ;
68+
69+ // Application services.
3770builder . Services . AddScoped < IInvoiceDetailsService , InvoiceDetailsService > ( ) ;
3871builder . Services . AddScoped < IServiceBusService , ServiceBusService > ( ) ;
39- builder . Services . AddScoped < ICalculatorRunStatusDataValidator , CalculatorRunStatusDataValidator > ( ) ;
4072builder . Services . AddScoped < IBillingFileService , BillingFileService > ( ) ;
4173builder . Services . AddScoped < IAvailableClassificationsService , AvailableClassificationsService > ( ) ;
4274builder . Services . AddScoped < ICalculationRunService , CalculationRunService > ( ) ;
4375builder . Services . AddScoped < IStorageService , BlobStorageService > ( ) ;
4476builder . Services . AddScoped < IBlobStorageService2 , BlobStorageService2 > ( ) ;
4577
46-
47- // Add services to the container.
48- builder . Services . AddAuthentication ( JwtBearerDefaults . AuthenticationScheme )
49- . AddMicrosoftIdentityWebApi ( builder . Configuration . GetSection ( "AzureAd" ) ) ;
50-
51- // Adding Authorization with Global Policy.
52- builder . Services . AddAuthorizationBuilder ( )
53- . SetFallbackPolicy ( new AuthorizationPolicyBuilder ( )
54- . RequireAuthenticatedUser ( )
55- . RequireRole ( CommonResources . SASuperUserRole )
56- . Build ( ) ) ;
57-
58- builder . Services . AddControllers ( ) ;
59-
60- // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
61- builder . Services . AddEndpointsApiExplorer ( ) ;
62- builder . Services . AddSwaggerGen ( ) ;
63- builder . Services . AddValidatorsFromAssemblyContaining < CreateDefaultParameterSettingValidator > ( ) ;
64-
65- // Configure the database context.
78+ // Database context.
6679builder . Services . AddDbContext < ApplicationDBContext > ( options =>
67- {
68- options . UseSqlServer (
69- builder . Configuration . GetConnectionString ( "DefaultConnection" ) ) ;
70- } ) ;
80+ options . UseSqlServer ( builder . Configuration . GetConnectionString ( "DefaultConnection" ) ) ) ;
7181
82+ // Blob storage.
7283builder . Services . Configure < BlobStorageSettings > (
73- builder . Configuration . GetSection ( "BlobStorage" ) ) ;
84+ builder . Configuration . GetSection ( CommonResources . BlobStorageSection ) ) ;
7485
75- builder . Services . AddSingleton < BlobServiceClient > ( provider =>
86+ builder . Services . AddSingleton ( provider =>
7687{
77- var configuration = provider . GetRequiredService < IConfiguration > ( ) ;
78- var connectionString = configuration . GetSection ( "BlobStorage:ConnectionString" ) . Value ;
88+ var connectionString = provider . GetRequiredService < IConfiguration > ( )
89+ . GetSection ( CommonResources . BlobStorageSection )
90+ . GetValue < string > ( "ConnectionString" ) ;
91+
7992 if ( string . IsNullOrEmpty ( connectionString ) )
8093 {
8194 throw new ConfigurationErrorsException ( "Blob Storage connection string is not configured." ) ;
8497 return new BlobServiceClient ( connectionString ) ;
8598} ) ;
8699
87- var serviceBusConnectionString = builder . Configuration . GetSection ( "ServiceBus" ) . GetSection ( "ConnectionString" ) ;
88- var serviceBusQueueName = builder . Configuration . GetSection ( "ServiceBus" ) . GetSection ( "QueueName" ) . Value ;
89- #pragma warning disable CS8604 // Possible null reference argument.
90- var retryPeriod = double . Parse ( builder . Configuration . GetSection ( "ServiceBus" ) . GetSection ( "PostMessageRetryPeriod" ) . Value ) ;
91- var retryCount = int . Parse ( builder . Configuration . GetSection ( "ServiceBus" ) . GetSection ( " PostMessageRetryCount") . Value ) ;
92- #pragma warning restore CS8604 // Possible null reference argument.
100+ // Service Bus.
101+ var serviceBusSection = builder . Configuration . GetSection ( "ServiceBus" ) ;
102+ var retryPeriod = serviceBusSection . GetValue < double ? > ( "PostMessageRetryPeriod" )
103+ ?? throw new ConfigurationErrorsException ( " Configuration item not found: ServiceBus__PostMessageRetryPeriod" ) ;
104+ var retryCount = serviceBusSection . GetValue < int ? > ( " PostMessageRetryCount")
105+ ?? throw new ConfigurationErrorsException ( "Configuration item not found: ServiceBus__PostMessageRetryCount" ) ;
93106
94- builder . Services . AddAzureClients ( builder =>
107+ builder . Services . AddAzureClients ( factoryBuilder =>
95108{
96- builder
97- . AddServiceBusClient ( serviceBusConnectionString )
98- . WithName ( "calculator" )
109+ factoryBuilder
110+ . AddServiceBusClient ( serviceBusSection . GetSection ( "ConnectionString" ) )
111+ . WithName ( CommonResources . ServiceBusClientName )
99112 . ConfigureOptions ( options =>
100113 {
101114 options . RetryOptions . Delay = TimeSpan . FromSeconds ( retryPeriod ) ;
102115 options . RetryOptions . MaxDelay = TimeSpan . FromSeconds ( retryPeriod ) ;
103116 options . RetryOptions . MaxRetries = retryCount ;
104117 } ) ;
105-
106- // Register a sender for the "calculator" client.
107- #pragma warning disable CS8602 // Dereference of a possibly null reference.
108- builder . AddClient < ServiceBusSender , ServiceBusClientOptions > ( ( _ , _ , provider ) =>
109- provider
110- . GetService < IAzureClientFactory < ServiceBusClient > > ( )
111- . CreateClient ( "calculator" )
112- . CreateSender ( serviceBusQueueName ) )
113- . WithName ( $ "calculator-{ serviceBusQueueName } ") ;
114- #pragma warning restore CS8602 // Dereference of a possibly null reference.
115118} ) ;
116119
117- builder . Services . AddExceptionHandler < GlobalExceptionHandler > ( ) ;
118- builder . Services . AddProblemDetails ( ) ;
119- builder . Configuration . AddUserSecrets ( Assembly . GetExecutingAssembly ( ) , true ) ;
120-
121- // Configure endpoint timeout policies.
122- foreach ( string policy in CommonResources . TimeoutPolicies . Split ( ',' ) )
120+ // Endpoint timeout policies.
121+ builder . Services . AddRequestTimeouts ( options =>
123122{
124- var timeout = builder . Configuration . GetSection ( "Timeouts" ) . GetValue < double > ( policy ) ;
125- builder . Services . AddRequestTimeouts ( options =>
123+ foreach ( var policy in CommonResources . TimeoutPolicies . Split ( ',' ) )
126124 {
125+ var timeout = builder . Configuration . GetSection ( "Timeouts" ) . GetValue < double > ( policy ) ;
127126 options . AddPolicy ( policy , TimeSpan . FromMinutes ( timeout ) ) ;
128- } ) ;
129- }
127+ }
128+ } ) ;
130129
131130var app = builder . Build ( ) ;
132131
133132// Configure the HTTP request pipeline.
134- if ( app . Environment . IsDevelopment ( ) || environmentName . Equals ( CommonResources . Local , StringComparison . OrdinalIgnoreCase ) )
133+ if ( app . Environment . IsDevelopment ( ) || app . Environment . IsLocal ( ) )
135134{
136135 app . UseSwagger ( ) ;
137136 app . UseSwaggerUI ( ) ;
138137}
139138
140139app . UseExceptionHandler ( ) ;
141140app . UseHttpsRedirection ( ) ;
142- app . MapControllers ( ) ;
143- app . UseCors ( CommonResources . PolicyName ) ;
141+ app . UseCors ( corsPolicy ) ;
144142app . UseAuthentication ( ) ;
145143app . UseAuthorization ( ) ;
146144app . UseRequestTimeouts ( ) ;
145+
146+ app . MapControllers ( ) ;
147147app . MapHealthChecks ( "/admin/health" , HealthCheckOptionsBuilder . Build ( ) ) . AllowAnonymous ( ) ;
148148
149- await app . RunAsync ( ) ;
149+ await app . RunAsync ( ) ;
0 commit comments