Skip to content
This repository was archived by the owner on Nov 17, 2023. It is now read-only.

Commit 9d38de0

Browse files
authored
Merge pull request #2092 from erjain/update/webshoppingagg-webap-builder
Update/webshoppingagg webapp builder
2 parents 7e2a966 + 65e2f13 commit 9d38de0

File tree

3 files changed

+204
-215
lines changed

3 files changed

+204
-215
lines changed

src/ApiGateways/Web.Bff.Shopping/aggregator/GlobalUsings.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,4 @@
3838
global using System.Threading;
3939
global using System;
4040
global using Microsoft.IdentityModel.Tokens;
41+
global using Serilog.Context;
Lines changed: 203 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,208 @@
1-
await BuildWebHost(args).RunAsync();
1+
var appName = "Web.Shopping.HttpAggregator";
2+
var builder = WebApplication.CreateBuilder(args);
23

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 =>
7126
{
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
10134
{
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+
}
14148
});
15-
})
16-
.UseStartup<Startup>()
17-
.UseSerilog((builderContext, config) =>
149+
150+
options.OperationFilter<AuthorizeCheckOperationFilter>();
151+
});
152+
services.AddCors(options =>
18153
{
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

Comments
 (0)