Fix formatting
This commit is contained in:
		
							parent
							
								
									9d38de0c83
								
							
						
					
					
						commit
						27aaed0a00
					
				@ -1,4 +1,4 @@
 | 
				
			|||||||
await BuildWebHost(args).RunAsync();
 | 
					await BuildWebHost(args).RunAsync();
 | 
				
			||||||
IWebHost BuildWebHost(string[] args) =>
 | 
					IWebHost BuildWebHost(string[] args) =>
 | 
				
			||||||
    WebHost
 | 
					    WebHost
 | 
				
			||||||
        .CreateDefaultBuilder(args)
 | 
					        .CreateDefaultBuilder(args)
 | 
				
			||||||
 | 
				
			|||||||
@ -3,12 +3,14 @@ using Microsoft.Azure.Amqp.Framing;
 | 
				
			|||||||
using Microsoft.Extensions.Configuration;
 | 
					using Microsoft.Extensions.Configuration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var appName = "Basket.API";
 | 
					var appName = "Basket.API";
 | 
				
			||||||
var builder = WebApplication.CreateBuilder(new WebApplicationOptions {
 | 
					var builder = WebApplication.CreateBuilder(new WebApplicationOptions
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    Args = args,
 | 
					    Args = args,
 | 
				
			||||||
    ApplicationName = typeof(Program).Assembly.FullName,
 | 
					    ApplicationName = typeof(Program).Assembly.FullName,
 | 
				
			||||||
    ContentRootPath = Directory.GetCurrentDirectory()
 | 
					    ContentRootPath = Directory.GetCurrentDirectory()
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
if (builder.Configuration.GetValue<bool>("UseVault", false)) {
 | 
					if (builder.Configuration.GetValue<bool>("UseVault", false))
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    TokenCredential credential = new ClientSecretCredential(
 | 
					    TokenCredential credential = new ClientSecretCredential(
 | 
				
			||||||
           builder.Configuration["Vault:TenantId"],
 | 
					           builder.Configuration["Vault:TenantId"],
 | 
				
			||||||
        builder.Configuration["Vault:ClientId"],
 | 
					        builder.Configuration["Vault:ClientId"],
 | 
				
			||||||
@ -16,29 +18,36 @@ if (builder.Configuration.GetValue<bool>("UseVault", false)) {
 | 
				
			|||||||
    builder.Configuration.AddAzureKeyVault(new Uri($"https://{builder.Configuration["Vault:Name"]}.vault.azure.net/"), credential);
 | 
					    builder.Configuration.AddAzureKeyVault(new Uri($"https://{builder.Configuration["Vault:Name"]}.vault.azure.net/"), credential);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
builder.Services.AddGrpc(options => {
 | 
					builder.Services.AddGrpc(options =>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    options.EnableDetailedErrors = true;
 | 
					    options.EnableDetailedErrors = true;
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
builder.Services.AddApplicationInsightsTelemetry(builder.Configuration);
 | 
					builder.Services.AddApplicationInsightsTelemetry(builder.Configuration);
 | 
				
			||||||
builder.Services.AddApplicationInsightsKubernetesEnricher();
 | 
					builder.Services.AddApplicationInsightsKubernetesEnricher();
 | 
				
			||||||
builder.Services.AddControllers(options => {
 | 
					builder.Services.AddControllers(options =>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    options.Filters.Add(typeof(HttpGlobalExceptionFilter));
 | 
					    options.Filters.Add(typeof(HttpGlobalExceptionFilter));
 | 
				
			||||||
    options.Filters.Add(typeof(ValidateModelStateFilter));
 | 
					    options.Filters.Add(typeof(ValidateModelStateFilter));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}) // Added for functional tests
 | 
					}) // Added for functional tests
 | 
				
			||||||
            .AddApplicationPart(typeof(BasketController).Assembly)
 | 
					            .AddApplicationPart(typeof(BasketController).Assembly)
 | 
				
			||||||
            .AddJsonOptions(options => options.JsonSerializerOptions.WriteIndented = true);
 | 
					            .AddJsonOptions(options => options.JsonSerializerOptions.WriteIndented = true);
 | 
				
			||||||
builder.Services.AddSwaggerGen(options => {
 | 
					builder.Services.AddSwaggerGen(options =>
 | 
				
			||||||
    options.SwaggerDoc("v1", new OpenApiInfo {
 | 
					{
 | 
				
			||||||
 | 
					    options.SwaggerDoc("v1", new OpenApiInfo
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        Title = "eShopOnContainers - Basket HTTP API",
 | 
					        Title = "eShopOnContainers - Basket HTTP API",
 | 
				
			||||||
        Version = "v1",
 | 
					        Version = "v1",
 | 
				
			||||||
        Description = "The Basket Service HTTP API"
 | 
					        Description = "The Basket Service HTTP API"
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme {
 | 
					    options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        Type = SecuritySchemeType.OAuth2,
 | 
					        Type = SecuritySchemeType.OAuth2,
 | 
				
			||||||
        Flows = new OpenApiOAuthFlows() {
 | 
					        Flows = new OpenApiOAuthFlows()
 | 
				
			||||||
            Implicit = new OpenApiOAuthFlow() {
 | 
					        {
 | 
				
			||||||
 | 
					            Implicit = new OpenApiOAuthFlow()
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                AuthorizationUrl = new Uri($"{builder.Configuration.GetValue<string>("IdentityUrlExternal")}/connect/authorize"),
 | 
					                AuthorizationUrl = new Uri($"{builder.Configuration.GetValue<string>("IdentityUrlExternal")}/connect/authorize"),
 | 
				
			||||||
                TokenUrl = new Uri($"{builder.Configuration.GetValue<string>("IdentityUrlExternal")}/connect/token"),
 | 
					                TokenUrl = new Uri($"{builder.Configuration.GetValue<string>("IdentityUrlExternal")}/connect/token"),
 | 
				
			||||||
                Scopes = new Dictionary<string, string>() { { "basket", "Basket API" } }
 | 
					                Scopes = new Dictionary<string, string>() { { "basket", "Basket API" } }
 | 
				
			||||||
@ -54,14 +63,17 @@ JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub");
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
var identityUrl = builder.Configuration.GetValue<string>("IdentityUrl");
 | 
					var identityUrl = builder.Configuration.GetValue<string>("IdentityUrl");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
builder.Services.AddAuthentication("Bearer").AddJwtBearer(options => {
 | 
					builder.Services.AddAuthentication("Bearer").AddJwtBearer(options =>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    options.Authority = identityUrl;
 | 
					    options.Authority = identityUrl;
 | 
				
			||||||
    options.RequireHttpsMetadata = false;
 | 
					    options.RequireHttpsMetadata = false;
 | 
				
			||||||
    options.Audience = "basket";
 | 
					    options.Audience = "basket";
 | 
				
			||||||
    options.TokenValidationParameters.ValidateAudience = false;
 | 
					    options.TokenValidationParameters.ValidateAudience = false;
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
builder.Services.AddAuthorization(options => {
 | 
					builder.Services.AddAuthorization(options =>
 | 
				
			||||||
    options.AddPolicy("ApiScope", policy => {
 | 
					{
 | 
				
			||||||
 | 
					    options.AddPolicy("ApiScope", policy =>
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        policy.RequireAuthenticatedUser();
 | 
					        policy.RequireAuthenticatedUser();
 | 
				
			||||||
        policy.RequireClaim("scope", "basket");
 | 
					        policy.RequireClaim("scope", "basket");
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
@ -71,7 +83,8 @@ builder.Services.AddCustomHealthCheck(builder.Configuration);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
builder.Services.Configure<BasketSettings>(builder.Configuration);
 | 
					builder.Services.Configure<BasketSettings>(builder.Configuration);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
builder.Services.AddSingleton<ConnectionMultiplexer>(sp => {
 | 
					builder.Services.AddSingleton<ConnectionMultiplexer>(sp =>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    var settings = sp.GetRequiredService<IOptions<BasketSettings>>().Value;
 | 
					    var settings = sp.GetRequiredService<IOptions<BasketSettings>>().Value;
 | 
				
			||||||
    var configuration = ConfigurationOptions.Parse(settings.ConnectionString, true);
 | 
					    var configuration = ConfigurationOptions.Parse(settings.ConnectionString, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -79,32 +92,40 @@ builder.Services.AddSingleton<ConnectionMultiplexer>(sp => {
 | 
				
			|||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if (builder.Configuration.GetValue<bool>("AzureServiceBusEnabled")) {
 | 
					if (builder.Configuration.GetValue<bool>("AzureServiceBusEnabled"))
 | 
				
			||||||
    builder.Services.AddSingleton<IServiceBusPersisterConnection>(sp => {
 | 
					{
 | 
				
			||||||
 | 
					    builder.Services.AddSingleton<IServiceBusPersisterConnection>(sp =>
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        var serviceBusConnectionString = builder.Configuration["EventBusConnection"];
 | 
					        var serviceBusConnectionString = builder.Configuration["EventBusConnection"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return new DefaultServiceBusPersisterConnection(serviceBusConnectionString);
 | 
					        return new DefaultServiceBusPersisterConnection(serviceBusConnectionString);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
else {
 | 
					else
 | 
				
			||||||
    builder.Services.AddSingleton<IRabbitMQPersistentConnection>(sp => {
 | 
					{
 | 
				
			||||||
 | 
					    builder.Services.AddSingleton<IRabbitMQPersistentConnection>(sp =>
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        var logger = sp.GetRequiredService<ILogger<DefaultRabbitMQPersistentConnection>>();
 | 
					        var logger = sp.GetRequiredService<ILogger<DefaultRabbitMQPersistentConnection>>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        var factory = new ConnectionFactory() {
 | 
					        var factory = new ConnectionFactory()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
            HostName = builder.Configuration["EventBusConnection"],
 | 
					            HostName = builder.Configuration["EventBusConnection"],
 | 
				
			||||||
            DispatchConsumersAsync = true
 | 
					            DispatchConsumersAsync = true
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!string.IsNullOrEmpty(builder.Configuration["EventBusUserName"])) {
 | 
					        if (!string.IsNullOrEmpty(builder.Configuration["EventBusUserName"]))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
            factory.UserName = builder.Configuration["EventBusUserName"];
 | 
					            factory.UserName = builder.Configuration["EventBusUserName"];
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!string.IsNullOrEmpty(builder.Configuration["EventBusPassword"])) {
 | 
					        if (!string.IsNullOrEmpty(builder.Configuration["EventBusPassword"]))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
            factory.Password = builder.Configuration["EventBusPassword"];
 | 
					            factory.Password = builder.Configuration["EventBusPassword"];
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        var retryCount = 5;
 | 
					        var retryCount = 5;
 | 
				
			||||||
        if (!string.IsNullOrEmpty(builder.Configuration["EventBusRetryCount"])) {
 | 
					        if (!string.IsNullOrEmpty(builder.Configuration["EventBusRetryCount"]))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
            retryCount = int.Parse(builder.Configuration["EventBusRetryCount"]);
 | 
					            retryCount = int.Parse(builder.Configuration["EventBusRetryCount"]);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -112,7 +133,8 @@ else {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
builder.Services.RegisterEventBus(builder.Configuration);
 | 
					builder.Services.RegisterEventBus(builder.Configuration);
 | 
				
			||||||
builder.Services.AddCors(options => {
 | 
					builder.Services.AddCors(options =>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    options.AddPolicy("CorsPolicy",
 | 
					    options.AddPolicy("CorsPolicy",
 | 
				
			||||||
        builder => builder
 | 
					        builder => builder
 | 
				
			||||||
        .SetIsOriginAllowed((host) => true)
 | 
					        .SetIsOriginAllowed((host) => true)
 | 
				
			||||||
@ -128,39 +150,47 @@ builder.Services.AddOptions();
 | 
				
			|||||||
builder.Configuration.SetBasePath(Directory.GetCurrentDirectory());
 | 
					builder.Configuration.SetBasePath(Directory.GetCurrentDirectory());
 | 
				
			||||||
builder.Configuration.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
 | 
					builder.Configuration.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
 | 
				
			||||||
builder.Configuration.AddEnvironmentVariables();
 | 
					builder.Configuration.AddEnvironmentVariables();
 | 
				
			||||||
builder.WebHost.UseKestrel(options => {
 | 
					builder.WebHost.UseKestrel(options =>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    var ports = GetDefinedPorts(builder.Configuration);
 | 
					    var ports = GetDefinedPorts(builder.Configuration);
 | 
				
			||||||
    options.Listen(IPAddress.Any, ports.httpPort, listenOptions => {
 | 
					    options.Listen(IPAddress.Any, ports.httpPort, listenOptions =>
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
 | 
					        listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    options.Listen(IPAddress.Any, ports.grpcPort, listenOptions => {
 | 
					    options.Listen(IPAddress.Any, ports.grpcPort, listenOptions =>
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        listenOptions.Protocols = HttpProtocols.Http2;
 | 
					        listenOptions.Protocols = HttpProtocols.Http2;
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
builder.WebHost.CaptureStartupErrors(false);
 | 
					builder.WebHost.CaptureStartupErrors(false);
 | 
				
			||||||
builder.Host.UseSerilog(CreateSerilogLogger(builder.Configuration));
 | 
					builder.Host.UseSerilog(CreateSerilogLogger(builder.Configuration));
 | 
				
			||||||
builder.WebHost.UseFailing(options => {
 | 
					builder.WebHost.UseFailing(options =>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    options.ConfigPath = "/Failing";
 | 
					    options.ConfigPath = "/Failing";
 | 
				
			||||||
    options.NotFilteredPaths.AddRange(new[] { "/hc", "/liveness" });
 | 
					    options.NotFilteredPaths.AddRange(new[] { "/hc", "/liveness" });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
var app = builder.Build();
 | 
					var app = builder.Build();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if (app.Environment.IsDevelopment()) {
 | 
					if (app.Environment.IsDevelopment())
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    app.UseDeveloperExceptionPage();
 | 
					    app.UseDeveloperExceptionPage();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
else {
 | 
					else
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    app.UseExceptionHandler("/Home/Error");
 | 
					    app.UseExceptionHandler("/Home/Error");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var pathBase = app.Configuration["PATH_BASE"];
 | 
					var pathBase = app.Configuration["PATH_BASE"];
 | 
				
			||||||
if (!string.IsNullOrEmpty(pathBase)) {
 | 
					if (!string.IsNullOrEmpty(pathBase))
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    app.UsePathBase(pathBase);
 | 
					    app.UsePathBase(pathBase);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
app.UseSwagger()
 | 
					app.UseSwagger()
 | 
				
			||||||
            .UseSwaggerUI(setup => {
 | 
					            .UseSwaggerUI(setup =>
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                setup.SwaggerEndpoint($"{(!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty)}/swagger/v1/swagger.json", "Basket.API V1");
 | 
					                setup.SwaggerEndpoint($"{(!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty)}/swagger/v1/swagger.json", "Basket.API V1");
 | 
				
			||||||
                setup.OAuthClientId("basketswaggerui");
 | 
					                setup.OAuthClientId("basketswaggerui");
 | 
				
			||||||
                setup.OAuthAppName("Basket Swagger UI");
 | 
					                setup.OAuthAppName("Basket Swagger UI");
 | 
				
			||||||
@ -176,26 +206,32 @@ app.UseStaticFiles();
 | 
				
			|||||||
app.MapGrpcService<BasketService>();
 | 
					app.MapGrpcService<BasketService>();
 | 
				
			||||||
app.MapDefaultControllerRoute();
 | 
					app.MapDefaultControllerRoute();
 | 
				
			||||||
app.MapControllers();
 | 
					app.MapControllers();
 | 
				
			||||||
app.MapGet("/_proto/", async ctx => {
 | 
					app.MapGet("/_proto/", async ctx =>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    ctx.Response.ContentType = "text/plain";
 | 
					    ctx.Response.ContentType = "text/plain";
 | 
				
			||||||
    using var fs = new FileStream(Path.Combine(app.Environment.ContentRootPath, "Proto", "basket.proto"), FileMode.Open, FileAccess.Read);
 | 
					    using var fs = new FileStream(Path.Combine(app.Environment.ContentRootPath, "Proto", "basket.proto"), FileMode.Open, FileAccess.Read);
 | 
				
			||||||
    using var sr = new StreamReader(fs);
 | 
					    using var sr = new StreamReader(fs);
 | 
				
			||||||
    while (!sr.EndOfStream) {
 | 
					    while (!sr.EndOfStream)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        var line = await sr.ReadLineAsync();
 | 
					        var line = await sr.ReadLineAsync();
 | 
				
			||||||
        if (line != "/* >>" || line != "<< */") {
 | 
					        if (line != "/* >>" || line != "<< */")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
            await ctx.Response.WriteAsync(line);
 | 
					            await ctx.Response.WriteAsync(line);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
app.MapHealthChecks("/hc", new HealthCheckOptions() {
 | 
					app.MapHealthChecks("/hc", new HealthCheckOptions()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    Predicate = _ => true,
 | 
					    Predicate = _ => true,
 | 
				
			||||||
    ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
 | 
					    ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
app.MapHealthChecks("/liveness", new HealthCheckOptions {
 | 
					app.MapHealthChecks("/liveness", new HealthCheckOptions
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    Predicate = r => r.Name.Contains("self")
 | 
					    Predicate = r => r.Name.Contains("self")
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
ConfigureEventBus(app);
 | 
					ConfigureEventBus(app);
 | 
				
			||||||
try {
 | 
					try
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    Log.Information("Configuring web host ({ApplicationContext})...", Program.AppName);
 | 
					    Log.Information("Configuring web host ({ApplicationContext})...", Program.AppName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -204,15 +240,18 @@ try {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
catch (Exception ex) {
 | 
					catch (Exception ex)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    Log.Fatal(ex, "Program terminated unexpectedly ({ApplicationContext})!", Program.AppName);
 | 
					    Log.Fatal(ex, "Program terminated unexpectedly ({ApplicationContext})!", Program.AppName);
 | 
				
			||||||
    return 1;
 | 
					    return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
finally {
 | 
					finally
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    Log.CloseAndFlush();
 | 
					    Log.CloseAndFlush();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Serilog.ILogger CreateSerilogLogger(IConfiguration configuration) {
 | 
					Serilog.ILogger CreateSerilogLogger(IConfiguration configuration)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    var seqServerUrl = configuration["Serilog:SeqServerUrl"];
 | 
					    var seqServerUrl = configuration["Serilog:SeqServerUrl"];
 | 
				
			||||||
    var logstashUrl = configuration["Serilog:LogstashgUrl"];
 | 
					    var logstashUrl = configuration["Serilog:LogstashgUrl"];
 | 
				
			||||||
    return new LoggerConfiguration()
 | 
					    return new LoggerConfiguration()
 | 
				
			||||||
@ -226,30 +265,37 @@ Serilog.ILogger CreateSerilogLogger(IConfiguration configuration) {
 | 
				
			|||||||
        .CreateLogger();
 | 
					        .CreateLogger();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(int httpPort, int grpcPort) GetDefinedPorts(IConfiguration config) {
 | 
					(int httpPort, int grpcPort) GetDefinedPorts(IConfiguration config)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    var grpcPort = config.GetValue("GRPC_PORT", 5001);
 | 
					    var grpcPort = config.GetValue("GRPC_PORT", 5001);
 | 
				
			||||||
    var port = config.GetValue("PORT", 80);
 | 
					    var port = config.GetValue("PORT", 80);
 | 
				
			||||||
    return (port, grpcPort);
 | 
					    return (port, grpcPort);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
void ConfigureEventBus(IApplicationBuilder app) {
 | 
					void ConfigureEventBus(IApplicationBuilder app)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    var eventBus = app.ApplicationServices.GetRequiredService<IEventBus>();
 | 
					    var eventBus = app.ApplicationServices.GetRequiredService<IEventBus>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    eventBus.Subscribe<ProductPriceChangedIntegrationEvent, ProductPriceChangedIntegrationEventHandler>();
 | 
					    eventBus.Subscribe<ProductPriceChangedIntegrationEvent, ProductPriceChangedIntegrationEventHandler>();
 | 
				
			||||||
    eventBus.Subscribe<OrderStartedIntegrationEvent, OrderStartedIntegrationEventHandler>();
 | 
					    eventBus.Subscribe<OrderStartedIntegrationEvent, OrderStartedIntegrationEventHandler>();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
public partial class Program {
 | 
					public partial class Program
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static string Namespace = typeof(Program).Assembly.GetName().Name;
 | 
					    public static string Namespace = typeof(Program).Assembly.GetName().Name;
 | 
				
			||||||
    public static string AppName = Namespace.Substring(Namespace.LastIndexOf('.', Namespace.LastIndexOf('.') - 1) + 1);
 | 
					    public static string AppName = Namespace.Substring(Namespace.LastIndexOf('.', Namespace.LastIndexOf('.') - 1) + 1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public static class CustomExtensionMethods {
 | 
					public static class CustomExtensionMethods
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static IServiceCollection RegisterEventBus(this IServiceCollection services, IConfiguration configuration) {
 | 
					    public static IServiceCollection RegisterEventBus(this IServiceCollection services, IConfiguration configuration)
 | 
				
			||||||
        if (configuration.GetValue<bool>("AzureServiceBusEnabled")) {
 | 
					    {
 | 
				
			||||||
            services.AddSingleton<IEventBus, EventBusServiceBus>(sp => {
 | 
					        if (configuration.GetValue<bool>("AzureServiceBusEnabled"))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            services.AddSingleton<IEventBus, EventBusServiceBus>(sp =>
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                var serviceBusPersisterConnection = sp.GetRequiredService<IServiceBusPersisterConnection>();
 | 
					                var serviceBusPersisterConnection = sp.GetRequiredService<IServiceBusPersisterConnection>();
 | 
				
			||||||
                var logger = sp.GetRequiredService<ILogger<EventBusServiceBus>>();
 | 
					                var logger = sp.GetRequiredService<ILogger<EventBusServiceBus>>();
 | 
				
			||||||
                var eventBusSubscriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>();
 | 
					                var eventBusSubscriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>();
 | 
				
			||||||
@ -259,15 +305,18 @@ public static class CustomExtensionMethods {
 | 
				
			|||||||
                    eventBusSubscriptionsManager, sp, subscriptionName);
 | 
					                    eventBusSubscriptionsManager, sp, subscriptionName);
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else {
 | 
					        else
 | 
				
			||||||
            services.AddSingleton<IEventBus, EventBusRabbitMQ>(sp => {
 | 
					        {
 | 
				
			||||||
 | 
					            services.AddSingleton<IEventBus, EventBusRabbitMQ>(sp =>
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                var subscriptionClientName = configuration["SubscriptionClientName"];
 | 
					                var subscriptionClientName = configuration["SubscriptionClientName"];
 | 
				
			||||||
                var rabbitMQPersistentConnection = sp.GetRequiredService<IRabbitMQPersistentConnection>();
 | 
					                var rabbitMQPersistentConnection = sp.GetRequiredService<IRabbitMQPersistentConnection>();
 | 
				
			||||||
                var logger = sp.GetRequiredService<ILogger<EventBusRabbitMQ>>();
 | 
					                var logger = sp.GetRequiredService<ILogger<EventBusRabbitMQ>>();
 | 
				
			||||||
                var eventBusSubscriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>();
 | 
					                var eventBusSubscriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var retryCount = 5;
 | 
					                var retryCount = 5;
 | 
				
			||||||
                if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) {
 | 
					                if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"]))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
                    retryCount = int.Parse(configuration["EventBusRetryCount"]);
 | 
					                    retryCount = int.Parse(configuration["EventBusRetryCount"]);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,11 +1,12 @@
 | 
				
			|||||||
var appName = "Catalog.API";
 | 
					var builder = WebApplication.CreateBuilder(new WebApplicationOptions
 | 
				
			||||||
var builder = WebApplication.CreateBuilder(new WebApplicationOptions {
 | 
					{
 | 
				
			||||||
    Args = args,
 | 
					    Args = args,
 | 
				
			||||||
    ApplicationName = typeof(Program).Assembly.FullName,
 | 
					    ApplicationName = typeof(Program).Assembly.FullName,
 | 
				
			||||||
    ContentRootPath = Directory.GetCurrentDirectory(),
 | 
					    ContentRootPath = Directory.GetCurrentDirectory(),
 | 
				
			||||||
    WebRootPath = "Pics",
 | 
					    WebRootPath = "Pics",
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
if (builder.Configuration.GetValue<bool>("UseVault", false)) {
 | 
					if (builder.Configuration.GetValue<bool>("UseVault", false))
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    TokenCredential credential = new ClientSecretCredential(
 | 
					    TokenCredential credential = new ClientSecretCredential(
 | 
				
			||||||
        builder.Configuration["Vault:TenantId"],
 | 
					        builder.Configuration["Vault:TenantId"],
 | 
				
			||||||
        builder.Configuration["Vault:ClientId"],
 | 
					        builder.Configuration["Vault:ClientId"],
 | 
				
			||||||
@ -13,12 +14,15 @@ if (builder.Configuration.GetValue<bool>("UseVault", false)) {
 | 
				
			|||||||
    //builder.AddAzureKeyVault(new Uri($"https://{builder.Configuration["Vault:Name"]}.vault.azure.net/"), credential);        
 | 
					    //builder.AddAzureKeyVault(new Uri($"https://{builder.Configuration["Vault:Name"]}.vault.azure.net/"), credential);        
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
builder.Configuration.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
 | 
					builder.Configuration.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
 | 
				
			||||||
builder.WebHost.UseKestrel(options => {
 | 
					builder.WebHost.UseKestrel(options =>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    var ports = GetDefinedPorts(builder.Configuration);
 | 
					    var ports = GetDefinedPorts(builder.Configuration);
 | 
				
			||||||
    options.Listen(IPAddress.Any, ports.httpPort, listenOptions => {
 | 
					    options.Listen(IPAddress.Any, ports.httpPort, listenOptions =>
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
 | 
					        listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    options.Listen(IPAddress.Any, ports.grpcPort, listenOptions => {
 | 
					    options.Listen(IPAddress.Any, ports.grpcPort, listenOptions =>
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        listenOptions.Protocols = HttpProtocols.Http2;
 | 
					        listenOptions.Protocols = HttpProtocols.Http2;
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -35,20 +39,24 @@ builder.Services.AddGrpc().Services
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
var app = builder.Build();
 | 
					var app = builder.Build();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if (app.Environment.IsDevelopment()) {
 | 
					if (app.Environment.IsDevelopment())
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    app.UseDeveloperExceptionPage();
 | 
					    app.UseDeveloperExceptionPage();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
else {
 | 
					else
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    app.UseExceptionHandler("/Home/Error");
 | 
					    app.UseExceptionHandler("/Home/Error");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var pathBase = app.Configuration["PATH_BASE"];
 | 
					var pathBase = app.Configuration["PATH_BASE"];
 | 
				
			||||||
if (!string.IsNullOrEmpty(pathBase)) {
 | 
					if (!string.IsNullOrEmpty(pathBase))
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    app.UsePathBase(pathBase);
 | 
					    app.UsePathBase(pathBase);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
app.UseSwagger()
 | 
					app.UseSwagger()
 | 
				
			||||||
            .UseSwaggerUI(c => {
 | 
					            .UseSwaggerUI(c =>
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                c.SwaggerEndpoint($"{(!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty)}/swagger/v1/swagger.json", "Catalog.API V1");
 | 
					                c.SwaggerEndpoint($"{(!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty)}/swagger/v1/swagger.json", "Catalog.API V1");
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -56,39 +64,45 @@ app.UseRouting();
 | 
				
			|||||||
app.UseCors("CorsPolicy");
 | 
					app.UseCors("CorsPolicy");
 | 
				
			||||||
app.MapDefaultControllerRoute();
 | 
					app.MapDefaultControllerRoute();
 | 
				
			||||||
app.MapControllers();
 | 
					app.MapControllers();
 | 
				
			||||||
app.UseFileServer(new FileServerOptions {
 | 
					app.UseFileServer(new FileServerOptions
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    FileProvider = new PhysicalFileProvider(Path.Combine(app.Environment.ContentRootPath, "Pics")),
 | 
					    FileProvider = new PhysicalFileProvider(Path.Combine(app.Environment.ContentRootPath, "Pics")),
 | 
				
			||||||
    RequestPath = "/pics"
 | 
					    RequestPath = "/pics"
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
app.UseStaticFiles(new StaticFileOptions {
 | 
					app.UseStaticFiles(new StaticFileOptions
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    FileProvider = new PhysicalFileProvider(Path.Combine(app.Environment.ContentRootPath, "Pics")),
 | 
					    FileProvider = new PhysicalFileProvider(Path.Combine(app.Environment.ContentRootPath, "Pics")),
 | 
				
			||||||
    RequestPath = "/pics"
 | 
					    RequestPath = "/pics"
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
app.MapGet("/_proto/", async ctx => {
 | 
					app.MapGet("/_proto/", async ctx =>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    ctx.Response.ContentType = "text/plain";
 | 
					    ctx.Response.ContentType = "text/plain";
 | 
				
			||||||
    using var fs = new FileStream(Path.Combine(app.Environment.ContentRootPath, "Proto", "catalog.proto"), FileMode.Open, FileAccess.Read);
 | 
					    using var fs = new FileStream(Path.Combine(app.Environment.ContentRootPath, "Proto", "catalog.proto"), FileMode.Open, FileAccess.Read);
 | 
				
			||||||
    using var sr = new StreamReader(fs);
 | 
					    using var sr = new StreamReader(fs);
 | 
				
			||||||
    while (!sr.EndOfStream) {
 | 
					    while (!sr.EndOfStream)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        var line = await sr.ReadLineAsync();
 | 
					        var line = await sr.ReadLineAsync();
 | 
				
			||||||
        if (line != "/* >>" || line != "<< */") {
 | 
					        if (line != "/* >>" || line != "<< */")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
            await ctx.Response.WriteAsync(line);
 | 
					            await ctx.Response.WriteAsync(line);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
app.MapGrpcService<CatalogService>();
 | 
					app.MapGrpcService<CatalogService>();
 | 
				
			||||||
app.MapHealthChecks("/hc", new HealthCheckOptions() {
 | 
					app.MapHealthChecks("/hc", new HealthCheckOptions()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    Predicate = _ => true,
 | 
					    Predicate = _ => true,
 | 
				
			||||||
    ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
 | 
					    ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
app.MapHealthChecks("/liveness", new HealthCheckOptions {
 | 
					app.MapHealthChecks("/liveness", new HealthCheckOptions
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    Predicate = r => r.Name.Contains("self")
 | 
					    Predicate = r => r.Name.Contains("self")
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ConfigureEventBus(app);
 | 
					ConfigureEventBus(app);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					try
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
try {
 | 
					 | 
				
			||||||
    Log.Information("Configuring web host ({ApplicationContext})...", Program.AppName);
 | 
					    Log.Information("Configuring web host ({ApplicationContext})...", Program.AppName);
 | 
				
			||||||
    using var scope = app.Services.CreateScope();
 | 
					    using var scope = app.Services.CreateScope();
 | 
				
			||||||
    var context = scope.ServiceProvider.GetRequiredService<CatalogContext>();
 | 
					    var context = scope.ServiceProvider.GetRequiredService<CatalogContext>();
 | 
				
			||||||
@ -100,50 +114,60 @@ try {
 | 
				
			|||||||
    await new CatalogContextSeed().SeedAsync(context, env, settings, logger);
 | 
					    await new CatalogContextSeed().SeedAsync(context, env, settings, logger);
 | 
				
			||||||
    var integEventContext = scope.ServiceProvider.GetRequiredService<IntegrationEventLogContext>();
 | 
					    var integEventContext = scope.ServiceProvider.GetRequiredService<IntegrationEventLogContext>();
 | 
				
			||||||
    await integEventContext.Database.MigrateAsync();
 | 
					    await integEventContext.Database.MigrateAsync();
 | 
				
			||||||
    app.Logger.LogInformation("Starting web host ({ApplicationName})...", appName);
 | 
					    app.Logger.LogInformation("Starting web host ({ApplicationName})...", AppName);
 | 
				
			||||||
    await app.RunAsync();
 | 
					    await app.RunAsync();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
catch (Exception ex) {
 | 
					catch (Exception ex)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    Log.Fatal(ex, "Program terminated unexpectedly ({ApplicationContext})!", Program.AppName);
 | 
					    Log.Fatal(ex, "Program terminated unexpectedly ({ApplicationContext})!", Program.AppName);
 | 
				
			||||||
    return 1;
 | 
					    return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
finally {
 | 
					finally
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    Log.CloseAndFlush();
 | 
					    Log.CloseAndFlush();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
void ConfigureEventBus(IApplicationBuilder app) {
 | 
					void ConfigureEventBus(IApplicationBuilder app)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    var eventBus = app.ApplicationServices.GetRequiredService<IEventBus>();
 | 
					    var eventBus = app.ApplicationServices.GetRequiredService<IEventBus>();
 | 
				
			||||||
    eventBus.Subscribe<OrderStatusChangedToAwaitingValidationIntegrationEvent, OrderStatusChangedToAwaitingValidationIntegrationEventHandler>();
 | 
					    eventBus.Subscribe<OrderStatusChangedToAwaitingValidationIntegrationEvent, OrderStatusChangedToAwaitingValidationIntegrationEventHandler>();
 | 
				
			||||||
    eventBus.Subscribe<OrderStatusChangedToPaidIntegrationEvent, OrderStatusChangedToPaidIntegrationEventHandler>();
 | 
					    eventBus.Subscribe<OrderStatusChangedToPaidIntegrationEvent, OrderStatusChangedToPaidIntegrationEventHandler>();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(int httpPort, int grpcPort) GetDefinedPorts(IConfiguration config) {
 | 
					(int httpPort, int grpcPort) GetDefinedPorts(IConfiguration config)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    var grpcPort = config.GetValue("GRPC_PORT", 81);
 | 
					    var grpcPort = config.GetValue("GRPC_PORT", 81);
 | 
				
			||||||
    var port = config.GetValue("PORT", 80);
 | 
					    var port = config.GetValue("PORT", 80);
 | 
				
			||||||
    return (port, grpcPort);
 | 
					    return (port, grpcPort);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public partial class Program {
 | 
					public partial class Program
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
    public static string Namespace = typeof(Program).Assembly.GetName().Name;
 | 
					    public static string Namespace = typeof(Program).Assembly.GetName().Name;
 | 
				
			||||||
    public static string AppName = Namespace.Substring(Namespace.LastIndexOf('.', Namespace.LastIndexOf('.') - 1) + 1);
 | 
					    public static string AppName = Namespace.Substring(Namespace.LastIndexOf('.', Namespace.LastIndexOf('.') - 1) + 1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public static class CustomExtensionMethods {
 | 
					public static class CustomExtensionMethods
 | 
				
			||||||
    public static IServiceCollection AddAppInsight(this IServiceCollection services, IConfiguration configuration) {
 | 
					{
 | 
				
			||||||
 | 
					    public static IServiceCollection AddAppInsight(this IServiceCollection services, IConfiguration configuration)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        services.AddApplicationInsightsTelemetry(configuration);
 | 
					        services.AddApplicationInsightsTelemetry(configuration);
 | 
				
			||||||
        services.AddApplicationInsightsKubernetesEnricher();
 | 
					        services.AddApplicationInsightsKubernetesEnricher();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return services;
 | 
					        return services;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static IServiceCollection AddCustomMVC(this IServiceCollection services, IConfiguration configuration) {
 | 
					    public static IServiceCollection AddCustomMVC(this IServiceCollection services, IConfiguration configuration)
 | 
				
			||||||
        services.AddControllers(options => {
 | 
					    {
 | 
				
			||||||
 | 
					        services.AddControllers(options =>
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
            options.Filters.Add(typeof(HttpGlobalExceptionFilter));
 | 
					            options.Filters.Add(typeof(HttpGlobalExceptionFilter));
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
        .AddJsonOptions(options => options.JsonSerializerOptions.WriteIndented = true);
 | 
					        .AddJsonOptions(options => options.JsonSerializerOptions.WriteIndented = true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        services.AddCors(options => {
 | 
					        services.AddCors(options =>
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
            options.AddPolicy("CorsPolicy",
 | 
					            options.AddPolicy("CorsPolicy",
 | 
				
			||||||
                builder => builder
 | 
					                builder => builder
 | 
				
			||||||
                .SetIsOriginAllowed((host) => true)
 | 
					                .SetIsOriginAllowed((host) => true)
 | 
				
			||||||
@ -155,7 +179,8 @@ public static class CustomExtensionMethods {
 | 
				
			|||||||
        return services;
 | 
					        return services;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static IServiceCollection AddCustomHealthCheck(this IServiceCollection services, IConfiguration configuration) {
 | 
					    public static IServiceCollection AddCustomHealthCheck(this IServiceCollection services, IConfiguration configuration)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        var accountName = configuration.GetValue<string>("AzureStorageAccountName");
 | 
					        var accountName = configuration.GetValue<string>("AzureStorageAccountName");
 | 
				
			||||||
        var accountKey = configuration.GetValue<string>("AzureStorageAccountKey");
 | 
					        var accountKey = configuration.GetValue<string>("AzureStorageAccountKey");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -168,7 +193,8 @@ public static class CustomExtensionMethods {
 | 
				
			|||||||
                name: "CatalogDB-check",
 | 
					                name: "CatalogDB-check",
 | 
				
			||||||
                tags: new string[] { "catalogdb" });
 | 
					                tags: new string[] { "catalogdb" });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!string.IsNullOrEmpty(accountName) && !string.IsNullOrEmpty(accountKey)) {
 | 
					        if (!string.IsNullOrEmpty(accountName) && !string.IsNullOrEmpty(accountKey))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
            hcBuilder
 | 
					            hcBuilder
 | 
				
			||||||
                .AddAzureBlobStorage(
 | 
					                .AddAzureBlobStorage(
 | 
				
			||||||
                    $"DefaultEndpointsProtocol=https;AccountName={accountName};AccountKey={accountKey};EndpointSuffix=core.windows.net",
 | 
					                    $"DefaultEndpointsProtocol=https;AccountName={accountName};AccountKey={accountKey};EndpointSuffix=core.windows.net",
 | 
				
			||||||
@ -176,7 +202,8 @@ public static class CustomExtensionMethods {
 | 
				
			|||||||
                    tags: new string[] { "catalogstorage" });
 | 
					                    tags: new string[] { "catalogstorage" });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (configuration.GetValue<bool>("AzureServiceBusEnabled")) {
 | 
					        if (configuration.GetValue<bool>("AzureServiceBusEnabled"))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
            hcBuilder
 | 
					            hcBuilder
 | 
				
			||||||
                .AddAzureServiceBusTopic(
 | 
					                .AddAzureServiceBusTopic(
 | 
				
			||||||
                    configuration["EventBusConnection"],
 | 
					                    configuration["EventBusConnection"],
 | 
				
			||||||
@ -184,7 +211,8 @@ public static class CustomExtensionMethods {
 | 
				
			|||||||
                    name: "catalog-servicebus-check",
 | 
					                    name: "catalog-servicebus-check",
 | 
				
			||||||
                    tags: new string[] { "servicebus" });
 | 
					                    tags: new string[] { "servicebus" });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else {
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
            hcBuilder
 | 
					            hcBuilder
 | 
				
			||||||
                .AddRabbitMQ(
 | 
					                .AddRabbitMQ(
 | 
				
			||||||
                    $"amqp://{configuration["EventBusConnection"]}",
 | 
					                    $"amqp://{configuration["EventBusConnection"]}",
 | 
				
			||||||
@ -195,20 +223,25 @@ public static class CustomExtensionMethods {
 | 
				
			|||||||
        return services;
 | 
					        return services;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static IServiceCollection AddCustomDbContext(this IServiceCollection services, IConfiguration configuration) {
 | 
					    public static IServiceCollection AddCustomDbContext(this IServiceCollection services, IConfiguration configuration)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        services.AddEntityFrameworkSqlServer()
 | 
					        services.AddEntityFrameworkSqlServer()
 | 
				
			||||||
            .AddDbContext<CatalogContext>(options => {
 | 
					            .AddDbContext<CatalogContext>(options =>
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                options.UseSqlServer(configuration["ConnectionString"],
 | 
					                options.UseSqlServer(configuration["ConnectionString"],
 | 
				
			||||||
                                        sqlServerOptionsAction: sqlOptions => {
 | 
					                                        sqlServerOptionsAction: sqlOptions =>
 | 
				
			||||||
 | 
					                                        {
 | 
				
			||||||
                                            sqlOptions.MigrationsAssembly(typeof(Program).GetTypeInfo().Assembly.GetName().Name);
 | 
					                                            sqlOptions.MigrationsAssembly(typeof(Program).GetTypeInfo().Assembly.GetName().Name);
 | 
				
			||||||
                                            //Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency 
 | 
					                                            //Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency 
 | 
				
			||||||
                                            sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null);
 | 
					                                            sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null);
 | 
				
			||||||
                                        });
 | 
					                                        });
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        services.AddDbContext<IntegrationEventLogContext>(options => {
 | 
					        services.AddDbContext<IntegrationEventLogContext>(options =>
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
            options.UseSqlServer(configuration["ConnectionString"],
 | 
					            options.UseSqlServer(configuration["ConnectionString"],
 | 
				
			||||||
                                    sqlServerOptionsAction: sqlOptions => {
 | 
					                                    sqlServerOptionsAction: sqlOptions =>
 | 
				
			||||||
 | 
					                                    {
 | 
				
			||||||
                                        sqlOptions.MigrationsAssembly(typeof(Program).GetTypeInfo().Assembly.GetName().Name);
 | 
					                                        sqlOptions.MigrationsAssembly(typeof(Program).GetTypeInfo().Assembly.GetName().Name);
 | 
				
			||||||
                                        //Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency 
 | 
					                                        //Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency 
 | 
				
			||||||
                                        sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null);
 | 
					                                        sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null);
 | 
				
			||||||
@ -218,17 +251,22 @@ public static class CustomExtensionMethods {
 | 
				
			|||||||
        return services;
 | 
					        return services;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static IServiceCollection AddCustomOptions(this IServiceCollection services, IConfiguration configuration) {
 | 
					    public static IServiceCollection AddCustomOptions(this IServiceCollection services, IConfiguration configuration)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        services.Configure<CatalogSettings>(configuration);
 | 
					        services.Configure<CatalogSettings>(configuration);
 | 
				
			||||||
        services.Configure<ApiBehaviorOptions>(options => {
 | 
					        services.Configure<ApiBehaviorOptions>(options =>
 | 
				
			||||||
            options.InvalidModelStateResponseFactory = context => {
 | 
					        {
 | 
				
			||||||
                var problemDetails = new ValidationProblemDetails(context.ModelState) {
 | 
					            options.InvalidModelStateResponseFactory = context =>
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var problemDetails = new ValidationProblemDetails(context.ModelState)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
                    Instance = context.HttpContext.Request.Path,
 | 
					                    Instance = context.HttpContext.Request.Path,
 | 
				
			||||||
                    Status = StatusCodes.Status400BadRequest,
 | 
					                    Status = StatusCodes.Status400BadRequest,
 | 
				
			||||||
                    Detail = "Please refer to the errors property for additional details."
 | 
					                    Detail = "Please refer to the errors property for additional details."
 | 
				
			||||||
                };
 | 
					                };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                return new BadRequestObjectResult(problemDetails) {
 | 
					                return new BadRequestObjectResult(problemDetails)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
                    ContentTypes = { "application/problem+json", "application/problem+xml" }
 | 
					                    ContentTypes = { "application/problem+json", "application/problem+xml" }
 | 
				
			||||||
                };
 | 
					                };
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
@ -237,9 +275,12 @@ public static class CustomExtensionMethods {
 | 
				
			|||||||
        return services;
 | 
					        return services;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static IServiceCollection AddSwagger(this IServiceCollection services, IConfiguration configuration) {
 | 
					    public static IServiceCollection AddSwagger(this IServiceCollection services, IConfiguration configuration)
 | 
				
			||||||
        services.AddSwaggerGen(options => {
 | 
					    {
 | 
				
			||||||
            options.SwaggerDoc("v1", new OpenApiInfo {
 | 
					        services.AddSwaggerGen(options =>
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            options.SwaggerDoc("v1", new OpenApiInfo
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                Title = "eShopOnContainers - Catalog HTTP API",
 | 
					                Title = "eShopOnContainers - Catalog HTTP API",
 | 
				
			||||||
                Version = "v1",
 | 
					                Version = "v1",
 | 
				
			||||||
                Description = "The Catalog Microservice HTTP API. This is a Data-Driven/CRUD microservice sample"
 | 
					                Description = "The Catalog Microservice HTTP API. This is a Data-Driven/CRUD microservice sample"
 | 
				
			||||||
@ -250,40 +291,49 @@ public static class CustomExtensionMethods {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static IServiceCollection AddIntegrationServices(this IServiceCollection services, IConfiguration configuration) {
 | 
					    public static IServiceCollection AddIntegrationServices(this IServiceCollection services, IConfiguration configuration)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        services.AddTransient<Func<DbConnection, IIntegrationEventLogService>>(
 | 
					        services.AddTransient<Func<DbConnection, IIntegrationEventLogService>>(
 | 
				
			||||||
            sp => (DbConnection c) => new IntegrationEventLogService(c));
 | 
					            sp => (DbConnection c) => new IntegrationEventLogService(c));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        services.AddTransient<ICatalogIntegrationEventService, CatalogIntegrationEventService>();
 | 
					        services.AddTransient<ICatalogIntegrationEventService, CatalogIntegrationEventService>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (configuration.GetValue<bool>("AzureServiceBusEnabled")) {
 | 
					        if (configuration.GetValue<bool>("AzureServiceBusEnabled"))
 | 
				
			||||||
            services.AddSingleton<IServiceBusPersisterConnection>(sp => {
 | 
					        {
 | 
				
			||||||
 | 
					            services.AddSingleton<IServiceBusPersisterConnection>(sp =>
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                var settings = sp.GetRequiredService<IOptions<CatalogSettings>>().Value;
 | 
					                var settings = sp.GetRequiredService<IOptions<CatalogSettings>>().Value;
 | 
				
			||||||
                var serviceBusConnection = settings.EventBusConnection;
 | 
					                var serviceBusConnection = settings.EventBusConnection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                return new DefaultServiceBusPersisterConnection(serviceBusConnection);
 | 
					                return new DefaultServiceBusPersisterConnection(serviceBusConnection);
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else {
 | 
					        else
 | 
				
			||||||
            services.AddSingleton<IRabbitMQPersistentConnection>(sp => {
 | 
					        {
 | 
				
			||||||
 | 
					            services.AddSingleton<IRabbitMQPersistentConnection>(sp =>
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                var settings = sp.GetRequiredService<IOptions<CatalogSettings>>().Value;
 | 
					                var settings = sp.GetRequiredService<IOptions<CatalogSettings>>().Value;
 | 
				
			||||||
                var logger = sp.GetRequiredService<ILogger<DefaultRabbitMQPersistentConnection>>();
 | 
					                var logger = sp.GetRequiredService<ILogger<DefaultRabbitMQPersistentConnection>>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var factory = new ConnectionFactory() {
 | 
					                var factory = new ConnectionFactory()
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
                    HostName = configuration["EventBusConnection"],
 | 
					                    HostName = configuration["EventBusConnection"],
 | 
				
			||||||
                    DispatchConsumersAsync = true
 | 
					                    DispatchConsumersAsync = true
 | 
				
			||||||
                };
 | 
					                };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (!string.IsNullOrEmpty(configuration["EventBusUserName"])) {
 | 
					                if (!string.IsNullOrEmpty(configuration["EventBusUserName"]))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
                    factory.UserName = configuration["EventBusUserName"];
 | 
					                    factory.UserName = configuration["EventBusUserName"];
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (!string.IsNullOrEmpty(configuration["EventBusPassword"])) {
 | 
					                if (!string.IsNullOrEmpty(configuration["EventBusPassword"]))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
                    factory.Password = configuration["EventBusPassword"];
 | 
					                    factory.Password = configuration["EventBusPassword"];
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var retryCount = 5;
 | 
					                var retryCount = 5;
 | 
				
			||||||
                if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) {
 | 
					                if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"]))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
                    retryCount = int.Parse(configuration["EventBusRetryCount"]);
 | 
					                    retryCount = int.Parse(configuration["EventBusRetryCount"]);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -294,9 +344,12 @@ public static class CustomExtensionMethods {
 | 
				
			|||||||
        return services;
 | 
					        return services;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static IServiceCollection AddEventBus(this IServiceCollection services, IConfiguration configuration) {
 | 
					    public static IServiceCollection AddEventBus(this IServiceCollection services, IConfiguration configuration)
 | 
				
			||||||
        if (configuration.GetValue<bool>("AzureServiceBusEnabled")) {
 | 
					    {
 | 
				
			||||||
            services.AddSingleton<IEventBus, EventBusServiceBus>(sp => {
 | 
					        if (configuration.GetValue<bool>("AzureServiceBusEnabled"))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            services.AddSingleton<IEventBus, EventBusServiceBus>(sp =>
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                var serviceBusPersisterConnection = sp.GetRequiredService<IServiceBusPersisterConnection>();
 | 
					                var serviceBusPersisterConnection = sp.GetRequiredService<IServiceBusPersisterConnection>();
 | 
				
			||||||
                var logger = sp.GetRequiredService<ILogger<EventBusServiceBus>>();
 | 
					                var logger = sp.GetRequiredService<ILogger<EventBusServiceBus>>();
 | 
				
			||||||
                var eventBusSubcriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>();
 | 
					                var eventBusSubcriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>();
 | 
				
			||||||
@ -307,15 +360,18 @@ public static class CustomExtensionMethods {
 | 
				
			|||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else {
 | 
					        else
 | 
				
			||||||
            services.AddSingleton<IEventBus, EventBusRabbitMQ>(sp => {
 | 
					        {
 | 
				
			||||||
 | 
					            services.AddSingleton<IEventBus, EventBusRabbitMQ>(sp =>
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                var subscriptionClientName = configuration["SubscriptionClientName"];
 | 
					                var subscriptionClientName = configuration["SubscriptionClientName"];
 | 
				
			||||||
                var rabbitMQPersistentConnection = sp.GetRequiredService<IRabbitMQPersistentConnection>();
 | 
					                var rabbitMQPersistentConnection = sp.GetRequiredService<IRabbitMQPersistentConnection>();
 | 
				
			||||||
                var logger = sp.GetRequiredService<ILogger<EventBusRabbitMQ>>();
 | 
					                var logger = sp.GetRequiredService<ILogger<EventBusRabbitMQ>>();
 | 
				
			||||||
                var eventBusSubcriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>();
 | 
					                var eventBusSubcriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var retryCount = 5;
 | 
					                var retryCount = 5;
 | 
				
			||||||
                if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) {
 | 
					                if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"]))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
                    retryCount = int.Parse(configuration["EventBusRetryCount"]);
 | 
					                    retryCount = int.Parse(configuration["EventBusRetryCount"]);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -36,10 +36,12 @@ namespace Ordering.BackgroundTasks.Services
 | 
				
			|||||||
                _logger.LogDebug("GracePeriodManagerService background task is doing background work.");
 | 
					                _logger.LogDebug("GracePeriodManagerService background task is doing background work.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                CheckConfirmedGracePeriodOrders();
 | 
					                CheckConfirmedGracePeriodOrders();
 | 
				
			||||||
                try {
 | 
					                try
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
                    await Task.Delay(_settings.CheckUpdateTime, stoppingToken);
 | 
					                    await Task.Delay(_settings.CheckUpdateTime, stoppingToken);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                catch (TaskCanceledException exception) {
 | 
					                catch (TaskCanceledException exception)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
                    _logger.LogCritical(exception, "TaskCanceledException Error", exception.Message);
 | 
					                    _logger.LogCritical(exception, "TaskCanceledException Error", exception.Message);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user