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