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)
 | 
				
			||||||
 | 
				
			|||||||
@ -44,7 +44,7 @@ public class Startup
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        app.UseSwagger().UseSwaggerUI(c =>
 | 
					        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.OAuthClientId("mobileshoppingaggswaggerui");
 | 
				
			||||||
            c.OAuthClientSecret(string.Empty);
 | 
					            c.OAuthClientSecret(string.Empty);
 | 
				
			||||||
 | 
				
			|||||||
@ -10,7 +10,7 @@ public class BasketService : IBasketService
 | 
				
			|||||||
        _basketClient = basketClient;
 | 
					        _basketClient = basketClient;
 | 
				
			||||||
        _logger = logger;
 | 
					        _logger = logger;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    public async Task<BasketData> GetByIdAsync(string id)
 | 
					    public async Task<BasketData> GetByIdAsync(string id)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        _logger.LogDebug("grpc client created, request = {@id}", id);
 | 
					        _logger.LogDebug("grpc client created, request = {@id}", id);
 | 
				
			||||||
 | 
				
			|||||||
@ -17,7 +17,7 @@ namespace EventBus.Tests
 | 
				
			|||||||
        public void After_One_Event_Subscription_Should_Contain_The_Event()
 | 
					        public void After_One_Event_Subscription_Should_Contain_The_Event()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var manager = new InMemoryEventBusSubscriptionsManager();
 | 
					            var manager = new InMemoryEventBusSubscriptionsManager();
 | 
				
			||||||
            manager.AddSubscription<TestIntegrationEvent,TestIntegrationEventHandler>();
 | 
					            manager.AddSubscription<TestIntegrationEvent, TestIntegrationEventHandler>();
 | 
				
			||||||
            Assert.True(manager.HasSubscriptionsForEvent<TestIntegrationEvent>());
 | 
					            Assert.True(manager.HasSubscriptionsForEvent<TestIntegrationEvent>());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
 | 
					namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public record IntegrationEvent
 | 
					public record IntegrationEvent
 | 
				
			||||||
{        
 | 
					{
 | 
				
			||||||
    public IntegrationEvent()
 | 
					    public IntegrationEvent()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Id = Guid.NewGuid();
 | 
					        Id = Guid.NewGuid();
 | 
				
			||||||
 | 
				
			|||||||
@ -80,7 +80,7 @@ public class EventBusRabbitMQ : IEventBus, IDisposable
 | 
				
			|||||||
            var properties = channel.CreateBasicProperties();
 | 
					            var properties = channel.CreateBasicProperties();
 | 
				
			||||||
            properties.DeliveryMode = 2; // persistent
 | 
					            properties.DeliveryMode = 2; // persistent
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                _logger.LogTrace("Publishing event to RabbitMQ: {EventId}", @event.Id);
 | 
					            _logger.LogTrace("Publishing event to RabbitMQ: {EventId}", @event.Id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            channel.BasicPublish(
 | 
					            channel.BasicPublish(
 | 
				
			||||||
                exchange: BROKER_NAME,
 | 
					                exchange: BROKER_NAME,
 | 
				
			||||||
@ -123,7 +123,7 @@ public class EventBusRabbitMQ : IEventBus, IDisposable
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
                _persistentConnection.TryConnect();
 | 
					                _persistentConnection.TryConnect();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 
 | 
					
 | 
				
			||||||
            _consumerChannel.QueueBind(queue: _queueName,
 | 
					            _consumerChannel.QueueBind(queue: _queueName,
 | 
				
			||||||
                                exchange: BROKER_NAME,
 | 
					                                exchange: BROKER_NAME,
 | 
				
			||||||
                                routingKey: eventName);
 | 
					                                routingKey: eventName);
 | 
				
			||||||
 | 
				
			|||||||
@ -27,7 +27,7 @@ public class DefaultServiceBusPersisterConnection : IServiceBusPersisterConnecti
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public ServiceBusAdministrationClient AdministrationClient => 
 | 
					    public ServiceBusAdministrationClient AdministrationClient =>
 | 
				
			||||||
        _subscriptionClient;
 | 
					        _subscriptionClient;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public ServiceBusClient CreateModel()
 | 
					    public ServiceBusClient CreateModel()
 | 
				
			||||||
 | 
				
			|||||||
@ -7,7 +7,7 @@ public class IntegrationEventLogEntry
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        EventId = @event.Id;
 | 
					        EventId = @event.Id;
 | 
				
			||||||
        CreationTime = @event.CreationDate;
 | 
					        CreationTime = @event.CreationDate;
 | 
				
			||||||
        EventTypeName = @event.GetType().FullName;                     
 | 
					        EventTypeName = @event.GetType().FullName;
 | 
				
			||||||
        Content = JsonSerializer.Serialize(@event, @event.GetType(), new JsonSerializerOptions
 | 
					        Content = JsonSerializer.Serialize(@event, @event.GetType(), new JsonSerializerOptions
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            WriteIndented = true
 | 
					            WriteIndented = true
 | 
				
			||||||
@ -29,7 +29,7 @@ public class IntegrationEventLogEntry
 | 
				
			|||||||
    public string TransactionId { get; private set; }
 | 
					    public string TransactionId { get; private set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public IntegrationEventLogEntry DeserializeJsonContent(Type type)
 | 
					    public IntegrationEventLogEntry DeserializeJsonContent(Type type)
 | 
				
			||||||
    {            
 | 
					    {
 | 
				
			||||||
        IntegrationEvent = JsonSerializer.Deserialize(Content, type, new JsonSerializerOptions() { PropertyNameCaseInsensitive = true }) as IntegrationEvent;
 | 
					        IntegrationEvent = JsonSerializer.Deserialize(Content, type, new JsonSerializerOptions() { PropertyNameCaseInsensitive = true }) as IntegrationEvent;
 | 
				
			||||||
        return this;
 | 
					        return this;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -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"]);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -9,7 +9,7 @@ public class CatalogService : CatalogBase
 | 
				
			|||||||
    private readonly CatalogContext _catalogContext;
 | 
					    private readonly CatalogContext _catalogContext;
 | 
				
			||||||
    private readonly CatalogSettings _settings;
 | 
					    private readonly CatalogSettings _settings;
 | 
				
			||||||
    private readonly ILogger _logger;
 | 
					    private readonly ILogger _logger;
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    public CatalogService(CatalogContext dbContext, IOptions<CatalogSettings> settings, ILogger<CatalogService> logger)
 | 
					    public CatalogService(CatalogContext dbContext, IOptions<CatalogSettings> settings, ILogger<CatalogService> logger)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        _settings = settings.Value;
 | 
					        _settings = settings.Value;
 | 
				
			||||||
 | 
				
			|||||||
@ -316,7 +316,7 @@ public class CatalogContextSeed
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (csvheaders.Count() < requiredHeaders.Count())
 | 
					        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)
 | 
					        if (optionalHeaders != null)
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.EventHandling;
 | 
					namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.EventHandling;
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
public class OrderStatusChangedToAwaitingValidationIntegrationEventHandler :
 | 
					public class OrderStatusChangedToAwaitingValidationIntegrationEventHandler :
 | 
				
			||||||
    IIntegrationEventHandler<OrderStatusChangedToAwaitingValidationIntegrationEvent>
 | 
					    IIntegrationEventHandler<OrderStatusChangedToAwaitingValidationIntegrationEvent>
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
				
			|||||||
@ -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"]);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -329,4 +385,4 @@ public static class CustomExtensionMethods {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        return services;
 | 
					        return services;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -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)
 | 
					        private static void InvokeSeeder<TContext>(Action<TContext, IServiceProvider> seeder, TContext context, IServiceProvider services)
 | 
				
			||||||
 | 
				
			|||||||
@ -9,7 +9,7 @@ public static class ProgramExtensions
 | 
				
			|||||||
    public static void AddCustomConfiguration(this WebApplicationBuilder builder)
 | 
					    public static void AddCustomConfiguration(this WebApplicationBuilder builder)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        builder.Configuration.AddConfiguration(GetConfiguration()).Build();
 | 
					        builder.Configuration.AddConfiguration(GetConfiguration()).Build();
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static void AddCustomSerilog(this WebApplicationBuilder builder)
 | 
					    public static void AddCustomSerilog(this WebApplicationBuilder builder)
 | 
				
			||||||
 | 
				
			|||||||
@ -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);
 | 
					                ModelState.AddModelError(string.Empty, AccountOptions.InvalidCredentialsErrorMessage);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -139,7 +139,7 @@ namespace IdentityServerHost.Quickstart.UI
 | 
				
			|||||||
            return View(vm);
 | 
					            return View(vm);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// Show logout page
 | 
					        /// Show logout page
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers.OrderGracePeriodConfirmed;
 | 
					namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers.OrderGracePeriodConfirmed;
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
public class OrderStatusChangedToAwaitingValidationDomainEventHandler
 | 
					public class OrderStatusChangedToAwaitingValidationDomainEventHandler
 | 
				
			||||||
                : INotificationHandler<OrderStatusChangedToAwaitingValidationDomainEvent>
 | 
					                : INotificationHandler<OrderStatusChangedToAwaitingValidationDomainEvent>
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers.OrderPaid;
 | 
					namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.DomainEventHandlers.OrderPaid;
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
public class OrderStatusChangedToPaidDomainEventHandler
 | 
					public class OrderStatusChangedToPaidDomainEventHandler
 | 
				
			||||||
                : INotificationHandler<OrderStatusChangedToPaidDomainEvent>
 | 
					                : INotificationHandler<OrderStatusChangedToPaidDomainEvent>
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.IntegrationEvents.EventHandling;
 | 
					namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.IntegrationEvents.EventHandling;
 | 
				
			||||||
   
 | 
					
 | 
				
			||||||
public class OrderPaymentSucceededIntegrationEventHandler :
 | 
					public class OrderPaymentSucceededIntegrationEventHandler :
 | 
				
			||||||
    IIntegrationEventHandler<OrderPaymentSucceededIntegrationEvent>
 | 
					    IIntegrationEventHandler<OrderPaymentSucceededIntegrationEvent>
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.IntegrationEvents.Events;    
 | 
					namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.IntegrationEvents.Events;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public record GracePeriodConfirmedIntegrationEvent : IntegrationEvent
 | 
					public record GracePeriodConfirmedIntegrationEvent : IntegrationEvent
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.IntegrationEvents.Events;
 | 
					namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.IntegrationEvents.Events;
 | 
				
			||||||
  
 | 
					
 | 
				
			||||||
public record OrderStatusChangedToAwaitingValidationIntegrationEvent : IntegrationEvent
 | 
					public record OrderStatusChangedToAwaitingValidationIntegrationEvent : IntegrationEvent
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public int OrderId { get; }
 | 
					    public int OrderId { get; }
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.IntegrationEvents.Events;    
 | 
					namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.IntegrationEvents.Events;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public record OrderStockRejectedIntegrationEvent : IntegrationEvent
 | 
					public record OrderStockRejectedIntegrationEvent : IntegrationEvent
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
				
			|||||||
@ -1,15 +1,15 @@
 | 
				
			|||||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.IntegrationEvents.Events;
 | 
					namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.IntegrationEvents.Events;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public record UserCheckoutAcceptedIntegrationEvent : IntegrationEvent
 | 
					public record UserCheckoutAcceptedIntegrationEvent : IntegrationEvent
 | 
				
			||||||
{        
 | 
					{
 | 
				
			||||||
    public string UserId { get; }
 | 
					    public string UserId { get; }
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
    public string UserName { get; }
 | 
					    public string UserName { get; }
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
    public string City { get; set; }
 | 
					    public string City { get; set; }
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
    public string Street { get; set; }
 | 
					    public string Street { get; set; }
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
    public string State { get; set; }
 | 
					    public string State { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public string Country { get; set; }
 | 
					    public string Country { get; set; }
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Queries;
 | 
					namespace Microsoft.eShopOnContainers.Services.Ordering.API.Application.Queries;
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
public class OrderQueries
 | 
					public class OrderQueries
 | 
				
			||||||
    : IOrderQueries
 | 
					    : IOrderQueries
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
				
			|||||||
@ -144,7 +144,7 @@ public class OrderingContextSeed
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (csvheaders.Count() != requiredHeaders.Count())
 | 
					        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)
 | 
					        foreach (var requiredHeader in requiredHeaders)
 | 
				
			||||||
 | 
				
			|||||||
@ -47,7 +47,7 @@ builder.Services
 | 
				
			|||||||
    .AddCustomMvc()
 | 
					    .AddCustomMvc()
 | 
				
			||||||
    .AddHealthChecks(builder.Configuration)
 | 
					    .AddHealthChecks(builder.Configuration)
 | 
				
			||||||
    .AddCustomDbContext(builder.Configuration)
 | 
					    .AddCustomDbContext(builder.Configuration)
 | 
				
			||||||
    .AddCustomSwagger(builder.Configuration)    
 | 
					    .AddCustomSwagger(builder.Configuration)
 | 
				
			||||||
    .AddCustomAuthentication(builder.Configuration)
 | 
					    .AddCustomAuthentication(builder.Configuration)
 | 
				
			||||||
    .AddCustomAuthorization(builder.Configuration)
 | 
					    .AddCustomAuthorization(builder.Configuration)
 | 
				
			||||||
    .AddCustomIntegrations(builder.Configuration)
 | 
					    .AddCustomIntegrations(builder.Configuration)
 | 
				
			||||||
 | 
				
			|||||||
@ -132,7 +132,7 @@ namespace Ordering.BackgroundTasks.Extensions
 | 
				
			|||||||
                .Enrich.FromLogContext()
 | 
					                .Enrich.FromLogContext()
 | 
				
			||||||
                .WriteTo.Console()
 | 
					                .WriteTo.Console()
 | 
				
			||||||
                .WriteTo.Seq(string.IsNullOrWhiteSpace(seqServerUrl) ? "http://seq" : seqServerUrl)
 | 
					                .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)
 | 
					                .ReadFrom.Configuration(configuration)
 | 
				
			||||||
                .CreateLogger();
 | 
					                .CreateLogger();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -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);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.Events;
 | 
					namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.Events;
 | 
				
			||||||
  
 | 
					
 | 
				
			||||||
/// <summary>
 | 
					/// <summary>
 | 
				
			||||||
/// Event used when the order is paid
 | 
					/// Event used when the order is paid
 | 
				
			||||||
/// </summary>
 | 
					/// </summary>
 | 
				
			||||||
 | 
				
			|||||||
@ -9,14 +9,14 @@ public abstract class Enumeration : IComparable
 | 
				
			|||||||
    protected Enumeration(int id, string name) => (Id, Name) = (id, name);
 | 
					    protected Enumeration(int id, string name) => (Id, Name) = (id, name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public override string ToString() => Name;
 | 
					    public override string ToString() => Name;
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
    public static IEnumerable<T> GetAll<T>() where T : Enumeration =>
 | 
					    public static IEnumerable<T> GetAll<T>() where T : Enumeration =>
 | 
				
			||||||
        typeof(T).GetFields(BindingFlags.Public |
 | 
					        typeof(T).GetFields(BindingFlags.Public |
 | 
				
			||||||
                            BindingFlags.Static |
 | 
					                            BindingFlags.Static |
 | 
				
			||||||
                            BindingFlags.DeclaredOnly)
 | 
					                            BindingFlags.DeclaredOnly)
 | 
				
			||||||
                    .Select(f => f.GetValue(null))
 | 
					                    .Select(f => f.GetValue(null))
 | 
				
			||||||
                    .Cast<T>();
 | 
					                    .Cast<T>();
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
    public override bool Equals(object obj)
 | 
					    public override bool Equals(object obj)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (obj is not Enumeration otherValue)
 | 
					        if (obj is not Enumeration otherValue)
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
namespace Microsoft.eShopOnContainers.Payment.API.IntegrationEvents.EventHandling;
 | 
					namespace Microsoft.eShopOnContainers.Payment.API.IntegrationEvents.EventHandling;
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
public class OrderStatusChangedToStockConfirmedIntegrationEventHandler :
 | 
					public class OrderStatusChangedToStockConfirmedIntegrationEventHandler :
 | 
				
			||||||
    IIntegrationEventHandler<OrderStatusChangedToStockConfirmedIntegrationEvent>
 | 
					    IIntegrationEventHandler<OrderStatusChangedToStockConfirmedIntegrationEvent>
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
namespace Microsoft.eShopOnContainers.Payment.API.IntegrationEvents.Events;
 | 
					namespace Microsoft.eShopOnContainers.Payment.API.IntegrationEvents.Events;
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
public record OrderStatusChangedToStockConfirmedIntegrationEvent : IntegrationEvent
 | 
					public record OrderStatusChangedToStockConfirmedIntegrationEvent : IntegrationEvent
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public int OrderId { get; }
 | 
					    public int OrderId { get; }
 | 
				
			||||||
 | 
				
			|||||||
@ -26,7 +26,7 @@ public class HttpGlobalExceptionFilter : IExceptionFilter
 | 
				
			|||||||
                Detail = "Please refer to the errors property for additional details."
 | 
					                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.Result = new BadRequestObjectResult(problemDetails);
 | 
				
			||||||
            context.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
 | 
					            context.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
 | 
				
			||||||
 | 
				
			|||||||
@ -33,7 +33,7 @@ public class Startup
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
 | 
					    public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
 | 
				
			||||||
    {        
 | 
					    {
 | 
				
			||||||
        var pathBase = Configuration["PATH_BASE"];
 | 
					        var pathBase = Configuration["PATH_BASE"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!string.IsNullOrEmpty(pathBase))
 | 
					        if (!string.IsNullOrEmpty(pathBase))
 | 
				
			||||||
@ -64,7 +64,7 @@ public class Startup
 | 
				
			|||||||
        app.UseSwagger()
 | 
					        app.UseSwagger()
 | 
				
			||||||
            .UseSwaggerUI(c =>
 | 
					            .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.OAuthClientId("webhooksswaggerui");
 | 
				
			||||||
                c.OAuthAppName("WebHooks Service Swagger UI");
 | 
					                c.OAuthAppName("WebHooks Service Swagger UI");
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
@ -137,7 +137,7 @@ internal static class CustomExtensionMethods
 | 
				
			|||||||
    public static IServiceCollection AddSwagger(this IServiceCollection services, IConfiguration configuration)
 | 
					    public static IServiceCollection AddSwagger(this IServiceCollection services, IConfiguration configuration)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        services.AddSwaggerGen(options =>
 | 
					        services.AddSwaggerGen(options =>
 | 
				
			||||||
        {            
 | 
					        {
 | 
				
			||||||
            options.SwaggerDoc("v1", new OpenApiInfo
 | 
					            options.SwaggerDoc("v1", new OpenApiInfo
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                Title = "eShopOnContainers - Webhooks HTTP API",
 | 
					                Title = "eShopOnContainers - Webhooks HTTP API",
 | 
				
			||||||
@ -239,47 +239,47 @@ internal static class CustomExtensionMethods
 | 
				
			|||||||
        services.AddTransient<Func<DbConnection, IIntegrationEventLogService>>(
 | 
					        services.AddTransient<Func<DbConnection, IIntegrationEventLogService>>(
 | 
				
			||||||
                sp => (DbConnection c) => new IntegrationEventLogService(c));
 | 
					                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"]);
 | 
				
			||||||
                    var subscriptionClientName = configuration["SubscriptionClientName"];
 | 
					            });
 | 
				
			||||||
                    return new DefaultServiceBusPersisterConnection(configuration["EventBusConnection"]);
 | 
					        }
 | 
				
			||||||
                });
 | 
					        else
 | 
				
			||||||
            }
 | 
					        {
 | 
				
			||||||
            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()
 | 
					                if (!string.IsNullOrEmpty(configuration["EventBusUserName"]))
 | 
				
			||||||
                    {
 | 
					                {
 | 
				
			||||||
                        HostName = configuration["EventBusConnection"],
 | 
					                    factory.UserName = configuration["EventBusUserName"];
 | 
				
			||||||
                        DispatchConsumersAsync = true
 | 
					                }
 | 
				
			||||||
                    };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if (!string.IsNullOrEmpty(configuration["EventBusUserName"]))
 | 
					                if (!string.IsNullOrEmpty(configuration["EventBusPassword"]))
 | 
				
			||||||
                    {
 | 
					                {
 | 
				
			||||||
                        factory.UserName = configuration["EventBusUserName"];
 | 
					                    factory.Password = configuration["EventBusPassword"];
 | 
				
			||||||
                    }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if (!string.IsNullOrEmpty(configuration["EventBusPassword"]))
 | 
					                var retryCount = 5;
 | 
				
			||||||
                    {
 | 
					                if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"]))
 | 
				
			||||||
                        factory.Password = configuration["EventBusPassword"];
 | 
					                {
 | 
				
			||||||
                    }
 | 
					                    retryCount = int.Parse(configuration["EventBusRetryCount"]);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    var retryCount = 5;
 | 
					                return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount);
 | 
				
			||||||
                    if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"]))
 | 
					            });
 | 
				
			||||||
                    {
 | 
					        }
 | 
				
			||||||
                        retryCount = int.Parse(configuration["EventBusRetryCount"]);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount);
 | 
					        return services;
 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return services;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static IServiceCollection AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration)
 | 
					    public static IServiceCollection AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration)
 | 
				
			||||||
 | 
				
			|||||||
@ -73,7 +73,7 @@ public class OrderingScenarios : OrderingScenariosBase
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
                PropertyNameCaseInsensitive = true
 | 
					                PropertyNameCaseInsensitive = true
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
                
 | 
					
 | 
				
			||||||
            order.City = city;
 | 
					            order.City = city;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (IsOrderCreated(order, city))
 | 
					            if (IsOrderCreated(order, city))
 | 
				
			||||||
 | 
				
			|||||||
@ -1,16 +1,16 @@
 | 
				
			|||||||
public static class SessionExtensions
 | 
					public static class SessionExtensions
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public static void SetObject(this ISession session, string key, object value) =>
 | 
					    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)
 | 
					    public static T GetObject<T>(this ISession session, string key)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        var value = session.GetString(key);
 | 
					        var value = session.GetString(key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return value == null ? default(T) :JsonSerializer.Deserialize<T>(value, new JsonSerializerOptions
 | 
					        return value == null ? default(T) : JsonSerializer.Deserialize<T>(value, new JsonSerializerOptions
 | 
				
			||||||
            {
 | 
					        {
 | 
				
			||||||
                PropertyNameCaseInsensitive = true
 | 
					            PropertyNameCaseInsensitive = true
 | 
				
			||||||
            });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -73,7 +73,7 @@ Serilog.ILogger CreateSerilogLogger(IConfiguration configuration)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    if (!string.IsNullOrWhiteSpace(logstashUrl))
 | 
					    if (!string.IsNullOrWhiteSpace(logstashUrl))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        cfg.WriteTo.Http(logstashUrl,null);
 | 
					        cfg.WriteTo.Http(logstashUrl, null);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return cfg.CreateLogger();
 | 
					    return cfg.CreateLogger();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -52,7 +52,7 @@ public class BasketService : IBasketService
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        var uri = API.Basket.CheckoutBasket(_basketByPassUrl);
 | 
					        var uri = API.Basket.CheckoutBasket(_basketByPassUrl);
 | 
				
			||||||
        var basketContent = new StringContent(JsonSerializer.Serialize(basket), Encoding.UTF8, "application/json");
 | 
					        var basketContent = new StringContent(JsonSerializer.Serialize(basket), Encoding.UTF8, "application/json");
 | 
				
			||||||
            
 | 
					
 | 
				
			||||||
        _logger.LogInformation("Uri chechout {uri}", uri);
 | 
					        _logger.LogInformation("Uri chechout {uri}", uri);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        var response = await _apiClient.PostAsync(uri, basketContent);
 | 
					        var response = await _apiClient.PostAsync(uri, basketContent);
 | 
				
			||||||
 | 
				
			|||||||
@ -40,10 +40,10 @@ public class CatalogService : ICatalogService
 | 
				
			|||||||
        var items = new List<SelectListItem>();
 | 
					        var items = new List<SelectListItem>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        items.Add(new SelectListItem() { Value = null, Text = "All", Selected = true });
 | 
					        items.Add(new SelectListItem() { Value = null, Text = "All", Selected = true });
 | 
				
			||||||
            
 | 
					
 | 
				
			||||||
        using var brands = JsonDocument.Parse(responseString);
 | 
					        using var brands = JsonDocument.Parse(responseString);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        foreach (JsonElement brand  in brands.RootElement.EnumerateArray())
 | 
					        foreach (JsonElement brand in brands.RootElement.EnumerateArray())
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            items.Add(new SelectListItem()
 | 
					            items.Add(new SelectListItem()
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@ -63,7 +63,7 @@ public class CatalogService : ICatalogService
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        var items = new List<SelectListItem>();
 | 
					        var items = new List<SelectListItem>();
 | 
				
			||||||
        items.Add(new SelectListItem() { Value = null, Text = "All", Selected = true });
 | 
					        items.Add(new SelectListItem() { Value = null, Text = "All", Selected = true });
 | 
				
			||||||
            
 | 
					
 | 
				
			||||||
        using var catalogTypes = JsonDocument.Parse(responseString);
 | 
					        using var catalogTypes = JsonDocument.Parse(responseString);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        foreach (JsonElement catalogType in catalogTypes.RootElement.EnumerateArray())
 | 
					        foreach (JsonElement catalogType in catalogTypes.RootElement.EnumerateArray())
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
namespace Microsoft.eShopOnContainers.WebMVC.ViewModels;
 | 
					namespace Microsoft.eShopOnContainers.WebMVC.ViewModels;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class Order
 | 
					public class Order
 | 
				
			||||||
{ 
 | 
					{
 | 
				
			||||||
    [JsonConverter(typeof(NumberToStringConverter))]
 | 
					    [JsonConverter(typeof(NumberToStringConverter))]
 | 
				
			||||||
    public string OrderNumber { get; set; }
 | 
					    public string OrderNumber { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -45,7 +45,7 @@ public class Order
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public List<SelectListItem> ActionCodeSelectList =>
 | 
					    public List<SelectListItem> ActionCodeSelectList =>
 | 
				
			||||||
        GetActionCodesByCurrentState();
 | 
					        GetActionCodesByCurrentState();
 | 
				
			||||||
                
 | 
					
 | 
				
			||||||
    public List<OrderItem> OrderItems { get; set; }
 | 
					    public List<OrderItem> OrderItems { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [Required]
 | 
					    [Required]
 | 
				
			||||||
 | 
				
			|||||||
@ -14,5 +14,5 @@ public class HomeController : Controller
 | 
				
			|||||||
    public IActionResult Configuration()
 | 
					    public IActionResult Configuration()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return Json(_settings.Value);
 | 
					        return Json(_settings.Value);
 | 
				
			||||||
    } 
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -3,7 +3,7 @@
 | 
				
			|||||||
public class WebHookReceived
 | 
					public class WebHookReceived
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public DateTime When { get; set; }
 | 
					    public DateTime When { get; set; }
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
    public string Data { get; set; }
 | 
					    public string Data { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public string Token { get; set; }
 | 
					    public string Token { get; set; }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user