Fix formatting
This commit is contained in:
		
							parent
							
								
									9d38de0c83
								
							
						
					
					
						commit
						451d79f7b9
					
				| @ -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