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) =>
 | 
			
		||||
    WebHost
 | 
			
		||||
        .CreateDefaultBuilder(args)
 | 
			
		||||
 | 
			
		||||
@ -44,7 +44,7 @@ public class Startup
 | 
			
		||||
 | 
			
		||||
        app.UseSwagger().UseSwaggerUI(c =>
 | 
			
		||||
        {
 | 
			
		||||
            c.SwaggerEndpoint($"{ (!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty) }/swagger/v1/swagger.json", "Purchase BFF V1");
 | 
			
		||||
            c.SwaggerEndpoint($"{(!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty)}/swagger/v1/swagger.json", "Purchase BFF V1");
 | 
			
		||||
 | 
			
		||||
            c.OAuthClientId("mobileshoppingaggswaggerui");
 | 
			
		||||
            c.OAuthClientSecret(string.Empty);
 | 
			
		||||
 | 
			
		||||
@ -17,7 +17,7 @@ namespace EventBus.Tests
 | 
			
		||||
        public void After_One_Event_Subscription_Should_Contain_The_Event()
 | 
			
		||||
        {
 | 
			
		||||
            var manager = new InMemoryEventBusSubscriptionsManager();
 | 
			
		||||
            manager.AddSubscription<TestIntegrationEvent,TestIntegrationEventHandler>();
 | 
			
		||||
            manager.AddSubscription<TestIntegrationEvent, TestIntegrationEventHandler>();
 | 
			
		||||
            Assert.True(manager.HasSubscriptionsForEvent<TestIntegrationEvent>());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -80,7 +80,7 @@ public class EventBusRabbitMQ : IEventBus, IDisposable
 | 
			
		||||
            var properties = channel.CreateBasicProperties();
 | 
			
		||||
            properties.DeliveryMode = 2; // persistent
 | 
			
		||||
 | 
			
		||||
                _logger.LogTrace("Publishing event to RabbitMQ: {EventId}", @event.Id);
 | 
			
		||||
            _logger.LogTrace("Publishing event to RabbitMQ: {EventId}", @event.Id);
 | 
			
		||||
 | 
			
		||||
            channel.BasicPublish(
 | 
			
		||||
                exchange: BROKER_NAME,
 | 
			
		||||
 | 
			
		||||
@ -3,12 +3,14 @@ using Microsoft.Azure.Amqp.Framing;
 | 
			
		||||
using Microsoft.Extensions.Configuration;
 | 
			
		||||
 | 
			
		||||
var appName = "Basket.API";
 | 
			
		||||
var builder = WebApplication.CreateBuilder(new WebApplicationOptions {
 | 
			
		||||
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
 | 
			
		||||
{
 | 
			
		||||
    Args = args,
 | 
			
		||||
    ApplicationName = typeof(Program).Assembly.FullName,
 | 
			
		||||
    ContentRootPath = Directory.GetCurrentDirectory()
 | 
			
		||||
});
 | 
			
		||||
if (builder.Configuration.GetValue<bool>("UseVault", false)) {
 | 
			
		||||
if (builder.Configuration.GetValue<bool>("UseVault", false))
 | 
			
		||||
{
 | 
			
		||||
    TokenCredential credential = new ClientSecretCredential(
 | 
			
		||||
           builder.Configuration["Vault:TenantId"],
 | 
			
		||||
        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.Services.AddGrpc(options => {
 | 
			
		||||
builder.Services.AddGrpc(options =>
 | 
			
		||||
{
 | 
			
		||||
    options.EnableDetailedErrors = true;
 | 
			
		||||
});
 | 
			
		||||
builder.Services.AddApplicationInsightsTelemetry(builder.Configuration);
 | 
			
		||||
builder.Services.AddApplicationInsightsKubernetesEnricher();
 | 
			
		||||
builder.Services.AddControllers(options => {
 | 
			
		||||
builder.Services.AddControllers(options =>
 | 
			
		||||
{
 | 
			
		||||
    options.Filters.Add(typeof(HttpGlobalExceptionFilter));
 | 
			
		||||
    options.Filters.Add(typeof(ValidateModelStateFilter));
 | 
			
		||||
 | 
			
		||||
}) // Added for functional tests
 | 
			
		||||
            .AddApplicationPart(typeof(BasketController).Assembly)
 | 
			
		||||
            .AddJsonOptions(options => options.JsonSerializerOptions.WriteIndented = true);
 | 
			
		||||
builder.Services.AddSwaggerGen(options => {
 | 
			
		||||
    options.SwaggerDoc("v1", new OpenApiInfo {
 | 
			
		||||
builder.Services.AddSwaggerGen(options =>
 | 
			
		||||
{
 | 
			
		||||
    options.SwaggerDoc("v1", new OpenApiInfo
 | 
			
		||||
    {
 | 
			
		||||
        Title = "eShopOnContainers - Basket HTTP API",
 | 
			
		||||
        Version = "v1",
 | 
			
		||||
        Description = "The Basket Service HTTP API"
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme {
 | 
			
		||||
    options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
 | 
			
		||||
    {
 | 
			
		||||
        Type = SecuritySchemeType.OAuth2,
 | 
			
		||||
        Flows = new OpenApiOAuthFlows() {
 | 
			
		||||
            Implicit = new OpenApiOAuthFlow() {
 | 
			
		||||
        Flows = new OpenApiOAuthFlows()
 | 
			
		||||
        {
 | 
			
		||||
            Implicit = new OpenApiOAuthFlow()
 | 
			
		||||
            {
 | 
			
		||||
                AuthorizationUrl = new Uri($"{builder.Configuration.GetValue<string>("IdentityUrlExternal")}/connect/authorize"),
 | 
			
		||||
                TokenUrl = new Uri($"{builder.Configuration.GetValue<string>("IdentityUrlExternal")}/connect/token"),
 | 
			
		||||
                Scopes = new Dictionary<string, string>() { { "basket", "Basket API" } }
 | 
			
		||||
@ -54,14 +63,17 @@ JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub");
 | 
			
		||||
 | 
			
		||||
var identityUrl = builder.Configuration.GetValue<string>("IdentityUrl");
 | 
			
		||||
 | 
			
		||||
builder.Services.AddAuthentication("Bearer").AddJwtBearer(options => {
 | 
			
		||||
builder.Services.AddAuthentication("Bearer").AddJwtBearer(options =>
 | 
			
		||||
{
 | 
			
		||||
    options.Authority = identityUrl;
 | 
			
		||||
    options.RequireHttpsMetadata = false;
 | 
			
		||||
    options.Audience = "basket";
 | 
			
		||||
    options.TokenValidationParameters.ValidateAudience = false;
 | 
			
		||||
});
 | 
			
		||||
builder.Services.AddAuthorization(options => {
 | 
			
		||||
    options.AddPolicy("ApiScope", policy => {
 | 
			
		||||
builder.Services.AddAuthorization(options =>
 | 
			
		||||
{
 | 
			
		||||
    options.AddPolicy("ApiScope", policy =>
 | 
			
		||||
    {
 | 
			
		||||
        policy.RequireAuthenticatedUser();
 | 
			
		||||
        policy.RequireClaim("scope", "basket");
 | 
			
		||||
    });
 | 
			
		||||
@ -71,7 +83,8 @@ builder.Services.AddCustomHealthCheck(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 configuration = ConfigurationOptions.Parse(settings.ConnectionString, true);
 | 
			
		||||
 | 
			
		||||
@ -79,32 +92,40 @@ builder.Services.AddSingleton<ConnectionMultiplexer>(sp => {
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if (builder.Configuration.GetValue<bool>("AzureServiceBusEnabled")) {
 | 
			
		||||
    builder.Services.AddSingleton<IServiceBusPersisterConnection>(sp => {
 | 
			
		||||
if (builder.Configuration.GetValue<bool>("AzureServiceBusEnabled"))
 | 
			
		||||
{
 | 
			
		||||
    builder.Services.AddSingleton<IServiceBusPersisterConnection>(sp =>
 | 
			
		||||
    {
 | 
			
		||||
        var serviceBusConnectionString = builder.Configuration["EventBusConnection"];
 | 
			
		||||
 | 
			
		||||
        return new DefaultServiceBusPersisterConnection(serviceBusConnectionString);
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
else {
 | 
			
		||||
    builder.Services.AddSingleton<IRabbitMQPersistentConnection>(sp => {
 | 
			
		||||
else
 | 
			
		||||
{
 | 
			
		||||
    builder.Services.AddSingleton<IRabbitMQPersistentConnection>(sp =>
 | 
			
		||||
    {
 | 
			
		||||
        var logger = sp.GetRequiredService<ILogger<DefaultRabbitMQPersistentConnection>>();
 | 
			
		||||
 | 
			
		||||
        var factory = new ConnectionFactory() {
 | 
			
		||||
        var factory = new ConnectionFactory()
 | 
			
		||||
        {
 | 
			
		||||
            HostName = builder.Configuration["EventBusConnection"],
 | 
			
		||||
            DispatchConsumersAsync = true
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        if (!string.IsNullOrEmpty(builder.Configuration["EventBusUserName"])) {
 | 
			
		||||
        if (!string.IsNullOrEmpty(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"];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var retryCount = 5;
 | 
			
		||||
        if (!string.IsNullOrEmpty(builder.Configuration["EventBusRetryCount"])) {
 | 
			
		||||
        if (!string.IsNullOrEmpty(builder.Configuration["EventBusRetryCount"]))
 | 
			
		||||
        {
 | 
			
		||||
            retryCount = int.Parse(builder.Configuration["EventBusRetryCount"]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -112,7 +133,8 @@ else {
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
builder.Services.RegisterEventBus(builder.Configuration);
 | 
			
		||||
builder.Services.AddCors(options => {
 | 
			
		||||
builder.Services.AddCors(options =>
 | 
			
		||||
{
 | 
			
		||||
    options.AddPolicy("CorsPolicy",
 | 
			
		||||
        builder => builder
 | 
			
		||||
        .SetIsOriginAllowed((host) => true)
 | 
			
		||||
@ -128,39 +150,47 @@ builder.Services.AddOptions();
 | 
			
		||||
builder.Configuration.SetBasePath(Directory.GetCurrentDirectory());
 | 
			
		||||
builder.Configuration.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
 | 
			
		||||
builder.Configuration.AddEnvironmentVariables();
 | 
			
		||||
builder.WebHost.UseKestrel(options => {
 | 
			
		||||
builder.WebHost.UseKestrel(options =>
 | 
			
		||||
{
 | 
			
		||||
    var ports = GetDefinedPorts(builder.Configuration);
 | 
			
		||||
    options.Listen(IPAddress.Any, ports.httpPort, listenOptions => {
 | 
			
		||||
    options.Listen(IPAddress.Any, ports.httpPort, listenOptions =>
 | 
			
		||||
    {
 | 
			
		||||
        listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    options.Listen(IPAddress.Any, ports.grpcPort, listenOptions => {
 | 
			
		||||
    options.Listen(IPAddress.Any, ports.grpcPort, listenOptions =>
 | 
			
		||||
    {
 | 
			
		||||
        listenOptions.Protocols = HttpProtocols.Http2;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
});
 | 
			
		||||
builder.WebHost.CaptureStartupErrors(false);
 | 
			
		||||
builder.Host.UseSerilog(CreateSerilogLogger(builder.Configuration));
 | 
			
		||||
builder.WebHost.UseFailing(options => {
 | 
			
		||||
builder.WebHost.UseFailing(options =>
 | 
			
		||||
{
 | 
			
		||||
    options.ConfigPath = "/Failing";
 | 
			
		||||
    options.NotFilteredPaths.AddRange(new[] { "/hc", "/liveness" });
 | 
			
		||||
});
 | 
			
		||||
var app = builder.Build();
 | 
			
		||||
 | 
			
		||||
if (app.Environment.IsDevelopment()) {
 | 
			
		||||
if (app.Environment.IsDevelopment())
 | 
			
		||||
{
 | 
			
		||||
    app.UseDeveloperExceptionPage();
 | 
			
		||||
}
 | 
			
		||||
else {
 | 
			
		||||
else
 | 
			
		||||
{
 | 
			
		||||
    app.UseExceptionHandler("/Home/Error");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var pathBase = app.Configuration["PATH_BASE"];
 | 
			
		||||
if (!string.IsNullOrEmpty(pathBase)) {
 | 
			
		||||
if (!string.IsNullOrEmpty(pathBase))
 | 
			
		||||
{
 | 
			
		||||
    app.UsePathBase(pathBase);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
app.UseSwagger()
 | 
			
		||||
            .UseSwaggerUI(setup => {
 | 
			
		||||
            .UseSwaggerUI(setup =>
 | 
			
		||||
            {
 | 
			
		||||
                setup.SwaggerEndpoint($"{(!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty)}/swagger/v1/swagger.json", "Basket.API V1");
 | 
			
		||||
                setup.OAuthClientId("basketswaggerui");
 | 
			
		||||
                setup.OAuthAppName("Basket Swagger UI");
 | 
			
		||||
@ -176,26 +206,32 @@ app.UseStaticFiles();
 | 
			
		||||
app.MapGrpcService<BasketService>();
 | 
			
		||||
app.MapDefaultControllerRoute();
 | 
			
		||||
app.MapControllers();
 | 
			
		||||
app.MapGet("/_proto/", async ctx => {
 | 
			
		||||
app.MapGet("/_proto/", async ctx =>
 | 
			
		||||
{
 | 
			
		||||
    ctx.Response.ContentType = "text/plain";
 | 
			
		||||
    using var fs = new FileStream(Path.Combine(app.Environment.ContentRootPath, "Proto", "basket.proto"), FileMode.Open, FileAccess.Read);
 | 
			
		||||
    using var sr = new StreamReader(fs);
 | 
			
		||||
    while (!sr.EndOfStream) {
 | 
			
		||||
    while (!sr.EndOfStream)
 | 
			
		||||
    {
 | 
			
		||||
        var line = await sr.ReadLineAsync();
 | 
			
		||||
        if (line != "/* >>" || line != "<< */") {
 | 
			
		||||
        if (line != "/* >>" || line != "<< */")
 | 
			
		||||
        {
 | 
			
		||||
            await ctx.Response.WriteAsync(line);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
app.MapHealthChecks("/hc", new HealthCheckOptions() {
 | 
			
		||||
app.MapHealthChecks("/hc", new HealthCheckOptions()
 | 
			
		||||
{
 | 
			
		||||
    Predicate = _ => true,
 | 
			
		||||
    ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
 | 
			
		||||
});
 | 
			
		||||
app.MapHealthChecks("/liveness", new HealthCheckOptions {
 | 
			
		||||
app.MapHealthChecks("/liveness", new HealthCheckOptions
 | 
			
		||||
{
 | 
			
		||||
    Predicate = r => r.Name.Contains("self")
 | 
			
		||||
});
 | 
			
		||||
ConfigureEventBus(app);
 | 
			
		||||
try {
 | 
			
		||||
try
 | 
			
		||||
{
 | 
			
		||||
    Log.Information("Configuring web host ({ApplicationContext})...", Program.AppName);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -204,15 +240,18 @@ try {
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
catch (Exception ex) {
 | 
			
		||||
catch (Exception ex)
 | 
			
		||||
{
 | 
			
		||||
    Log.Fatal(ex, "Program terminated unexpectedly ({ApplicationContext})!", Program.AppName);
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
finally {
 | 
			
		||||
finally
 | 
			
		||||
{
 | 
			
		||||
    Log.CloseAndFlush();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Serilog.ILogger CreateSerilogLogger(IConfiguration configuration) {
 | 
			
		||||
Serilog.ILogger CreateSerilogLogger(IConfiguration configuration)
 | 
			
		||||
{
 | 
			
		||||
    var seqServerUrl = configuration["Serilog:SeqServerUrl"];
 | 
			
		||||
    var logstashUrl = configuration["Serilog:LogstashgUrl"];
 | 
			
		||||
    return new LoggerConfiguration()
 | 
			
		||||
@ -226,30 +265,37 @@ Serilog.ILogger CreateSerilogLogger(IConfiguration configuration) {
 | 
			
		||||
        .CreateLogger();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
(int httpPort, int grpcPort) GetDefinedPorts(IConfiguration config) {
 | 
			
		||||
(int httpPort, int grpcPort) GetDefinedPorts(IConfiguration config)
 | 
			
		||||
{
 | 
			
		||||
    var grpcPort = config.GetValue("GRPC_PORT", 5001);
 | 
			
		||||
    var port = config.GetValue("PORT", 80);
 | 
			
		||||
    return (port, grpcPort);
 | 
			
		||||
}
 | 
			
		||||
void ConfigureEventBus(IApplicationBuilder app) {
 | 
			
		||||
void ConfigureEventBus(IApplicationBuilder app)
 | 
			
		||||
{
 | 
			
		||||
    var eventBus = app.ApplicationServices.GetRequiredService<IEventBus>();
 | 
			
		||||
 | 
			
		||||
    eventBus.Subscribe<ProductPriceChangedIntegrationEvent, ProductPriceChangedIntegrationEventHandler>();
 | 
			
		||||
    eventBus.Subscribe<OrderStartedIntegrationEvent, OrderStartedIntegrationEventHandler>();
 | 
			
		||||
}
 | 
			
		||||
public partial class Program {
 | 
			
		||||
public partial class Program
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    public static string Namespace = typeof(Program).Assembly.GetName().Name;
 | 
			
		||||
    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) {
 | 
			
		||||
        if (configuration.GetValue<bool>("AzureServiceBusEnabled")) {
 | 
			
		||||
            services.AddSingleton<IEventBus, EventBusServiceBus>(sp => {
 | 
			
		||||
    public static IServiceCollection RegisterEventBus(this IServiceCollection services, IConfiguration configuration)
 | 
			
		||||
    {
 | 
			
		||||
        if (configuration.GetValue<bool>("AzureServiceBusEnabled"))
 | 
			
		||||
        {
 | 
			
		||||
            services.AddSingleton<IEventBus, EventBusServiceBus>(sp =>
 | 
			
		||||
            {
 | 
			
		||||
                var serviceBusPersisterConnection = sp.GetRequiredService<IServiceBusPersisterConnection>();
 | 
			
		||||
                var logger = sp.GetRequiredService<ILogger<EventBusServiceBus>>();
 | 
			
		||||
                var eventBusSubscriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>();
 | 
			
		||||
@ -259,15 +305,18 @@ public static class CustomExtensionMethods {
 | 
			
		||||
                    eventBusSubscriptionsManager, sp, subscriptionName);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            services.AddSingleton<IEventBus, EventBusRabbitMQ>(sp => {
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            services.AddSingleton<IEventBus, EventBusRabbitMQ>(sp =>
 | 
			
		||||
            {
 | 
			
		||||
                var subscriptionClientName = configuration["SubscriptionClientName"];
 | 
			
		||||
                var rabbitMQPersistentConnection = sp.GetRequiredService<IRabbitMQPersistentConnection>();
 | 
			
		||||
                var logger = sp.GetRequiredService<ILogger<EventBusRabbitMQ>>();
 | 
			
		||||
                var eventBusSubscriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>();
 | 
			
		||||
 | 
			
		||||
                var retryCount = 5;
 | 
			
		||||
                if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) {
 | 
			
		||||
                if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"]))
 | 
			
		||||
                {
 | 
			
		||||
                    retryCount = int.Parse(configuration["EventBusRetryCount"]);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -316,7 +316,7 @@ public class CatalogContextSeed
 | 
			
		||||
 | 
			
		||||
        if (csvheaders.Count() < requiredHeaders.Count())
 | 
			
		||||
        {
 | 
			
		||||
            throw new Exception($"requiredHeader count '{ requiredHeaders.Count()}' is bigger then csv header count '{csvheaders.Count()}' ");
 | 
			
		||||
            throw new Exception($"requiredHeader count '{requiredHeaders.Count()}' is bigger then csv header count '{csvheaders.Count()}' ");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (optionalHeaders != null)
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,12 @@
 | 
			
		||||
var appName = "Catalog.API";
 | 
			
		||||
var builder = WebApplication.CreateBuilder(new WebApplicationOptions {
 | 
			
		||||
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
 | 
			
		||||
{
 | 
			
		||||
    Args = args,
 | 
			
		||||
    ApplicationName = typeof(Program).Assembly.FullName,
 | 
			
		||||
    ContentRootPath = Directory.GetCurrentDirectory(),
 | 
			
		||||
    WebRootPath = "Pics",
 | 
			
		||||
});
 | 
			
		||||
if (builder.Configuration.GetValue<bool>("UseVault", false)) {
 | 
			
		||||
if (builder.Configuration.GetValue<bool>("UseVault", false))
 | 
			
		||||
{
 | 
			
		||||
    TokenCredential credential = new ClientSecretCredential(
 | 
			
		||||
        builder.Configuration["Vault:TenantId"],
 | 
			
		||||
        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.Configuration.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
 | 
			
		||||
builder.WebHost.UseKestrel(options => {
 | 
			
		||||
builder.WebHost.UseKestrel(options =>
 | 
			
		||||
{
 | 
			
		||||
    var ports = GetDefinedPorts(builder.Configuration);
 | 
			
		||||
    options.Listen(IPAddress.Any, ports.httpPort, listenOptions => {
 | 
			
		||||
    options.Listen(IPAddress.Any, ports.httpPort, listenOptions =>
 | 
			
		||||
    {
 | 
			
		||||
        listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
 | 
			
		||||
    });
 | 
			
		||||
    options.Listen(IPAddress.Any, ports.grpcPort, listenOptions => {
 | 
			
		||||
    options.Listen(IPAddress.Any, ports.grpcPort, listenOptions =>
 | 
			
		||||
    {
 | 
			
		||||
        listenOptions.Protocols = HttpProtocols.Http2;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
@ -35,20 +39,24 @@ builder.Services.AddGrpc().Services
 | 
			
		||||
 | 
			
		||||
var app = builder.Build();
 | 
			
		||||
 | 
			
		||||
if (app.Environment.IsDevelopment()) {
 | 
			
		||||
if (app.Environment.IsDevelopment())
 | 
			
		||||
{
 | 
			
		||||
    app.UseDeveloperExceptionPage();
 | 
			
		||||
}
 | 
			
		||||
else {
 | 
			
		||||
else
 | 
			
		||||
{
 | 
			
		||||
    app.UseExceptionHandler("/Home/Error");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var pathBase = app.Configuration["PATH_BASE"];
 | 
			
		||||
if (!string.IsNullOrEmpty(pathBase)) {
 | 
			
		||||
if (!string.IsNullOrEmpty(pathBase))
 | 
			
		||||
{
 | 
			
		||||
    app.UsePathBase(pathBase);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
app.UseSwagger()
 | 
			
		||||
            .UseSwaggerUI(c => {
 | 
			
		||||
            .UseSwaggerUI(c =>
 | 
			
		||||
            {
 | 
			
		||||
                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.MapDefaultControllerRoute();
 | 
			
		||||
app.MapControllers();
 | 
			
		||||
app.UseFileServer(new FileServerOptions {
 | 
			
		||||
app.UseFileServer(new FileServerOptions
 | 
			
		||||
{
 | 
			
		||||
    FileProvider = new PhysicalFileProvider(Path.Combine(app.Environment.ContentRootPath, "Pics")),
 | 
			
		||||
    RequestPath = "/pics"
 | 
			
		||||
});
 | 
			
		||||
app.UseStaticFiles(new StaticFileOptions {
 | 
			
		||||
app.UseStaticFiles(new StaticFileOptions
 | 
			
		||||
{
 | 
			
		||||
    FileProvider = new PhysicalFileProvider(Path.Combine(app.Environment.ContentRootPath, "Pics")),
 | 
			
		||||
    RequestPath = "/pics"
 | 
			
		||||
});
 | 
			
		||||
app.MapGet("/_proto/", async ctx => {
 | 
			
		||||
app.MapGet("/_proto/", async ctx =>
 | 
			
		||||
{
 | 
			
		||||
    ctx.Response.ContentType = "text/plain";
 | 
			
		||||
    using var fs = new FileStream(Path.Combine(app.Environment.ContentRootPath, "Proto", "catalog.proto"), FileMode.Open, FileAccess.Read);
 | 
			
		||||
    using var sr = new StreamReader(fs);
 | 
			
		||||
    while (!sr.EndOfStream) {
 | 
			
		||||
    while (!sr.EndOfStream)
 | 
			
		||||
    {
 | 
			
		||||
        var line = await sr.ReadLineAsync();
 | 
			
		||||
        if (line != "/* >>" || line != "<< */") {
 | 
			
		||||
        if (line != "/* >>" || line != "<< */")
 | 
			
		||||
        {
 | 
			
		||||
            await ctx.Response.WriteAsync(line);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
app.MapGrpcService<CatalogService>();
 | 
			
		||||
app.MapHealthChecks("/hc", new HealthCheckOptions() {
 | 
			
		||||
app.MapHealthChecks("/hc", new HealthCheckOptions()
 | 
			
		||||
{
 | 
			
		||||
    Predicate = _ => true,
 | 
			
		||||
    ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
 | 
			
		||||
});
 | 
			
		||||
app.MapHealthChecks("/liveness", new HealthCheckOptions {
 | 
			
		||||
app.MapHealthChecks("/liveness", new HealthCheckOptions
 | 
			
		||||
{
 | 
			
		||||
    Predicate = r => r.Name.Contains("self")
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
ConfigureEventBus(app);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
try {
 | 
			
		||||
try
 | 
			
		||||
{
 | 
			
		||||
    Log.Information("Configuring web host ({ApplicationContext})...", Program.AppName);
 | 
			
		||||
    using var scope = app.Services.CreateScope();
 | 
			
		||||
    var context = scope.ServiceProvider.GetRequiredService<CatalogContext>();
 | 
			
		||||
@ -100,50 +114,60 @@ try {
 | 
			
		||||
    await new CatalogContextSeed().SeedAsync(context, env, settings, logger);
 | 
			
		||||
    var integEventContext = scope.ServiceProvider.GetRequiredService<IntegrationEventLogContext>();
 | 
			
		||||
    await integEventContext.Database.MigrateAsync();
 | 
			
		||||
    app.Logger.LogInformation("Starting web host ({ApplicationName})...", appName);
 | 
			
		||||
    app.Logger.LogInformation("Starting web host ({ApplicationName})...", AppName);
 | 
			
		||||
    await app.RunAsync();
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
catch (Exception ex) {
 | 
			
		||||
catch (Exception ex)
 | 
			
		||||
{
 | 
			
		||||
    Log.Fatal(ex, "Program terminated unexpectedly ({ApplicationContext})!", Program.AppName);
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
finally {
 | 
			
		||||
finally
 | 
			
		||||
{
 | 
			
		||||
    Log.CloseAndFlush();
 | 
			
		||||
}
 | 
			
		||||
void ConfigureEventBus(IApplicationBuilder app) {
 | 
			
		||||
void ConfigureEventBus(IApplicationBuilder app)
 | 
			
		||||
{
 | 
			
		||||
    var eventBus = app.ApplicationServices.GetRequiredService<IEventBus>();
 | 
			
		||||
    eventBus.Subscribe<OrderStatusChangedToAwaitingValidationIntegrationEvent, OrderStatusChangedToAwaitingValidationIntegrationEventHandler>();
 | 
			
		||||
    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 port = config.GetValue("PORT", 80);
 | 
			
		||||
    return (port, grpcPort);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public partial class Program {
 | 
			
		||||
public partial class Program
 | 
			
		||||
{
 | 
			
		||||
    public static string Namespace = typeof(Program).Assembly.GetName().Name;
 | 
			
		||||
    public static string AppName = Namespace.Substring(Namespace.LastIndexOf('.', Namespace.LastIndexOf('.') - 1) + 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public static class CustomExtensionMethods {
 | 
			
		||||
    public static IServiceCollection AddAppInsight(this IServiceCollection services, IConfiguration configuration) {
 | 
			
		||||
public static class CustomExtensionMethods
 | 
			
		||||
{
 | 
			
		||||
    public static IServiceCollection AddAppInsight(this IServiceCollection services, IConfiguration configuration)
 | 
			
		||||
    {
 | 
			
		||||
        services.AddApplicationInsightsTelemetry(configuration);
 | 
			
		||||
        services.AddApplicationInsightsKubernetesEnricher();
 | 
			
		||||
 | 
			
		||||
        return services;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static IServiceCollection AddCustomMVC(this IServiceCollection services, IConfiguration configuration) {
 | 
			
		||||
        services.AddControllers(options => {
 | 
			
		||||
    public static IServiceCollection AddCustomMVC(this IServiceCollection services, IConfiguration configuration)
 | 
			
		||||
    {
 | 
			
		||||
        services.AddControllers(options =>
 | 
			
		||||
        {
 | 
			
		||||
            options.Filters.Add(typeof(HttpGlobalExceptionFilter));
 | 
			
		||||
        })
 | 
			
		||||
        .AddJsonOptions(options => options.JsonSerializerOptions.WriteIndented = true);
 | 
			
		||||
 | 
			
		||||
        services.AddCors(options => {
 | 
			
		||||
        services.AddCors(options =>
 | 
			
		||||
        {
 | 
			
		||||
            options.AddPolicy("CorsPolicy",
 | 
			
		||||
                builder => builder
 | 
			
		||||
                .SetIsOriginAllowed((host) => true)
 | 
			
		||||
@ -155,7 +179,8 @@ public static class CustomExtensionMethods {
 | 
			
		||||
        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 accountKey = configuration.GetValue<string>("AzureStorageAccountKey");
 | 
			
		||||
 | 
			
		||||
@ -168,7 +193,8 @@ public static class CustomExtensionMethods {
 | 
			
		||||
                name: "CatalogDB-check",
 | 
			
		||||
                tags: new string[] { "catalogdb" });
 | 
			
		||||
 | 
			
		||||
        if (!string.IsNullOrEmpty(accountName) && !string.IsNullOrEmpty(accountKey)) {
 | 
			
		||||
        if (!string.IsNullOrEmpty(accountName) && !string.IsNullOrEmpty(accountKey))
 | 
			
		||||
        {
 | 
			
		||||
            hcBuilder
 | 
			
		||||
                .AddAzureBlobStorage(
 | 
			
		||||
                    $"DefaultEndpointsProtocol=https;AccountName={accountName};AccountKey={accountKey};EndpointSuffix=core.windows.net",
 | 
			
		||||
@ -176,7 +202,8 @@ public static class CustomExtensionMethods {
 | 
			
		||||
                    tags: new string[] { "catalogstorage" });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (configuration.GetValue<bool>("AzureServiceBusEnabled")) {
 | 
			
		||||
        if (configuration.GetValue<bool>("AzureServiceBusEnabled"))
 | 
			
		||||
        {
 | 
			
		||||
            hcBuilder
 | 
			
		||||
                .AddAzureServiceBusTopic(
 | 
			
		||||
                    configuration["EventBusConnection"],
 | 
			
		||||
@ -184,7 +211,8 @@ public static class CustomExtensionMethods {
 | 
			
		||||
                    name: "catalog-servicebus-check",
 | 
			
		||||
                    tags: new string[] { "servicebus" });
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            hcBuilder
 | 
			
		||||
                .AddRabbitMQ(
 | 
			
		||||
                    $"amqp://{configuration["EventBusConnection"]}",
 | 
			
		||||
@ -195,20 +223,25 @@ public static class CustomExtensionMethods {
 | 
			
		||||
        return services;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static IServiceCollection AddCustomDbContext(this IServiceCollection services, IConfiguration configuration) {
 | 
			
		||||
    public static IServiceCollection AddCustomDbContext(this IServiceCollection services, IConfiguration configuration)
 | 
			
		||||
    {
 | 
			
		||||
        services.AddEntityFrameworkSqlServer()
 | 
			
		||||
            .AddDbContext<CatalogContext>(options => {
 | 
			
		||||
            .AddDbContext<CatalogContext>(options =>
 | 
			
		||||
            {
 | 
			
		||||
                options.UseSqlServer(configuration["ConnectionString"],
 | 
			
		||||
                                        sqlServerOptionsAction: sqlOptions => {
 | 
			
		||||
                                        sqlServerOptionsAction: sqlOptions =>
 | 
			
		||||
                                        {
 | 
			
		||||
                                            sqlOptions.MigrationsAssembly(typeof(Program).GetTypeInfo().Assembly.GetName().Name);
 | 
			
		||||
                                            //Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency 
 | 
			
		||||
                                            sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null);
 | 
			
		||||
                                        });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        services.AddDbContext<IntegrationEventLogContext>(options => {
 | 
			
		||||
        services.AddDbContext<IntegrationEventLogContext>(options =>
 | 
			
		||||
        {
 | 
			
		||||
            options.UseSqlServer(configuration["ConnectionString"],
 | 
			
		||||
                                    sqlServerOptionsAction: sqlOptions => {
 | 
			
		||||
                                    sqlServerOptionsAction: sqlOptions =>
 | 
			
		||||
                                    {
 | 
			
		||||
                                        sqlOptions.MigrationsAssembly(typeof(Program).GetTypeInfo().Assembly.GetName().Name);
 | 
			
		||||
                                        //Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency 
 | 
			
		||||
                                        sqlOptions.EnableRetryOnFailure(maxRetryCount: 15, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null);
 | 
			
		||||
@ -218,17 +251,22 @@ public static class CustomExtensionMethods {
 | 
			
		||||
        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<ApiBehaviorOptions>(options => {
 | 
			
		||||
            options.InvalidModelStateResponseFactory = context => {
 | 
			
		||||
                var problemDetails = new ValidationProblemDetails(context.ModelState) {
 | 
			
		||||
        services.Configure<ApiBehaviorOptions>(options =>
 | 
			
		||||
        {
 | 
			
		||||
            options.InvalidModelStateResponseFactory = context =>
 | 
			
		||||
            {
 | 
			
		||||
                var problemDetails = new ValidationProblemDetails(context.ModelState)
 | 
			
		||||
                {
 | 
			
		||||
                    Instance = context.HttpContext.Request.Path,
 | 
			
		||||
                    Status = StatusCodes.Status400BadRequest,
 | 
			
		||||
                    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" }
 | 
			
		||||
                };
 | 
			
		||||
            };
 | 
			
		||||
@ -237,9 +275,12 @@ public static class CustomExtensionMethods {
 | 
			
		||||
        return services;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static IServiceCollection AddSwagger(this IServiceCollection services, IConfiguration configuration) {
 | 
			
		||||
        services.AddSwaggerGen(options => {
 | 
			
		||||
            options.SwaggerDoc("v1", new OpenApiInfo {
 | 
			
		||||
    public static IServiceCollection AddSwagger(this IServiceCollection services, IConfiguration configuration)
 | 
			
		||||
    {
 | 
			
		||||
        services.AddSwaggerGen(options =>
 | 
			
		||||
        {
 | 
			
		||||
            options.SwaggerDoc("v1", new OpenApiInfo
 | 
			
		||||
            {
 | 
			
		||||
                Title = "eShopOnContainers - Catalog HTTP API",
 | 
			
		||||
                Version = "v1",
 | 
			
		||||
                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>>(
 | 
			
		||||
            sp => (DbConnection c) => new IntegrationEventLogService(c));
 | 
			
		||||
 | 
			
		||||
        services.AddTransient<ICatalogIntegrationEventService, CatalogIntegrationEventService>();
 | 
			
		||||
 | 
			
		||||
        if (configuration.GetValue<bool>("AzureServiceBusEnabled")) {
 | 
			
		||||
            services.AddSingleton<IServiceBusPersisterConnection>(sp => {
 | 
			
		||||
        if (configuration.GetValue<bool>("AzureServiceBusEnabled"))
 | 
			
		||||
        {
 | 
			
		||||
            services.AddSingleton<IServiceBusPersisterConnection>(sp =>
 | 
			
		||||
            {
 | 
			
		||||
                var settings = sp.GetRequiredService<IOptions<CatalogSettings>>().Value;
 | 
			
		||||
                var serviceBusConnection = settings.EventBusConnection;
 | 
			
		||||
 | 
			
		||||
                return new DefaultServiceBusPersisterConnection(serviceBusConnection);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            services.AddSingleton<IRabbitMQPersistentConnection>(sp => {
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            services.AddSingleton<IRabbitMQPersistentConnection>(sp =>
 | 
			
		||||
            {
 | 
			
		||||
                var settings = sp.GetRequiredService<IOptions<CatalogSettings>>().Value;
 | 
			
		||||
                var logger = sp.GetRequiredService<ILogger<DefaultRabbitMQPersistentConnection>>();
 | 
			
		||||
 | 
			
		||||
                var factory = new ConnectionFactory() {
 | 
			
		||||
                var factory = new ConnectionFactory()
 | 
			
		||||
                {
 | 
			
		||||
                    HostName = configuration["EventBusConnection"],
 | 
			
		||||
                    DispatchConsumersAsync = true
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                if (!string.IsNullOrEmpty(configuration["EventBusUserName"])) {
 | 
			
		||||
                if (!string.IsNullOrEmpty(configuration["EventBusUserName"]))
 | 
			
		||||
                {
 | 
			
		||||
                    factory.UserName = configuration["EventBusUserName"];
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (!string.IsNullOrEmpty(configuration["EventBusPassword"])) {
 | 
			
		||||
                if (!string.IsNullOrEmpty(configuration["EventBusPassword"]))
 | 
			
		||||
                {
 | 
			
		||||
                    factory.Password = configuration["EventBusPassword"];
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                var retryCount = 5;
 | 
			
		||||
                if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) {
 | 
			
		||||
                if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"]))
 | 
			
		||||
                {
 | 
			
		||||
                    retryCount = int.Parse(configuration["EventBusRetryCount"]);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -294,9 +344,12 @@ public static class CustomExtensionMethods {
 | 
			
		||||
        return services;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static IServiceCollection AddEventBus(this IServiceCollection services, IConfiguration configuration) {
 | 
			
		||||
        if (configuration.GetValue<bool>("AzureServiceBusEnabled")) {
 | 
			
		||||
            services.AddSingleton<IEventBus, EventBusServiceBus>(sp => {
 | 
			
		||||
    public static IServiceCollection AddEventBus(this IServiceCollection services, IConfiguration configuration)
 | 
			
		||||
    {
 | 
			
		||||
        if (configuration.GetValue<bool>("AzureServiceBusEnabled"))
 | 
			
		||||
        {
 | 
			
		||||
            services.AddSingleton<IEventBus, EventBusServiceBus>(sp =>
 | 
			
		||||
            {
 | 
			
		||||
                var serviceBusPersisterConnection = sp.GetRequiredService<IServiceBusPersisterConnection>();
 | 
			
		||||
                var logger = sp.GetRequiredService<ILogger<EventBusServiceBus>>();
 | 
			
		||||
                var eventBusSubcriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>();
 | 
			
		||||
@ -307,15 +360,18 @@ public static class CustomExtensionMethods {
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            services.AddSingleton<IEventBus, EventBusRabbitMQ>(sp => {
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            services.AddSingleton<IEventBus, EventBusRabbitMQ>(sp =>
 | 
			
		||||
            {
 | 
			
		||||
                var subscriptionClientName = configuration["SubscriptionClientName"];
 | 
			
		||||
                var rabbitMQPersistentConnection = sp.GetRequiredService<IRabbitMQPersistentConnection>();
 | 
			
		||||
                var logger = sp.GetRequiredService<ILogger<EventBusRabbitMQ>>();
 | 
			
		||||
                var eventBusSubcriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>();
 | 
			
		||||
 | 
			
		||||
                var retryCount = 5;
 | 
			
		||||
                if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) {
 | 
			
		||||
                if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"]))
 | 
			
		||||
                {
 | 
			
		||||
                    retryCount = int.Parse(configuration["EventBusRetryCount"]);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -56,7 +56,7 @@ namespace Microsoft.AspNetCore.Hosting
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        return webHost;
 | 
			
		||||
            return webHost;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static void InvokeSeeder<TContext>(Action<TContext, IServiceProvider> seeder, TContext context, IServiceProvider services)
 | 
			
		||||
 | 
			
		||||
@ -127,7 +127,7 @@ namespace IdentityServerHost.Quickstart.UI
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, "invalid credentials", clientId:context?.Client.ClientId));
 | 
			
		||||
                await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, "invalid credentials", clientId: context?.Client.ClientId));
 | 
			
		||||
                ModelState.AddModelError(string.Empty, AccountOptions.InvalidCredentialsErrorMessage);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -144,7 +144,7 @@ public class OrderingContextSeed
 | 
			
		||||
 | 
			
		||||
        if (csvheaders.Count() != requiredHeaders.Count())
 | 
			
		||||
        {
 | 
			
		||||
            throw new Exception($"requiredHeader count '{ requiredHeaders.Count()}' is different then read header '{csvheaders.Count()}'");
 | 
			
		||||
            throw new Exception($"requiredHeader count '{requiredHeaders.Count()}' is different then read header '{csvheaders.Count()}'");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        foreach (var requiredHeader in requiredHeaders)
 | 
			
		||||
 | 
			
		||||
@ -132,7 +132,7 @@ namespace Ordering.BackgroundTasks.Extensions
 | 
			
		||||
                .Enrich.FromLogContext()
 | 
			
		||||
                .WriteTo.Console()
 | 
			
		||||
                .WriteTo.Seq(string.IsNullOrWhiteSpace(seqServerUrl) ? "http://seq" : seqServerUrl)
 | 
			
		||||
                .WriteTo.Http(string.IsNullOrWhiteSpace(logstashUrl) ? "http://logstash:8080" : logstashUrl,null)
 | 
			
		||||
                .WriteTo.Http(string.IsNullOrWhiteSpace(logstashUrl) ? "http://logstash:8080" : logstashUrl, null)
 | 
			
		||||
                .ReadFrom.Configuration(configuration)
 | 
			
		||||
                .CreateLogger();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -36,10 +36,12 @@ namespace Ordering.BackgroundTasks.Services
 | 
			
		||||
                _logger.LogDebug("GracePeriodManagerService background task is doing background work.");
 | 
			
		||||
 | 
			
		||||
                CheckConfirmedGracePeriodOrders();
 | 
			
		||||
                try {
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    await Task.Delay(_settings.CheckUpdateTime, stoppingToken);
 | 
			
		||||
                }
 | 
			
		||||
                catch (TaskCanceledException exception) {
 | 
			
		||||
                catch (TaskCanceledException exception)
 | 
			
		||||
                {
 | 
			
		||||
                    _logger.LogCritical(exception, "TaskCanceledException Error", exception.Message);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -26,7 +26,7 @@ public class HttpGlobalExceptionFilter : IExceptionFilter
 | 
			
		||||
                Detail = "Please refer to the errors property for additional details."
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            problemDetails.Errors.Add("DomainValidations", new [] { context.Exception.Message });
 | 
			
		||||
            problemDetails.Errors.Add("DomainValidations", new[] { context.Exception.Message });
 | 
			
		||||
 | 
			
		||||
            context.Result = new BadRequestObjectResult(problemDetails);
 | 
			
		||||
            context.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
 | 
			
		||||
 | 
			
		||||
@ -64,7 +64,7 @@ public class Startup
 | 
			
		||||
        app.UseSwagger()
 | 
			
		||||
            .UseSwaggerUI(c =>
 | 
			
		||||
            {
 | 
			
		||||
                c.SwaggerEndpoint($"{ (!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty) }/swagger/v1/swagger.json", "Webhooks.API V1");
 | 
			
		||||
                c.SwaggerEndpoint($"{(!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty)}/swagger/v1/swagger.json", "Webhooks.API V1");
 | 
			
		||||
                c.OAuthClientId("webhooksswaggerui");
 | 
			
		||||
                c.OAuthAppName("WebHooks Service Swagger UI");
 | 
			
		||||
            });
 | 
			
		||||
@ -239,47 +239,47 @@ internal static class CustomExtensionMethods
 | 
			
		||||
        services.AddTransient<Func<DbConnection, IIntegrationEventLogService>>(
 | 
			
		||||
                sp => (DbConnection c) => new IntegrationEventLogService(c));
 | 
			
		||||
 | 
			
		||||
            if (configuration.GetValue<bool>("AzureServiceBusEnabled"))
 | 
			
		||||
        if (configuration.GetValue<bool>("AzureServiceBusEnabled"))
 | 
			
		||||
        {
 | 
			
		||||
            services.AddSingleton<IServiceBusPersisterConnection>(sp =>
 | 
			
		||||
            {
 | 
			
		||||
                services.AddSingleton<IServiceBusPersisterConnection>(sp =>
 | 
			
		||||
                {
 | 
			
		||||
                    var subscriptionClientName = configuration["SubscriptionClientName"];
 | 
			
		||||
                    return new DefaultServiceBusPersisterConnection(configuration["EventBusConnection"]);
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
                var subscriptionClientName = configuration["SubscriptionClientName"];
 | 
			
		||||
                return new DefaultServiceBusPersisterConnection(configuration["EventBusConnection"]);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            services.AddSingleton<IRabbitMQPersistentConnection>(sp =>
 | 
			
		||||
            {
 | 
			
		||||
                services.AddSingleton<IRabbitMQPersistentConnection>(sp =>
 | 
			
		||||
                var logger = sp.GetRequiredService<ILogger<DefaultRabbitMQPersistentConnection>>();
 | 
			
		||||
 | 
			
		||||
                var factory = new ConnectionFactory()
 | 
			
		||||
                {
 | 
			
		||||
                    var logger = sp.GetRequiredService<ILogger<DefaultRabbitMQPersistentConnection>>();
 | 
			
		||||
                    HostName = configuration["EventBusConnection"],
 | 
			
		||||
                    DispatchConsumersAsync = true
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                    var factory = new ConnectionFactory()
 | 
			
		||||
                    {
 | 
			
		||||
                        HostName = configuration["EventBusConnection"],
 | 
			
		||||
                        DispatchConsumersAsync = true
 | 
			
		||||
                    };
 | 
			
		||||
                if (!string.IsNullOrEmpty(configuration["EventBusUserName"]))
 | 
			
		||||
                {
 | 
			
		||||
                    factory.UserName = configuration["EventBusUserName"];
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                    if (!string.IsNullOrEmpty(configuration["EventBusUserName"]))
 | 
			
		||||
                    {
 | 
			
		||||
                        factory.UserName = configuration["EventBusUserName"];
 | 
			
		||||
                    }
 | 
			
		||||
                if (!string.IsNullOrEmpty(configuration["EventBusPassword"]))
 | 
			
		||||
                {
 | 
			
		||||
                    factory.Password = configuration["EventBusPassword"];
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                    if (!string.IsNullOrEmpty(configuration["EventBusPassword"]))
 | 
			
		||||
                    {
 | 
			
		||||
                        factory.Password = configuration["EventBusPassword"];
 | 
			
		||||
                    }
 | 
			
		||||
                var retryCount = 5;
 | 
			
		||||
                if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"]))
 | 
			
		||||
                {
 | 
			
		||||
                    retryCount = int.Parse(configuration["EventBusRetryCount"]);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                    var retryCount = 5;
 | 
			
		||||
                    if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"]))
 | 
			
		||||
                    {
 | 
			
		||||
                        retryCount = int.Parse(configuration["EventBusRetryCount"]);
 | 
			
		||||
                    }
 | 
			
		||||
                return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
                    return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount);
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return services;
 | 
			
		||||
        return services;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static IServiceCollection AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration)
 | 
			
		||||
 | 
			
		||||
@ -1,16 +1,16 @@
 | 
			
		||||
public static class SessionExtensions
 | 
			
		||||
{
 | 
			
		||||
    public static void SetObject(this ISession session, string key, object value) =>
 | 
			
		||||
        session.SetString(key,JsonSerializer.Serialize(value));
 | 
			
		||||
        session.SetString(key, JsonSerializer.Serialize(value));
 | 
			
		||||
 | 
			
		||||
    public static T GetObject<T>(this ISession session, string key)
 | 
			
		||||
    {
 | 
			
		||||
        var value = session.GetString(key);
 | 
			
		||||
 | 
			
		||||
        return value == null ? default(T) :JsonSerializer.Deserialize<T>(value, new JsonSerializerOptions
 | 
			
		||||
            {
 | 
			
		||||
                PropertyNameCaseInsensitive = true
 | 
			
		||||
            });
 | 
			
		||||
        return value == null ? default(T) : JsonSerializer.Deserialize<T>(value, new JsonSerializerOptions
 | 
			
		||||
        {
 | 
			
		||||
            PropertyNameCaseInsensitive = true
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -73,7 +73,7 @@ Serilog.ILogger CreateSerilogLogger(IConfiguration configuration)
 | 
			
		||||
    }
 | 
			
		||||
    if (!string.IsNullOrWhiteSpace(logstashUrl))
 | 
			
		||||
    {
 | 
			
		||||
        cfg.WriteTo.Http(logstashUrl,null);
 | 
			
		||||
        cfg.WriteTo.Http(logstashUrl, null);
 | 
			
		||||
    }
 | 
			
		||||
    return cfg.CreateLogger();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,7 @@ public class CatalogService : ICatalogService
 | 
			
		||||
 | 
			
		||||
        using var brands = JsonDocument.Parse(responseString);
 | 
			
		||||
 | 
			
		||||
        foreach (JsonElement brand  in brands.RootElement.EnumerateArray())
 | 
			
		||||
        foreach (JsonElement brand in brands.RootElement.EnumerateArray())
 | 
			
		||||
        {
 | 
			
		||||
            items.Add(new SelectListItem()
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user