diff --git a/.gitignore b/.gitignore index 69800e3b7..8bad337c5 100644 --- a/.gitignore +++ b/.gitignore @@ -269,4 +269,4 @@ pub/ .mfractor # Ignore HealthCheckdb -*healthchecksdb* \ No newline at end of file +*healthchecksdb* diff --git a/README.md b/README.md index 6fceb20ee..2a8f8e22c 100644 --- a/README.md +++ b/README.md @@ -5,66 +5,21 @@ Sample .NET Core reference application, powered by Microsoft, based on a simplif Dev branch contains the latest "stable" code, and their images are tagged with `:dev` in our [Docker Hub](https://cloud.docker.com/u/eshop/repository/list): -Api Gateways base image +| Basket API | Catalog API | Identity API | Location API | +| ------------- | ------------- | ------------- | ------------- | +| [![Basket API](https://msftdevtools.visualstudio.com/eShopOnContainers/_apis/build/status/microservices/basket?branchName=dev)](https://msftdevtools.visualstudio.com/eShopOnContainers/_build/latest?definitionId=199&branchName=dev) | [![Catalog API](https://msftdevtools.visualstudio.com/eShopOnContainers/_apis/build/status/microservices/catalog?branchName=dev)](https://msftdevtools.visualstudio.com/eShopOnContainers/_build/latest?definitionId=197&branchName=dev) | [![Identity API](https://msftdevtools.visualstudio.com/eShopOnContainers/_apis/build/status/microservices/identity?branchName=dev)](https://msftdevtools.visualstudio.com/eShopOnContainers/_build/latest?definitionId=200&branchName=dev) | [![Location API](https://msftdevtools.visualstudio.com/eShopOnContainers/_apis/build/status/microservices/location?branchName=dev)](https://msftdevtools.visualstudio.com/eShopOnContainers/_build/latest?definitionId=202&branchName=dev) | -[![Api Gateways base image](https://msftdevtools.visualstudio.com/eShopOnContainers/_apis/build/status/microservices/apigws?branchName=dev)](https://msftdevtools.visualstudio.com/eShopOnContainers/_build/latest?definitionId=201&branchName=dev) +| Marketing API | Ordering API | Payment API | Api Gateways base image | +| ------------- | ------------- | ------------- | ------------- | +| [![Marketing API](https://msftdevtools.visualstudio.com/eShopOnContainers/_apis/build/status/microservices/marketing?branchName=dev)](https://msftdevtools.visualstudio.com/eShopOnContainers/_build/latest?definitionId=203&branchName=dev) | [![Ordering API](https://msftdevtools.visualstudio.com/eShopOnContainers/_apis/build/status/microservices/ordering?branchName=dev)](https://msftdevtools.visualstudio.com/eShopOnContainers/_build/latest?definitionId=198&branchName=dev) | [![Payment API](https://msftdevtools.visualstudio.com/eShopOnContainers/_apis/build/status/microservices/payment?branchName=dev)](https://msftdevtools.visualstudio.com/eShopOnContainers/_build/latest?definitionId=205&branchName=dev) | [![Api Gateways base image](https://msftdevtools.visualstudio.com/eShopOnContainers/_apis/build/status/microservices/apigws?branchName=dev)](https://msftdevtools.visualstudio.com/eShopOnContainers/_build/latest?definitionId=201&branchName=dev) -Basket API - -[![Basket API](https://msftdevtools.visualstudio.com/eShopOnContainers/_apis/build/status/microservices/basket?branchName=dev)](https://msftdevtools.visualstudio.com/eShopOnContainers/_build/latest?definitionId=199&branchName=dev) - -Catalog API - -[![Catalog API](https://msftdevtools.visualstudio.com/eShopOnContainers/_apis/build/status/microservices/catalog?branchName=dev)](https://msftdevtools.visualstudio.com/eShopOnContainers/_build/latest?definitionId=197&branchName=dev) - -Identity API - -[![Identity API](https://msftdevtools.visualstudio.com/eShopOnContainers/_apis/build/status/microservices/identity?branchName=dev)](https://msftdevtools.visualstudio.com/eShopOnContainers/_build/latest?definitionId=200&branchName=dev) - -Location API - -[![Location API](https://msftdevtools.visualstudio.com/eShopOnContainers/_apis/build/status/microservices/location?branchName=dev)](https://msftdevtools.visualstudio.com/eShopOnContainers/_build/latest?definitionId=202&branchName=dev) - -Marketing API - -[![Marketing API](https://msftdevtools.visualstudio.com/eShopOnContainers/_apis/build/status/microservices/marketing?branchName=dev)](https://msftdevtools.visualstudio.com/eShopOnContainers/_build/latest?definitionId=203&branchName=dev) - -Ordering API - -[![Ordering API](https://msftdevtools.visualstudio.com/eShopOnContainers/_apis/build/status/microservices/ordering?branchName=dev)](https://msftdevtools.visualstudio.com/eShopOnContainers/_build/latest?definitionId=198&branchName=dev) - -Payment API - -[![Payment API](https://msftdevtools.visualstudio.com/eShopOnContainers/_apis/build/status/microservices/payment?branchName=dev)](https://msftdevtools.visualstudio.com/eShopOnContainers/_build/latest?definitionId=205&branchName=dev) - -Webhooks API - -[![Webhooks API](https://msftdevtools.visualstudio.com/eShopOnContainers/_apis/build/status/microservices/webhooks?branchName=dev)](https://msftdevtools.visualstudio.com/eShopOnContainers/_build/latest?definitionId=207&branchName=dev) - -Web Shopping Aggregator - -[![Web Shopping Aggregator](https://msftdevtools.visualstudio.com/eShopOnContainers/_apis/build/status/microservices/web-shopping-agg?branchName=dev)](https://msftdevtools.visualstudio.com/eShopOnContainers/_build/latest?definitionId=206&branchName=dev) - -Mobile Shopping Aggregator - -[![Mobile Shopping Aggregator](https://msftdevtools.visualstudio.com/eShopOnContainers/_apis/build/status/microservices/mobile-shopping-agg?branchName=dev)](https://msftdevtools.visualstudio.com/eShopOnContainers/_build/latest?definitionId=204&branchName=dev) - -Webbhooks demo client - -[![Webhooks demo client](https://msftdevtools.visualstudio.com/eShopOnContainers/_apis/build/status/microservices/webhooks-client?branchName=dev)](https://msftdevtools.visualstudio.com/eShopOnContainers/_build/latest?definitionId=208&branchName=dev) - -WebMVC Client - -[![WebMVC Client](https://msftdevtools.visualstudio.com/eShopOnContainers/_apis/build/status/microservices/webmvc?branchName=dev)](https://msftdevtools.visualstudio.com/eShopOnContainers/_build/latest?definitionId=209&branchName=dev) - -WebSPA Client - -[![WebSPA Client](https://msftdevtools.visualstudio.com/eShopOnContainers/_apis/build/status/microservices/webspa?branchName=dev)](https://msftdevtools.visualstudio.com/eShopOnContainers/_build/latest?definitionId=210&branchName=dev) - -Web Status - -[![Web Status](https://msftdevtools.visualstudio.com/eShopOnContainers/_apis/build/status/microservices/webstatus?branchName=dev)](https://msftdevtools.visualstudio.com/eShopOnContainers/_build/latest?definitionId=211&branchName=dev) +| Web Shopping Aggregator | Mobile Shopping Aggregator | WebMVC Client | WebSPA Client | +| ------------- | ------------- | ------------- | ------------- | +| [![Web Shopping Aggregator](https://msftdevtools.visualstudio.com/eShopOnContainers/_apis/build/status/microservices/web-shopping-agg?branchName=dev)](https://msftdevtools.visualstudio.com/eShopOnContainers/_build/latest?definitionId=206&branchName=dev) | [![Mobile Shopping Aggregator](https://msftdevtools.visualstudio.com/eShopOnContainers/_apis/build/status/microservices/mobile-shopping-agg?branchName=dev)](https://msftdevtools.visualstudio.com/eShopOnContainers/_build/latest?definitionId=204&branchName=dev) | [![WebMVC Client](https://msftdevtools.visualstudio.com/eShopOnContainers/_apis/build/status/microservices/webmvc?branchName=dev)](https://msftdevtools.visualstudio.com/eShopOnContainers/_build/latest?definitionId=209&branchName=dev) | [![WebSPA Client](https://msftdevtools.visualstudio.com/eShopOnContainers/_apis/build/status/microservices/webspa?branchName=dev)](https://msftdevtools.visualstudio.com/eShopOnContainers/_build/latest?definitionId=210&branchName=dev) | +| Web Status | Webhooks API | Webbhooks demo client | +| ------------- | ------------- | ------------- | + [![Web Status](https://msftdevtools.visualstudio.com/eShopOnContainers/_apis/build/status/microservices/webstatus?branchName=dev)](https://msftdevtools.visualstudio.com/eShopOnContainers/_build/latest?definitionId=211&branchName=dev) | [![Webhooks API](https://msftdevtools.visualstudio.com/eShopOnContainers/_apis/build/status/microservices/webhooks?branchName=dev)](https://msftdevtools.visualstudio.com/eShopOnContainers/_build/latest?definitionId=207&branchName=dev) | [![Webhooks demo client](https://msftdevtools.visualstudio.com/eShopOnContainers/_apis/build/status/microservices/webhooks-client?branchName=dev)](https://msftdevtools.visualstudio.com/eShopOnContainers/_build/latest?definitionId=208&branchName=dev) | ## IMPORTANT NOTES! **You can use either the latest version of Visual Studio or simply Docker CLI and .NET CLI for Windows, Mac and Linux**. diff --git a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs index 9044a4283..397b75017 100644 --- a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs +++ b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs @@ -178,27 +178,46 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ { if (_consumerChannel != null) { - var consumer = new EventingBasicConsumer(_consumerChannel); - consumer.Received += async (model, ea) => - { - var eventName = ea.RoutingKey; - var message = Encoding.UTF8.GetString(ea.Body); - - await ProcessEvent(eventName, message); + var consumer = new AsyncEventingBasicConsumer(_consumerChannel); - _consumerChannel.BasicAck(ea.DeliveryTag, multiple: false); - }; + consumer.Received += Consumer_Received; - _consumerChannel.BasicConsume(queue: _queueName, - autoAck: false, - consumer: consumer); + _consumerChannel.BasicConsume( + queue: _queueName, + autoAck: false, + consumer: consumer); } else { - _logger.LogError("StartBasicConsume can not call on _consumerChannelCreated == false"); + _logger.LogError("StartBasicConsume can't call on _consumerChannel == null"); } } + private async Task Consumer_Received(object sender, BasicDeliverEventArgs eventArgs) + { + var eventName = eventArgs.RoutingKey; + var message = Encoding.UTF8.GetString(eventArgs.Body); + + try + { + if (message.ToLowerInvariant().Contains("throw-fake-exception")) + { + throw new InvalidOperationException($"Fake exception requested: \"{message}\""); + } + + await ProcessEvent(eventName, message); + } + catch (Exception ex) + { + _logger.LogWarning(ex, "----- ERROR Processing message \"{Message}\"", message); + } + + // Even on exception we take the message off the queue. + // in a REAL WORLD app this should be handled with a Dead Letter Exchange (DLX). + // For more information see: https://www.rabbitmq.com/dlx.html + _consumerChannel.BasicAck(eventArgs.DeliveryTag, multiple: false); + } + private IModel CreateConsumerChannel() { if (!_persistentConnection.IsConnected) @@ -209,7 +228,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ var channel = _persistentConnection.CreateModel(); channel.ExchangeDeclare(exchange: BROKER_NAME, - type: "direct"); + type: "direct"); channel.QueueDeclare(queue: _queueName, durable: true, diff --git a/src/Services/Basket/Basket.API/Startup.cs b/src/Services/Basket/Basket.API/Startup.cs index 235b787d0..97ede1879 100644 --- a/src/Services/Basket/Basket.API/Startup.cs +++ b/src/Services/Basket/Basket.API/Startup.cs @@ -105,7 +105,8 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API var factory = new ConnectionFactory() { - HostName = Configuration["EventBusConnection"] + HostName = Configuration["EventBusConnection"], + DispatchConsumersAsync = true }; if (!string.IsNullOrEmpty(Configuration["EventBusUserName"])) diff --git a/src/Services/Catalog/Catalog.API/Model/CatalogItem.cs b/src/Services/Catalog/Catalog.API/Model/CatalogItem.cs index 459c60098..2e4579f7f 100644 --- a/src/Services/Catalog/Catalog.API/Model/CatalogItem.cs +++ b/src/Services/Catalog/Catalog.API/Model/CatalogItem.cs @@ -64,7 +64,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Model if (quantityDesired <= 0) { - throw new CatalogDomainException($"Item units desired should be greater than cero"); + throw new CatalogDomainException($"Item units desired should be greater than zero"); } int removed = Math.Min(quantityDesired, this.AvailableStock); diff --git a/src/Services/Catalog/Catalog.API/Startup.cs b/src/Services/Catalog/Catalog.API/Startup.cs index 0258a0a98..1a51a86fb 100644 --- a/src/Services/Catalog/Catalog.API/Startup.cs +++ b/src/Services/Catalog/Catalog.API/Startup.cs @@ -297,7 +297,8 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API var factory = new ConnectionFactory() { - HostName = configuration["EventBusConnection"] + HostName = configuration["EventBusConnection"], + DispatchConsumersAsync = true }; if (!string.IsNullOrEmpty(configuration["EventBusUserName"])) diff --git a/src/Services/Identity/Identity.API/README.md b/src/Services/Identity/Identity.API/README.md index 76e599dea..ffaaed531 100644 --- a/src/Services/Identity/Identity.API/README.md +++ b/src/Services/Identity/Identity.API/README.md @@ -2,10 +2,10 @@ Sample reference containerized application, cross-platform and microservices architecture. Powered by Microsoft -#Overview +## Overview This sample runs a microservices oriented application and a .net core Mvc application that consumes this services. You can find more information about how to set up docker in your machine in the global directory solution. -#Setup +## Setup This service is a identity provider or STS (Security Token Service) currently implemented with IdentityServer 4 wrapping ASP.NET Identity underneath. Check procedures on how to get the sample app started at the Wiki: diff --git a/src/Services/Location/Locations.API/Startup.cs b/src/Services/Location/Locations.API/Startup.cs index 6d5fe3200..4664381d0 100644 --- a/src/Services/Location/Locations.API/Startup.cs +++ b/src/Services/Location/Locations.API/Startup.cs @@ -77,7 +77,8 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API var factory = new ConnectionFactory() { - HostName = Configuration["EventBusConnection"] + HostName = Configuration["EventBusConnection"], + DispatchConsumersAsync = true }; if (!string.IsNullOrEmpty(Configuration["EventBusUserName"])) diff --git a/src/Services/Marketing/Marketing.API/Startup.cs b/src/Services/Marketing/Marketing.API/Startup.cs index 75c749452..7f990e3ad 100644 --- a/src/Services/Marketing/Marketing.API/Startup.cs +++ b/src/Services/Marketing/Marketing.API/Startup.cs @@ -101,7 +101,8 @@ var factory = new ConnectionFactory() { - HostName = Configuration["EventBusConnection"] + HostName = Configuration["EventBusConnection"], + DispatchConsumersAsync = true }; if (!string.IsNullOrEmpty(Configuration["EventBusUserName"])) diff --git a/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs b/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs index ae35b0377..7a592bfb8 100644 --- a/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs +++ b/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs @@ -105,6 +105,8 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers { try { + //Todo: It's good idea to take advantage of GetOrderByIdQuery and handle by GetCustomerByIdQueryHandler + //var order customer = await _mediator.Send(new GetOrderByIdQuery(orderId)); var order = await _orderQueries.GetOrderAsync(orderId); return Ok(order); @@ -149,4 +151,4 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers return await _mediator.Send(createOrderDraftCommand); } } -} \ No newline at end of file +} diff --git a/src/Services/Ordering/Ordering.API/Startup.cs b/src/Services/Ordering/Ordering.API/Startup.cs index cd34f98dd..b77354052 100644 --- a/src/Services/Ordering/Ordering.API/Startup.cs +++ b/src/Services/Ordering/Ordering.API/Startup.cs @@ -305,7 +305,8 @@ var factory = new ConnectionFactory() { - HostName = configuration["EventBusConnection"] + HostName = configuration["EventBusConnection"], + DispatchConsumersAsync = true }; if (!string.IsNullOrEmpty(configuration["EventBusUserName"])) diff --git a/src/Services/Ordering/Ordering.BackgroundTasks/Startup.cs b/src/Services/Ordering/Ordering.BackgroundTasks/Startup.cs index 683fe1d0c..9d6a78e38 100644 --- a/src/Services/Ordering/Ordering.BackgroundTasks/Startup.cs +++ b/src/Services/Ordering/Ordering.BackgroundTasks/Startup.cs @@ -68,7 +68,8 @@ namespace Ordering.BackgroundTasks var factory = new ConnectionFactory() { - HostName = Configuration["EventBusConnection"] + HostName = Configuration["EventBusConnection"], + DispatchConsumersAsync = true }; if (!string.IsNullOrEmpty(Configuration["EventBusUserName"])) diff --git a/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs b/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs index 99b3154d8..7da025d3a 100644 --- a/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs +++ b/src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs @@ -132,7 +132,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O AddDomainEvent(new OrderStatusChangedToPaidDomainEvent(Id, OrderItems)); _orderStatusId = OrderStatus.Paid.Id; - _description = "The payment was performed at a simulated \"American Bank checking bank account endinf on XX35071\""; + _description = "The payment was performed at a simulated \"American Bank checking bank account ending on XX35071\""; } } diff --git a/src/Services/Ordering/Ordering.SignalrHub/Startup.cs b/src/Services/Ordering/Ordering.SignalrHub/Startup.cs index e8bb7ecd1..edcc80521 100644 --- a/src/Services/Ordering/Ordering.SignalrHub/Startup.cs +++ b/src/Services/Ordering/Ordering.SignalrHub/Startup.cs @@ -80,7 +80,8 @@ namespace Ordering.SignalrHub var factory = new ConnectionFactory() { - HostName = Configuration["EventBusConnection"] + HostName = Configuration["EventBusConnection"], + DispatchConsumersAsync = true }; if (!string.IsNullOrEmpty(Configuration["EventBusUserName"])) diff --git a/src/Services/Payment/Payment.API/Startup.cs b/src/Services/Payment/Payment.API/Startup.cs index 4d5010868..39bb78f91 100644 --- a/src/Services/Payment/Payment.API/Startup.cs +++ b/src/Services/Payment/Payment.API/Startup.cs @@ -58,7 +58,8 @@ namespace Payment.API var logger = sp.GetRequiredService>(); var factory = new ConnectionFactory() { - HostName = Configuration["EventBusConnection"] + HostName = Configuration["EventBusConnection"], + DispatchConsumersAsync = true }; if (!string.IsNullOrEmpty(Configuration["EventBusUserName"])) diff --git a/src/Services/Webhooks/Webhooks.API/Startup.cs b/src/Services/Webhooks/Webhooks.API/Startup.cs index 654b1c897..9d39da719 100644 --- a/src/Services/Webhooks/Webhooks.API/Startup.cs +++ b/src/Services/Webhooks/Webhooks.API/Startup.cs @@ -320,7 +320,8 @@ namespace Webhooks.API var factory = new ConnectionFactory() { - HostName = configuration["EventBusConnection"] + HostName = configuration["EventBusConnection"], + DispatchConsumersAsync = true }; if (!string.IsNullOrEmpty(configuration["EventBusUserName"]))