1
- await BuildWebHost ( args ) . RunAsync ( ) ;
1
+ var appName = "Web.Shopping.HttpAggregator" ;
2
+ var builder = WebApplication . CreateBuilder ( args ) ;
2
3
3
- IWebHost BuildWebHost ( string [ ] args ) =>
4
- WebHost
5
- . CreateDefaultBuilder ( args )
6
- . ConfigureAppConfiguration ( cb =>
4
+ builder . Host . UseSerilog ( CreateSerilogLogger ( builder . Configuration ) ) ;
5
+ builder . Services . AddHealthChecks ( )
6
+ . AddCheck ( "self" , ( ) => HealthCheckResult . Healthy ( ) )
7
+ . AddUrlGroup ( new Uri ( builder . Configuration [ "CatalogUrlHC" ] ) , name : "catalogapi-check" , tags : new string [ ] { "catalogapi" } )
8
+ . AddUrlGroup ( new Uri ( builder . Configuration [ "OrderingUrlHC" ] ) , name : "orderingapi-check" , tags : new string [ ] { "orderingapi" } )
9
+ . AddUrlGroup ( new Uri ( builder . Configuration [ "BasketUrlHC" ] ) , name : "basketapi-check" , tags : new string [ ] { "basketapi" } )
10
+ . AddUrlGroup ( new Uri ( builder . Configuration [ "IdentityUrlHC" ] ) , name : "identityapi-check" , tags : new string [ ] { "identityapi" } )
11
+ . AddUrlGroup ( new Uri ( builder . Configuration [ "PaymentUrlHC" ] ) , name : "paymentapi-check" , tags : new string [ ] { "paymentapi" } ) ;
12
+ builder . Services . AddCustomMvc ( builder . Configuration )
13
+ . AddCustomAuthentication ( builder . Configuration )
14
+ . AddApplicationServices ( )
15
+ . AddGrpcServices ( ) ;
16
+ var app = builder . Build ( ) ;
17
+ if ( app . Environment . IsDevelopment ( ) )
18
+ {
19
+ app . UseDeveloperExceptionPage ( ) ;
20
+ }
21
+ else
22
+ {
23
+ app . UseExceptionHandler ( "/Home/Error" ) ;
24
+ }
25
+ var pathBase = builder . Configuration [ "PATH_BASE" ] ;
26
+ if ( ! string . IsNullOrEmpty ( pathBase ) )
27
+ {
28
+ app . UsePathBase ( pathBase ) ;
29
+ }
30
+
31
+ app . UseHttpsRedirection ( ) ;
32
+
33
+ app . UseSwagger ( ) . UseSwaggerUI ( c =>
34
+ {
35
+ c . SwaggerEndpoint ( $ "{ ( ! string . IsNullOrEmpty ( pathBase ) ? pathBase : string . Empty ) } /swagger/v1/swagger.json", "Purchase BFF V1" ) ;
36
+
37
+ c . OAuthClientId ( "webshoppingaggswaggerui" ) ;
38
+ c . OAuthClientSecret ( string . Empty ) ;
39
+ c . OAuthRealm ( string . Empty ) ;
40
+ c . OAuthAppName ( "web shopping bff Swagger UI" ) ;
41
+ } ) ;
42
+
43
+ app . UseRouting ( ) ;
44
+ app . UseCors ( "CorsPolicy" ) ;
45
+ app . UseAuthentication ( ) ;
46
+ app . UseAuthorization ( ) ;
47
+
48
+ app . MapDefaultControllerRoute ( ) ;
49
+ app . MapControllers ( ) ;
50
+ app . MapHealthChecks ( "/hc" , new HealthCheckOptions ( )
51
+ {
52
+ Predicate = _ => true ,
53
+ ResponseWriter = UIResponseWriter . WriteHealthCheckUIResponse
54
+ } ) ;
55
+ app . MapHealthChecks ( "/liveness" , new HealthCheckOptions
56
+ {
57
+ Predicate = r => r . Name . Contains ( "self" )
58
+ } ) ;
59
+
60
+ try
61
+ {
62
+ Log . Information ( "Starts Web Application ({ApplicationContext})..." , Program . AppName ) ;
63
+ await app . RunAsync ( ) ;
64
+
65
+ return 0 ;
66
+ }
67
+ catch ( Exception ex )
68
+ {
69
+ Log . Fatal ( ex , "Program terminated unexpectedly ({ApplicationContext})!" , Program . AppName ) ;
70
+ return 1 ;
71
+ }
72
+ finally
73
+ {
74
+ Log . CloseAndFlush ( ) ;
75
+ }
76
+
77
+ Serilog . ILogger CreateSerilogLogger ( IConfiguration configuration )
78
+ {
79
+ var seqServerUrl = configuration [ "Serilog:SeqServerUrl" ] ;
80
+ var logstashUrl = configuration [ "Serilog:LogstashgUrl" ] ;
81
+ return new LoggerConfiguration ( )
82
+ . MinimumLevel . Verbose ( )
83
+ . Enrich . WithProperty ( "ApplicationContext" , Program . AppName )
84
+ . Enrich . FromLogContext ( )
85
+ . WriteTo . Console ( )
86
+ . ReadFrom . Configuration ( configuration )
87
+ . CreateLogger ( ) ;
88
+ }
89
+ public partial class Program
90
+ {
91
+
92
+ public static string Namespace = typeof ( Program ) . Assembly . GetName ( ) . Name ;
93
+ public static string AppName = Namespace . Substring ( Namespace . LastIndexOf ( '.' , Namespace . LastIndexOf ( '.' ) - 1 ) + 1 ) ;
94
+ }
95
+
96
+ public static class ServiceCollectionExtensions
97
+ {
98
+ public static IServiceCollection AddCustomAuthentication ( this IServiceCollection services , IConfiguration configuration )
99
+ {
100
+ JwtSecurityTokenHandler . DefaultInboundClaimTypeMap . Remove ( "sub" ) ;
101
+
102
+ var identityUrl = configuration . GetValue < string > ( "urls:identity" ) ;
103
+ services . AddAuthentication ( "Bearer" )
104
+ . AddJwtBearer ( options =>
105
+ {
106
+ options . Authority = identityUrl ;
107
+ options . RequireHttpsMetadata = false ;
108
+ options . Audience = "webshoppingagg" ;
109
+ options . TokenValidationParameters = new TokenValidationParameters
110
+ {
111
+ ValidateAudience = false
112
+ } ;
113
+ } ) ;
114
+
115
+ return services ;
116
+ }
117
+ public static IServiceCollection AddCustomMvc ( this IServiceCollection services , IConfiguration configuration )
118
+ {
119
+ services . AddOptions ( ) ;
120
+ services . Configure < UrlsConfig > ( configuration . GetSection ( "urls" ) ) ;
121
+
122
+ services . AddControllers ( )
123
+ . AddJsonOptions ( options => options . JsonSerializerOptions . WriteIndented = true ) ;
124
+
125
+ services . AddSwaggerGen ( options =>
7
126
{
8
- var sources = cb . Sources ;
9
- sources . Insert ( 3 , new Microsoft . Extensions . Configuration . Json . JsonConfigurationSource ( )
127
+ options . SwaggerDoc ( "v1" , new OpenApiInfo
128
+ {
129
+ Title = "Shopping Aggregator for Web Clients" ,
130
+ Version = "v1" ,
131
+ Description = "Shopping Aggregator for Web Clients"
132
+ } ) ;
133
+ options . AddSecurityDefinition ( "oauth2" , new OpenApiSecurityScheme
10
134
{
11
- Optional = true ,
12
- Path = "appsettings.localhost.json" ,
13
- ReloadOnChange = false
135
+ Type = SecuritySchemeType . OAuth2 ,
136
+ Flows = new OpenApiOAuthFlows ( )
137
+ {
138
+ Implicit = new OpenApiOAuthFlow ( )
139
+ {
140
+ AuthorizationUrl = new Uri ( $ "{ configuration . GetValue < string > ( "IdentityUrlExternal" ) } /connect/authorize") ,
141
+ TokenUrl = new Uri ( $ "{ configuration . GetValue < string > ( "IdentityUrlExternal" ) } /connect/token") ,
142
+ Scopes = new Dictionary < string , string > ( )
143
+ {
144
+ { "webshoppingagg" , "Shopping Aggregator for Web Clients" }
145
+ }
146
+ }
147
+ }
14
148
} ) ;
15
- } )
16
- . UseStartup < Startup > ( )
17
- . UseSerilog ( ( builderContext , config ) =>
149
+
150
+ options . OperationFilter < AuthorizeCheckOperationFilter > ( ) ;
151
+ } ) ;
152
+ services . AddCors ( options =>
18
153
{
19
- config
20
- . MinimumLevel . Information ( )
21
- . Enrich . FromLogContext ( )
22
- . WriteTo . Console ( ) ;
23
- } )
24
- . Build ( ) ;
154
+ options . AddPolicy ( "CorsPolicy" ,
155
+ builder => builder
156
+ . SetIsOriginAllowed ( ( host ) => true )
157
+ . AllowAnyMethod ( )
158
+ . AllowAnyHeader ( )
159
+ . AllowCredentials ( ) ) ;
160
+ } ) ;
161
+
162
+ return services ;
163
+ }
164
+ public static IServiceCollection AddApplicationServices ( this IServiceCollection services )
165
+ {
166
+ //register delegating handlers
167
+ services . AddTransient < HttpClientAuthorizationDelegatingHandler > ( ) ;
168
+ services . AddSingleton < IHttpContextAccessor , HttpContextAccessor > ( ) ;
169
+
170
+ //register http services
171
+
172
+ services . AddHttpClient < IOrderApiClient , OrderApiClient > ( )
173
+ . AddHttpMessageHandler < HttpClientAuthorizationDelegatingHandler > ( ) ;
174
+
175
+ return services ;
176
+ }
177
+
178
+ public static IServiceCollection AddGrpcServices ( this IServiceCollection services )
179
+ {
180
+ services . AddTransient < GrpcExceptionInterceptor > ( ) ;
181
+
182
+ services . AddScoped < IBasketService , BasketService > ( ) ;
183
+
184
+ services . AddGrpcClient < Basket . BasketClient > ( ( services , options ) =>
185
+ {
186
+ var basketApi = services . GetRequiredService < IOptions < UrlsConfig > > ( ) . Value . GrpcBasket ;
187
+ options . Address = new Uri ( basketApi ) ;
188
+ } ) . AddInterceptor < GrpcExceptionInterceptor > ( ) ;
189
+
190
+ services . AddScoped < ICatalogService , CatalogService > ( ) ;
191
+
192
+ services . AddGrpcClient < Catalog . CatalogClient > ( ( services , options ) =>
193
+ {
194
+ var catalogApi = services . GetRequiredService < IOptions < UrlsConfig > > ( ) . Value . GrpcCatalog ;
195
+ options . Address = new Uri ( catalogApi ) ;
196
+ } ) . AddInterceptor < GrpcExceptionInterceptor > ( ) ;
197
+
198
+ services . AddScoped < IOrderingService , OrderingService > ( ) ;
199
+
200
+ services . AddGrpcClient < OrderingGrpc . OrderingGrpcClient > ( ( services , options ) =>
201
+ {
202
+ var orderingApi = services . GetRequiredService < IOptions < UrlsConfig > > ( ) . Value . GrpcOrdering ;
203
+ options . Address = new Uri ( orderingApi ) ;
204
+ } ) . AddInterceptor < GrpcExceptionInterceptor > ( ) ;
205
+
206
+ return services ;
207
+ }
208
+ }
0 commit comments