From 5c60b6ace7f9906c4445d2c66d1d0ffc250a036d Mon Sep 17 00:00:00 2001 From: Rafsanul Hasan Date: Thu, 4 Apr 2019 09:48:49 +0600 Subject: [PATCH] fix async/await warnings --- src/ApiGateways/ApiGw-Base/Startup.cs | 172 ++++---- .../Mobile.Bff.Shopping/aggregator/Startup.cs | 397 +++++++++--------- .../Web.Bff.Shopping/aggregator/Startup.cs | 393 +++++++++-------- ...ductPriceChangedIntegrationEventHandler.cs | 15 +- 4 files changed, 485 insertions(+), 492 deletions(-) diff --git a/src/ApiGateways/ApiGw-Base/Startup.cs b/src/ApiGateways/ApiGw-Base/Startup.cs index 585c26471..41b04af6e 100644 --- a/src/ApiGateways/ApiGw-Base/Startup.cs +++ b/src/ApiGateways/ApiGw-Base/Startup.cs @@ -1,109 +1,113 @@ -using Microsoft.AspNetCore.Builder; +using HealthChecks.UI.Client; +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Diagnostics.HealthChecks; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Diagnostics.HealthChecks; using Ocelot.DependencyInjection; using Ocelot.Middleware; using System; -using HealthChecks.UI.Client; -using Microsoft.Extensions.Diagnostics.HealthChecks; +using System.Threading.Tasks; namespace OcelotApiGw { - public class Startup - { - private readonly IConfiguration _cfg; + public class Startup + { + private readonly IConfiguration _cfg; - public Startup(IConfiguration configuration) - { - _cfg = configuration; - } + public Startup(IConfiguration configuration) + => _cfg = configuration; - public void ConfigureServices(IServiceCollection services) - { - var identityUrl = _cfg.GetValue("IdentityUrl"); - var authenticationProviderKey = "IdentityApiKey"; + public void ConfigureServices(IServiceCollection services) + { + var identityUrl = _cfg.GetValue("IdentityUrl"); + var authenticationProviderKey = "IdentityApiKey"; - services.AddHealthChecks() - .AddCheck("self", () => HealthCheckResult.Healthy()) - .AddUrlGroup(new Uri(_cfg["CatalogUrlHC"]), name: "catalogapi-check", tags: new string[] { "catalogapi" }) - .AddUrlGroup(new Uri(_cfg["OrderingUrlHC"]), name: "orderingapi-check", tags: new string[] { "orderingapi" }) - .AddUrlGroup(new Uri(_cfg["BasketUrlHC"]), name: "basketapi-check", tags: new string[] { "basketapi" }) - .AddUrlGroup(new Uri(_cfg["IdentityUrlHC"]), name: "identityapi-check", tags: new string[] { "identityapi" }) - .AddUrlGroup(new Uri(_cfg["MarketingUrlHC"]), name: "marketingapi-check", tags: new string[] { "marketingapi" }) - .AddUrlGroup(new Uri(_cfg["PaymentUrlHC"]), name: "paymentapi-check", tags: new string[] { "paymentapi" }) - .AddUrlGroup(new Uri(_cfg["LocationUrlHC"]), name: "locationapi-check", tags: new string[] { "locationapi" }); + services.AddHealthChecks() + .AddCheck("self", () => HealthCheckResult.Healthy()) + .AddUrlGroup(new Uri(_cfg["CatalogUrlHC"]), name: "catalogapi-check", tags: new string[] { "catalogapi" }) + .AddUrlGroup(new Uri(_cfg["OrderingUrlHC"]), name: "orderingapi-check", tags: new string[] { "orderingapi" }) + .AddUrlGroup(new Uri(_cfg["BasketUrlHC"]), name: "basketapi-check", tags: new string[] { "basketapi" }) + .AddUrlGroup(new Uri(_cfg["IdentityUrlHC"]), name: "identityapi-check", tags: new string[] { "identityapi" }) + .AddUrlGroup(new Uri(_cfg["MarketingUrlHC"]), name: "marketingapi-check", tags: new string[] { "marketingapi" }) + .AddUrlGroup(new Uri(_cfg["PaymentUrlHC"]), name: "paymentapi-check", tags: new string[] { "paymentapi" }) + .AddUrlGroup(new Uri(_cfg["LocationUrlHC"]), name: "locationapi-check", tags: new string[] { "locationapi" }); - services.AddCors(options => - { - options.AddPolicy("CorsPolicy", - builder => builder - .AllowAnyMethod() - .AllowAnyHeader() - .SetIsOriginAllowed((host) => true) - .AllowCredentials()); - }); + services.AddCors(options => + { + options.AddPolicy("CorsPolicy", + builder => builder + .AllowAnyMethod() + .AllowAnyHeader() + .SetIsOriginAllowed((host) => true) + .AllowCredentials()); + }); - services.AddAuthentication() - .AddJwtBearer(authenticationProviderKey, x => - { - x.Authority = identityUrl; - x.RequireHttpsMetadata = false; - x.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters() - { - ValidAudiences = new[] { "orders", "basket", "locations", "marketing", "mobileshoppingagg", "webshoppingagg" } - }; - x.Events = new Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerEvents() - { - OnAuthenticationFailed = async ctx => - { - int i = 0; - }, - OnTokenValidated = async ctx => - { - int i = 0; - }, + services.AddAuthentication() + .AddJwtBearer(authenticationProviderKey, x => + { + x.Authority = identityUrl; + x.RequireHttpsMetadata = false; + x.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters() + { + ValidAudiences = new[] { "orders", "basket", "locations", "marketing", "mobileshoppingagg", "webshoppingagg" } + }; + x.Events = new Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerEvents() + { + OnAuthenticationFailed = async ctx => + { + await Task.Run(() => + { + }); + }, + OnTokenValidated = async ctx => + { + await Task.Run(() => + { + }); + }, - OnMessageReceived = async ctx => - { - int i = 0; - } - }; - }); + OnMessageReceived = async ctx => + { + await Task.Run(() => + { + }); + } + }; + }); - services.AddOcelot(_cfg); - } + services.AddOcelot(_cfg); + } - public void Configure(IApplicationBuilder app, IHostingEnvironment env) - { - var pathBase = _cfg["PATH_BASE"]; + public void Configure(IApplicationBuilder app, IHostingEnvironment env) + { + var pathBase = _cfg["PATH_BASE"]; - if (!string.IsNullOrEmpty(pathBase)) - { - app.UsePathBase(pathBase); - } + if (!string.IsNullOrEmpty(pathBase)) + { + app.UsePathBase(pathBase); + } - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } - app.UseHealthChecks("/hc", new HealthCheckOptions() - { - Predicate = _ => true, - ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse - }); + app.UseHealthChecks("/hc", new HealthCheckOptions() + { + Predicate = _ => true, + ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse + }); - app.UseHealthChecks("/liveness", new HealthCheckOptions - { - Predicate = r => r.Name.Contains("self") - }); + app.UseHealthChecks("/liveness", new HealthCheckOptions + { + Predicate = r => r.Name.Contains("self") + }); - app.UseCors("CorsPolicy"); + app.UseCors("CorsPolicy"); - app.UseOcelot().Wait(); - } - } + app.UseOcelot().Wait(); + } + } } diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs index 924b5b1aa..845cd28fa 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs @@ -1,9 +1,7 @@ -using System; -using System.Collections.Generic; -using System.IdentityModel.Tokens.Jwt; -using System.Net.Http; +using HealthChecks.UI.Client; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Diagnostics.HealthChecks; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; @@ -13,207 +11,206 @@ using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Infrastructure; using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Diagnostics.HealthChecks; using Microsoft.Extensions.Logging; using Polly; using Polly.Extensions.Http; using Swashbuckle.AspNetCore.Swagger; -using HealthChecks.UI.Client; -using Microsoft.AspNetCore.Diagnostics.HealthChecks; -using Microsoft.Extensions.Diagnostics.HealthChecks; +using System; +using System.Collections.Generic; +using System.IdentityModel.Tokens.Jwt; +using System.Net.Http; +using System.Threading.Tasks; namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator { - public class Startup - { - public Startup(IConfiguration configuration) - { - Configuration = configuration; - } - - public IConfiguration Configuration { get; } - - // This method gets called by the runtime. Use this method to add services to the container. - public void ConfigureServices(IServiceCollection services) - { - services.AddHealthChecks() - .AddCheck("self", () => HealthCheckResult.Healthy()) - .AddUrlGroup(new Uri(Configuration["CatalogUrlHC"]), name: "catalogapi-check", tags: new string[] { "catalogapi" }) - .AddUrlGroup(new Uri(Configuration["OrderingUrlHC"]), name: "orderingapi-check", tags: new string[] { "orderingapi" }) - .AddUrlGroup(new Uri(Configuration["BasketUrlHC"]), name: "basketapi-check", tags: new string[] { "basketapi" }) - .AddUrlGroup(new Uri(Configuration["IdentityUrlHC"]), name: "identityapi-check", tags: new string[] { "identityapi" }) - .AddUrlGroup(new Uri(Configuration["MarketingUrlHC"]), name: "marketingapi-check", tags: new string[] { "marketingapi" }) - .AddUrlGroup(new Uri(Configuration["PaymentUrlHC"]), name: "paymentapi-check", tags: new string[] { "paymentapi" }) - .AddUrlGroup(new Uri(Configuration["LocationUrlHC"]), name: "locationapi-check", tags: new string[] { "locationapi" }); - - services.AddCustomMvc(Configuration) - .AddCustomAuthentication(Configuration) - .AddHttpServices(); - } - - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) - { - var pathBase = Configuration["PATH_BASE"]; - - if (!string.IsNullOrEmpty(pathBase)) - { - loggerFactory.CreateLogger().LogDebug("Using PATH BASE '{pathBase}'", pathBase); - app.UsePathBase(pathBase); - } - - app.UseHealthChecks("/hc", new HealthCheckOptions() - { - Predicate = _ => true, - ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse - }); - - app.UseHealthChecks("/liveness", new HealthCheckOptions - { - Predicate = r => r.Name.Contains("self") - }); - - app.UseCors("CorsPolicy"); - - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } - else - { - // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. - app.UseHsts(); - } - - app.UseAuthentication(); - app.UseHttpsRedirection(); - app.UseMvc(); - - app.UseSwagger().UseSwaggerUI(c => - { - c.SwaggerEndpoint($"{ (!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty) }/swagger/v1/swagger.json", "Purchase BFF V1"); - - c.OAuthClientId("Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregatorwaggerui"); - c.OAuthClientSecret(string.Empty); - c.OAuthRealm(string.Empty); - c.OAuthAppName("Purchase BFF Swagger UI"); - }); - } - } - - public static class ServiceCollectionExtensions - { - public static IServiceCollection AddCustomMvc(this IServiceCollection services, IConfiguration configuration) - { - services.AddOptions(); - services.Configure(configuration.GetSection("urls")); - - services.AddMvc() - .SetCompatibilityVersion(CompatibilityVersion.Version_2_2); - - services.AddSwaggerGen(options => - { - options.DescribeAllEnumsAsStrings(); - options.SwaggerDoc("v1", new Swashbuckle.AspNetCore.Swagger.Info - { - Title = "Shopping Aggregator for Mobile Clients", - Version = "v1", - Description = "Shopping Aggregator for Mobile Clients", - TermsOfService = "Terms Of Service" - }); - - options.AddSecurityDefinition("oauth2", new OAuth2Scheme - { - Type = "oauth2", - Flow = "implicit", - AuthorizationUrl = $"{configuration.GetValue("IdentityUrlExternal")}/connect/authorize", - TokenUrl = $"{configuration.GetValue("IdentityUrlExternal")}/connect/token", - Scopes = new Dictionary() - { - { "mobileshoppingagg", "Shopping Aggregator for Mobile Clients" } - } - }); - - options.OperationFilter(); - }); - - services.AddCors(options => - { - options.AddPolicy("CorsPolicy", - builder => builder - .AllowAnyMethod() - .AllowAnyHeader() - .SetIsOriginAllowed((host) => true) - .AllowCredentials()); - }); - - return services; - } - public static IServiceCollection AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration) - { - JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); - var identityUrl = configuration.GetValue("urls:identity"); - - services.AddAuthentication(options => - { - options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; - options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; - - }) - .AddJwtBearer(options => - { - options.Authority = identityUrl; - options.RequireHttpsMetadata = false; - options.Audience = "mobileshoppingagg"; - options.Events = new JwtBearerEvents() - { - OnAuthenticationFailed = async ctx => - { - }, - OnTokenValidated = async ctx => - { - } - }; - }); - - return services; - } - - public static IServiceCollection AddHttpServices(this IServiceCollection services) - { - //register delegating handlers - services.AddTransient(); - services.AddSingleton(); - - //register http services - services.AddHttpClient() - .AddHttpMessageHandler() - .AddPolicyHandler(GetRetryPolicy()) - .AddPolicyHandler(GetCircuitBreakerPolicy()); - - services.AddHttpClient() - .AddPolicyHandler(GetRetryPolicy()) - .AddPolicyHandler(GetCircuitBreakerPolicy()); - - services.AddHttpClient() - .AddPolicyHandler(GetRetryPolicy()) - .AddPolicyHandler(GetCircuitBreakerPolicy()); - - return services; - } - - private static IAsyncPolicy GetRetryPolicy() - { - return HttpPolicyExtensions - .HandleTransientHttpError() - .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound) - .WaitAndRetryAsync(6, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))); - } - - private static IAsyncPolicy GetCircuitBreakerPolicy() - { - return HttpPolicyExtensions - .HandleTransientHttpError() - .CircuitBreakerAsync(5, TimeSpan.FromSeconds(30)); - } - } + public class Startup + { + public Startup(IConfiguration configuration) + => Configuration = configuration; + + public IConfiguration Configuration { get; } + + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + services.AddHealthChecks() + .AddCheck("self", () => HealthCheckResult.Healthy()) + .AddUrlGroup(new Uri(Configuration["CatalogUrlHC"]), name: "catalogapi-check", tags: new string[] { "catalogapi" }) + .AddUrlGroup(new Uri(Configuration["OrderingUrlHC"]), name: "orderingapi-check", tags: new string[] { "orderingapi" }) + .AddUrlGroup(new Uri(Configuration["BasketUrlHC"]), name: "basketapi-check", tags: new string[] { "basketapi" }) + .AddUrlGroup(new Uri(Configuration["IdentityUrlHC"]), name: "identityapi-check", tags: new string[] { "identityapi" }) + .AddUrlGroup(new Uri(Configuration["MarketingUrlHC"]), name: "marketingapi-check", tags: new string[] { "marketingapi" }) + .AddUrlGroup(new Uri(Configuration["PaymentUrlHC"]), name: "paymentapi-check", tags: new string[] { "paymentapi" }) + .AddUrlGroup(new Uri(Configuration["LocationUrlHC"]), name: "locationapi-check", tags: new string[] { "locationapi" }); + + services.AddCustomMvc(Configuration) + .AddCustomAuthentication(Configuration) + .AddHttpServices(); + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) + { + var pathBase = Configuration["PATH_BASE"]; + + if (!string.IsNullOrEmpty(pathBase)) + { + loggerFactory.CreateLogger().LogDebug("Using PATH BASE '{pathBase}'", pathBase); + app.UsePathBase(pathBase); + } + + app.UseHealthChecks("/hc", new HealthCheckOptions() + { + Predicate = _ => true, + ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse + }); + + app.UseHealthChecks("/liveness", new HealthCheckOptions + { + Predicate = r => r.Name.Contains("self") + }); + + app.UseCors("CorsPolicy"); + + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + else + { + // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. + app.UseHsts(); + } + + app.UseAuthentication(); + app.UseHttpsRedirection(); + app.UseMvc(); + + app.UseSwagger().UseSwaggerUI(c => + { + c.SwaggerEndpoint($"{ (!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty) }/swagger/v1/swagger.json", "Purchase BFF V1"); + + c.OAuthClientId("Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregatorwaggerui"); + c.OAuthClientSecret(string.Empty); + c.OAuthRealm(string.Empty); + c.OAuthAppName("Purchase BFF Swagger UI"); + }); + } + } + + public static class ServiceCollectionExtensions + { + public static IServiceCollection AddCustomMvc(this IServiceCollection services, IConfiguration configuration) + { + services.AddOptions(); + services.Configure(configuration.GetSection("urls")); + + services.AddMvc() + .SetCompatibilityVersion(CompatibilityVersion.Version_2_2); + + services.AddSwaggerGen(options => + { + options.DescribeAllEnumsAsStrings(); + options.SwaggerDoc("v1", new Swashbuckle.AspNetCore.Swagger.Info + { + Title = "Shopping Aggregator for Mobile Clients", + Version = "v1", + Description = "Shopping Aggregator for Mobile Clients", + TermsOfService = "Terms Of Service" + }); + + options.AddSecurityDefinition("oauth2", new OAuth2Scheme + { + Type = "oauth2", + Flow = "implicit", + AuthorizationUrl = $"{configuration.GetValue("IdentityUrlExternal")}/connect/authorize", + TokenUrl = $"{configuration.GetValue("IdentityUrlExternal")}/connect/token", + Scopes = new Dictionary() + { + { "mobileshoppingagg", "Shopping Aggregator for Mobile Clients" } + } + }); + + options.OperationFilter(); + }); + + services.AddCors(options => + { + options.AddPolicy("CorsPolicy", + builder => builder + .AllowAnyMethod() + .AllowAnyHeader() + .SetIsOriginAllowed((host) => true) + .AllowCredentials()); + }); + + return services; + } + public static IServiceCollection AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration) + { + JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); + var identityUrl = configuration.GetValue("urls:identity"); + + services.AddAuthentication(options => + { + options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; + + }) + .AddJwtBearer(options => + { + options.Authority = identityUrl; + options.RequireHttpsMetadata = false; + options.Audience = "mobileshoppingagg"; + options.Events = new JwtBearerEvents() + { + OnAuthenticationFailed = async ctx => + { + await Task.Run(() => { }); + }, + OnTokenValidated = async ctx => + { + await Task.Run(() => { }); + } + }; + }); + + return services; + } + + public static IServiceCollection AddHttpServices(this IServiceCollection services) + { + //register delegating handlers + services.AddTransient(); + services.AddSingleton(); + + //register http services + services.AddHttpClient() + .AddHttpMessageHandler() + .AddPolicyHandler(GetRetryPolicy()) + .AddPolicyHandler(GetCircuitBreakerPolicy()); + + services.AddHttpClient() + .AddPolicyHandler(GetRetryPolicy()) + .AddPolicyHandler(GetCircuitBreakerPolicy()); + + services.AddHttpClient() + .AddPolicyHandler(GetRetryPolicy()) + .AddPolicyHandler(GetCircuitBreakerPolicy()); + + return services; + } + + private static IAsyncPolicy GetRetryPolicy() + => HttpPolicyExtensions + .HandleTransientHttpError() + .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound) + .WaitAndRetryAsync(6, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))); + + private static IAsyncPolicy GetCircuitBreakerPolicy() + => HttpPolicyExtensions + .HandleTransientHttpError() + .CircuitBreakerAsync(5, TimeSpan.FromSeconds(30)); + } } diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs index 6d3da29b7..82220b62d 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs @@ -1,5 +1,7 @@ -using Microsoft.AspNetCore.Authentication.JwtBearer; +using HealthChecks.UI.Client; +using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Diagnostics.HealthChecks; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; @@ -9,212 +11,207 @@ using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Infrastructure; using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Diagnostics.HealthChecks; using Microsoft.Extensions.Logging; using Polly; using Polly.Extensions.Http; -using Polly.Timeout; using Swashbuckle.AspNetCore.Swagger; using System; using System.Collections.Generic; using System.IdentityModel.Tokens.Jwt; using System.Net.Http; -using HealthChecks.UI.Client; -using Microsoft.AspNetCore.Diagnostics.HealthChecks; -using Microsoft.Extensions.Diagnostics.HealthChecks; +using System.Threading.Tasks; namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator { - public class Startup - { - public Startup(IConfiguration configuration) - { - Configuration = configuration; - } - - public IConfiguration Configuration { get; } - - // This method gets called by the runtime. Use this method to add services to the container. - public void ConfigureServices(IServiceCollection services) - { - services.AddHealthChecks() - .AddCheck("self", () => HealthCheckResult.Healthy()) - .AddUrlGroup(new Uri(Configuration["CatalogUrlHC"]), name: "catalogapi-check", tags: new string[] { "catalogapi" }) - .AddUrlGroup(new Uri(Configuration["OrderingUrlHC"]), name: "orderingapi-check", tags: new string[] { "orderingapi" }) - .AddUrlGroup(new Uri(Configuration["BasketUrlHC"]), name: "basketapi-check", tags: new string[] { "basketapi" }) - .AddUrlGroup(new Uri(Configuration["IdentityUrlHC"]), name: "identityapi-check", tags: new string[] { "identityapi" }) - .AddUrlGroup(new Uri(Configuration["MarketingUrlHC"]), name: "marketingapi-check", tags: new string[] { "marketingapi" }) - .AddUrlGroup(new Uri(Configuration["PaymentUrlHC"]), name: "paymentapi-check", tags: new string[] { "paymentapi" }) - .AddUrlGroup(new Uri(Configuration["LocationUrlHC"]), name: "locationapi-check", tags: new string[] { "locationapi" }); - - services.AddCustomMvc(Configuration) - .AddCustomAuthentication(Configuration) - .AddApplicationServices(); - } - - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) - { - var pathBase = Configuration["PATH_BASE"]; - if (!string.IsNullOrEmpty(pathBase)) - { - loggerFactory.CreateLogger().LogDebug("Using PATH BASE '{pathBase}'", pathBase); - app.UsePathBase(pathBase); - } - - app.UseHealthChecks("/hc", new HealthCheckOptions() - { - Predicate = _ => true, - ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse - }); - - app.UseHealthChecks("/liveness", new HealthCheckOptions - { - Predicate = r => r.Name.Contains("self") - }); - - app.UseCors("CorsPolicy"); - - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } - else - { - // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. - app.UseHsts(); - } - - app.UseAuthentication(); - app.UseHttpsRedirection(); - app.UseMvc(); - - app.UseSwagger() - .UseSwaggerUI(c => - { - c.SwaggerEndpoint($"{ (!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty) }/swagger/v1/swagger.json", "Purchase BFF V1"); - //c.ConfigureOAuth2("Microsoft.eShopOnContainers.Web.Shopping.HttpAggregatorwaggerui", "", "", "Purchase BFF Swagger UI"); - }); - } - } - - public static class ServiceCollectionExtensions - { - public static IServiceCollection AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration) - { - JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); - var identityUrl = configuration.GetValue("urls:identity"); - services.AddAuthentication(options => - { - options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; - options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; - - }).AddJwtBearer(options => - { - options.Authority = identityUrl; - options.RequireHttpsMetadata = false; - options.Audience = "webshoppingagg"; - options.Events = new JwtBearerEvents() - { - OnAuthenticationFailed = async ctx => - { - int i = 0; - }, - OnTokenValidated = async ctx => - { - int i = 0; - } - }; - }); - - return services; - } - - public static IServiceCollection AddCustomMvc(this IServiceCollection services, IConfiguration configuration) - { - services.AddOptions(); - services.Configure(configuration.GetSection("urls")); - - services.AddMvc() - .SetCompatibilityVersion(CompatibilityVersion.Version_2_2); - - services.AddSwaggerGen(options => - { - options.DescribeAllEnumsAsStrings(); - options.SwaggerDoc("v1", new Swashbuckle.AspNetCore.Swagger.Info - { - Title = "Shopping Aggregator for Web Clients", - Version = "v1", - Description = "Shopping Aggregator for Web Clients", - TermsOfService = "Terms Of Service" - }); - - options.AddSecurityDefinition("oauth2", new OAuth2Scheme - { - Type = "oauth2", - Flow = "implicit", - AuthorizationUrl = $"{configuration.GetValue("IdentityUrlExternal")}/connect/authorize", - TokenUrl = $"{configuration.GetValue("IdentityUrlExternal")}/connect/token", - Scopes = new Dictionary() - { - { "webshoppingagg", "Shopping Aggregator for Web Clients" } - } - }); - - options.OperationFilter(); - }); - - services.AddCors(options => - { - options.AddPolicy("CorsPolicy", - builder => builder - .SetIsOriginAllowed((host) => true) - .AllowAnyMethod() - .AllowAnyHeader() - .AllowCredentials()); - }); - - return services; - } - public static IServiceCollection AddApplicationServices(this IServiceCollection services) - { - //register delegating handlers - services.AddTransient(); - services.AddSingleton(); - - //register http services - - services.AddHttpClient() - .AddHttpMessageHandler() - .AddPolicyHandler(GetRetryPolicy()) - .AddPolicyHandler(GetCircuitBreakerPolicy()); - - services.AddHttpClient() - .AddPolicyHandler(GetRetryPolicy()) - .AddPolicyHandler(GetCircuitBreakerPolicy()); - - services.AddHttpClient() - .AddHttpMessageHandler() - .AddPolicyHandler(GetRetryPolicy()) - .AddPolicyHandler(GetCircuitBreakerPolicy()); - - - return services; - } - - static IAsyncPolicy GetRetryPolicy() - { - return HttpPolicyExtensions - .HandleTransientHttpError() - .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound) - .WaitAndRetryAsync(6, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))); - - } - - static IAsyncPolicy GetCircuitBreakerPolicy() - { - return HttpPolicyExtensions - .HandleTransientHttpError() - .CircuitBreakerAsync(5, TimeSpan.FromSeconds(30)); - } - } + public class Startup + { + public Startup(IConfiguration configuration) + => Configuration = configuration; + + public IConfiguration Configuration { get; } + + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + services.AddHealthChecks() + .AddCheck("self", () => HealthCheckResult.Healthy()) + .AddUrlGroup(new Uri(Configuration["CatalogUrlHC"]), name: "catalogapi-check", tags: new string[] { "catalogapi" }) + .AddUrlGroup(new Uri(Configuration["OrderingUrlHC"]), name: "orderingapi-check", tags: new string[] { "orderingapi" }) + .AddUrlGroup(new Uri(Configuration["BasketUrlHC"]), name: "basketapi-check", tags: new string[] { "basketapi" }) + .AddUrlGroup(new Uri(Configuration["IdentityUrlHC"]), name: "identityapi-check", tags: new string[] { "identityapi" }) + .AddUrlGroup(new Uri(Configuration["MarketingUrlHC"]), name: "marketingapi-check", tags: new string[] { "marketingapi" }) + .AddUrlGroup(new Uri(Configuration["PaymentUrlHC"]), name: "paymentapi-check", tags: new string[] { "paymentapi" }) + .AddUrlGroup(new Uri(Configuration["LocationUrlHC"]), name: "locationapi-check", tags: new string[] { "locationapi" }); + + services.AddCustomMvc(Configuration) + .AddCustomAuthentication(Configuration) + .AddApplicationServices(); + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) + { + var pathBase = Configuration["PATH_BASE"]; + if (!string.IsNullOrEmpty(pathBase)) + { + loggerFactory.CreateLogger().LogDebug("Using PATH BASE '{pathBase}'", pathBase); + app.UsePathBase(pathBase); + } + + app.UseHealthChecks("/hc", new HealthCheckOptions() + { + Predicate = _ => true, + ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse + }); + + app.UseHealthChecks("/liveness", new HealthCheckOptions + { + Predicate = r => r.Name.Contains("self") + }); + + app.UseCors("CorsPolicy"); + + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + else + { + // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. + app.UseHsts(); + } + + app.UseAuthentication(); + app.UseHttpsRedirection(); + app.UseMvc(); + + app.UseSwagger() + .UseSwaggerUI(c => + { + c.SwaggerEndpoint($"{ (!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty) }/swagger/v1/swagger.json", "Purchase BFF V1"); + //c.ConfigureOAuth2("Microsoft.eShopOnContainers.Web.Shopping.HttpAggregatorwaggerui", "", "", "Purchase BFF Swagger UI"); + }); + } + } + + public static class ServiceCollectionExtensions + { + public static IServiceCollection AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration) + { + JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); + var identityUrl = configuration.GetValue("urls:identity"); + services.AddAuthentication(options => + { + options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; + + }).AddJwtBearer(options => + { + options.Authority = identityUrl; + options.RequireHttpsMetadata = false; + options.Audience = "webshoppingagg"; + options.Events = new JwtBearerEvents() + { + OnAuthenticationFailed = async ctx => + { + await Task.Run(() => + { + }); + }, + OnTokenValidated = async ctx => + { + await Task.Run(() => + { + }); + } + }; + }); + + return services; + } + + public static IServiceCollection AddCustomMvc(this IServiceCollection services, IConfiguration configuration) + { + services.AddOptions(); + services.Configure(configuration.GetSection("urls")); + + services.AddMvc() + .SetCompatibilityVersion(CompatibilityVersion.Version_2_2); + + services.AddSwaggerGen(options => + { + options.DescribeAllEnumsAsStrings(); + options.SwaggerDoc("v1", new Swashbuckle.AspNetCore.Swagger.Info + { + Title = "Shopping Aggregator for Web Clients", + Version = "v1", + Description = "Shopping Aggregator for Web Clients", + TermsOfService = "Terms Of Service" + }); + + options.AddSecurityDefinition("oauth2", new OAuth2Scheme + { + Type = "oauth2", + Flow = "implicit", + AuthorizationUrl = $"{configuration.GetValue("IdentityUrlExternal")}/connect/authorize", + TokenUrl = $"{configuration.GetValue("IdentityUrlExternal")}/connect/token", + Scopes = new Dictionary() + { + { "webshoppingagg", "Shopping Aggregator for Web Clients" } + } + }); + + options.OperationFilter(); + }); + + services.AddCors(options => + { + options.AddPolicy("CorsPolicy", + builder => builder + .SetIsOriginAllowed((host) => true) + .AllowAnyMethod() + .AllowAnyHeader() + .AllowCredentials()); + }); + + return services; + } + public static IServiceCollection AddApplicationServices(this IServiceCollection services) + { + //register delegating handlers + services.AddTransient(); + services.AddSingleton(); + + //register http services + + services.AddHttpClient() + .AddHttpMessageHandler() + .AddPolicyHandler(GetRetryPolicy()) + .AddPolicyHandler(GetCircuitBreakerPolicy()); + + services.AddHttpClient() + .AddPolicyHandler(GetRetryPolicy()) + .AddPolicyHandler(GetCircuitBreakerPolicy()); + + services.AddHttpClient() + .AddHttpMessageHandler() + .AddPolicyHandler(GetRetryPolicy()) + .AddPolicyHandler(GetCircuitBreakerPolicy()); + + + return services; + } + + private static IAsyncPolicy GetRetryPolicy() + => HttpPolicyExtensions + .HandleTransientHttpError() + .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound) + .WaitAndRetryAsync(6, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))); + + private static IAsyncPolicy GetCircuitBreakerPolicy() + => HttpPolicyExtensions + .HandleTransientHttpError() + .CircuitBreakerAsync(5, TimeSpan.FromSeconds(30)); + } } diff --git a/src/Services/Webhooks/Webhooks.API/IntegrationEvents/ProductPriceChangedIntegrationEventHandler.cs b/src/Services/Webhooks/Webhooks.API/IntegrationEvents/ProductPriceChangedIntegrationEventHandler.cs index 10e1542c8..f887963af 100644 --- a/src/Services/Webhooks/Webhooks.API/IntegrationEvents/ProductPriceChangedIntegrationEventHandler.cs +++ b/src/Services/Webhooks/Webhooks.API/IntegrationEvents/ProductPriceChangedIntegrationEventHandler.cs @@ -1,16 +1,11 @@ using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; -using System; -using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; namespace Webhooks.API.IntegrationEvents { - public class ProductPriceChangedIntegrationEventHandler : IIntegrationEventHandler - { - public async Task Handle(ProductPriceChangedIntegrationEvent @event) - { - int i = 0; - } - } + public class ProductPriceChangedIntegrationEventHandler : IIntegrationEventHandler + { + public async Task Handle(ProductPriceChangedIntegrationEvent @event) + => await Task.Run(() => { }); + } }