Browse Source

Merge branch 'order-processflow-redesign' of https://github.com/dotnet-architecture/eShopOnContainers into order-processflow-redesign

pull/223/head
Ramón Tomás 7 years ago
parent
commit
87201a3f35
53 changed files with 273 additions and 357 deletions
  1. +0
    -1
      docker-compose.override.yml
  2. +6
    -6
      src/Services/Basket/Basket.API/Controllers/BasketController.cs
  3. +8
    -20
      src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs
  4. +6
    -5
      src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs
  5. +3
    -3
      src/Services/Catalog/Catalog.API/IntegrationEvents/Events/OrderStatusChangedToAwaitingValidationIntegrationEvent.cs
  6. +3
    -3
      src/Services/Catalog/Catalog.API/IntegrationEvents/Events/OrderStatusChangedToPaidIntegrationEvent.cs
  7. +2
    -2
      src/Services/Catalog/Catalog.API/IntegrationEvents/Events/OrderStockRejectedIntegrationEvent.cs
  8. +11
    -11
      src/Services/Catalog/Catalog.API/Startup.cs
  9. +1
    -5
      src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/BuyerAndPaymentMethodVerified/UpdateOrderWhenBuyerAndPaymentMethodVerifiedDomainEventHandler.cs
  10. +4
    -5
      src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderGracePeriodConfirmed/OrderStatusChangedToAwaitingValidationDomainEventHandler.cs
  11. +3
    -4
      src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderPaid/OrderStatusChangedToPaidDomainEventHandler.cs
  12. +3
    -4
      src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStockConfirmed/OrderStatusChangedToStockConfirmedDomainEventHandler.cs
  13. +0
    -12
      src/Services/Ordering/Ordering.API/Application/IntegrationCommands/Commands/ConfirmGracePeriodCommand.cs
  14. +0
    -14
      src/Services/Ordering/Ordering.API/Application/IntegrationCommands/Commands/PayOrderCommand.cs
  15. +1
    -1
      src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentFailedIntegrationEventHandler.cs
  16. +1
    -1
      src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentSuccededIntegrationEventHandler.cs
  17. +1
    -1
      src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockConfirmedIntegrationEventHandler.cs
  18. +0
    -33
      src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockNotConfirmedIntegrationEventHandler.cs
  19. +31
    -0
      src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockRejectedIntegrationEventHandler.cs
  20. +12
    -0
      src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/GracePeriodConfirmedIntegrationEvent.cs
  21. +4
    -4
      src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderPaymentFailedIntegrationEvent .cs
  22. +4
    -4
      src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderPaymentSuccededIntegrationEvent.cs
  23. +3
    -3
      src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStatusChangedToAwaitingValidationIntegrationEvent.cs
  24. +3
    -3
      src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStatusChangedToPaidIntegrationEvent.cs
  25. +12
    -0
      src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStatusChangedToStockConfirmedIntegrationEvent.cs
  26. +4
    -5
      src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStockRejectedIntegrationEvent.cs
  27. +0
    -1
      src/Services/Ordering/Ordering.API/Application/IntegrationEvents/IOrderingIntegrationEventService.cs
  28. +2
    -1
      src/Services/Ordering/Ordering.API/Application/IntegrationEvents/OrderingIntegrationEventService.cs
  29. +4
    -9
      src/Services/Ordering/Ordering.API/Application/Sagas/OrderProcessSaga.cs
  30. +2
    -3
      src/Services/Ordering/Ordering.API/Application/Sagas/OrderSaga.cs
  31. +0
    -1
      src/Services/Ordering/Ordering.API/Ordering.API.csproj
  32. +6
    -14
      src/Services/Ordering/Ordering.API/Startup.cs
  33. +2
    -0
      src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Address.cs
  34. +0
    -2
      src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/IOrderRepository.cs
  35. +32
    -47
      src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs
  36. +11
    -8
      src/Services/Ordering/Ordering.Infrastructure/Repositories/OrderRepository.cs
  37. +0
    -27
      src/Services/Payment/Payment.API/IntegrationCommands/CommandHandlers/PayOrderCommandHandler.cs
  38. +0
    -11
      src/Services/Payment/Payment.API/IntegrationCommands/Commands/PayOrderCommand.cs
  39. +37
    -0
      src/Services/Payment/Payment.API/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs
  40. +12
    -0
      src/Services/Payment/Payment.API/IntegrationEvents/Events/OrderStatusChangedToStockConfirmedIntegrationEvent.cs
  41. +0
    -9
      src/Services/Payment/Payment.API/IntegrationEvents/IPaymentIntegrationEventService.cs
  42. +0
    -21
      src/Services/Payment/Payment.API/IntegrationEvents/PaymentIntegrationEventService.cs
  43. +8
    -0
      src/Services/Payment/Payment.API/PaymentSettings.cs
  44. +8
    -8
      src/Services/Payment/Payment.API/Startup.cs
  45. +2
    -1
      src/Services/Payment/Payment.API/appsettings.json
  46. +2
    -2
      src/Services/SagaManager/SagaManager/IntegrationEvents/Events/GracePeriodConfirmedIntegrationEvent.cs
  47. +0
    -9
      src/Services/SagaManager/SagaManager/IntegrationEvents/ISagaManagerIntegrationEventService.cs
  48. +0
    -17
      src/Services/SagaManager/SagaManager/IntegrationEvents/SagaManagerIntegrationEventService.cs
  49. +3
    -4
      src/Services/SagaManager/SagaManager/Program.cs
  50. +3
    -1
      src/Services/SagaManager/SagaManager/SagaManagerSettings.cs
  51. +8
    -8
      src/Services/SagaManager/SagaManager/Services/SagaManagerService.cs
  52. +3
    -1
      src/Services/SagaManager/SagaManager/appsettings.json
  53. +2
    -2
      src/Web/WebMVC/Views/Order/Index.cshtml

+ 0
- 1
docker-compose.override.yml View File

@ -11,7 +11,6 @@ services:
environment: environment:
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word - ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word
- EventBusConnection=rabbitmq - EventBusConnection=rabbitmq
- GracePeriod=15 #In minutes
basket.api: basket.api:
environment: environment:


+ 6
- 6
src/Services/Basket/Basket.API/Controllers/BasketController.cs View File

@ -53,16 +53,16 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers
[Route("checkout")] [Route("checkout")]
[HttpPost] [HttpPost]
public async Task<IActionResult> Checkout([FromBody]BasketCheckout value, [FromHeader(Name = "x-requestid")] string requestId)
public async Task<IActionResult> Checkout([FromBody]BasketCheckout basketCheckout, [FromHeader(Name = "x-requestid")] string requestId)
{ {
var userId = _identitySvc.GetUserIdentity(); var userId = _identitySvc.GetUserIdentity();
value.RequestId = (Guid.TryParse(requestId, out Guid guid) && guid != Guid.Empty) ?
guid : value.RequestId;
basketCheckout.RequestId = (Guid.TryParse(requestId, out Guid guid) && guid != Guid.Empty) ?
guid : basketCheckout.RequestId;
var basket = await _repository.GetBasketAsync(userId); var basket = await _repository.GetBasketAsync(userId);
var eventMessage = new UserCheckoutAcceptedIntegrationEvent(userId, value.City, value.Street,
value.State, value.Country, value.ZipCode, value.CardNumber, value.CardHolderName,
value.CardExpiration, value.CardSecurityNumber, value.CardTypeId, value.Buyer, value.RequestId, basket);
var eventMessage = new UserCheckoutAcceptedIntegrationEvent(userId, basketCheckout.City, basketCheckout.Street,
basketCheckout.State, basketCheckout.Country, basketCheckout.ZipCode, basketCheckout.CardNumber, basketCheckout.CardHolderName,
basketCheckout.CardExpiration, basketCheckout.CardSecurityNumber, basketCheckout.CardTypeId, basketCheckout.Buyer, basketCheckout.RequestId, basket);
// Once basket is checkout, sends an integration event to // Once basket is checkout, sends an integration event to
// ordering.api to convert basket to order and proceeds with // ordering.api to convert basket to order and proceeds with


src/Services/Catalog/Catalog.API/IntegrationCommands/CommandHandlers/ConfirmOrderStockCommandHandler.cs → src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs View File

@ -1,4 +1,4 @@
namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationCommands.CommandHandlers
namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.EventHandling
{ {
using BuildingBlocks.EventBus.Abstractions; using BuildingBlocks.EventBus.Abstractions;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -6,53 +6,41 @@
using Infrastructure; using Infrastructure;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using global::Catalog.API.Infrastructure.Exceptions;
using global::Catalog.API.IntegrationEvents; using global::Catalog.API.IntegrationEvents;
using Model;
using Commands;
using IntegrationEvents.Events; using IntegrationEvents.Events;
public class ConfirmOrderStockCommandHandler : IIntegrationEventHandler<ConfirmOrderStockCommand>
public class OrderStatusChangedToAwaitingValidationIntegrationEventHandler :
IIntegrationEventHandler<OrderStatusChangedToAwaitingValidationIntegrationEvent>
{ {
private readonly CatalogContext _catalogContext; private readonly CatalogContext _catalogContext;
private readonly ICatalogIntegrationEventService _catalogIntegrationEventService; private readonly ICatalogIntegrationEventService _catalogIntegrationEventService;
public ConfirmOrderStockCommandHandler(CatalogContext catalogContext,
public OrderStatusChangedToAwaitingValidationIntegrationEventHandler(CatalogContext catalogContext,
ICatalogIntegrationEventService catalogIntegrationEventService) ICatalogIntegrationEventService catalogIntegrationEventService)
{ {
_catalogContext = catalogContext; _catalogContext = catalogContext;
_catalogIntegrationEventService = catalogIntegrationEventService; _catalogIntegrationEventService = catalogIntegrationEventService;
} }
public async Task Handle(ConfirmOrderStockCommand command)
public async Task Handle(OrderStatusChangedToAwaitingValidationIntegrationEvent command)
{ {
var confirmedOrderStockItems = new List<ConfirmedOrderStockItem>(); var confirmedOrderStockItems = new List<ConfirmedOrderStockItem>();
foreach (var orderStockItem in command.OrderStockItems) foreach (var orderStockItem in command.OrderStockItems)
{ {
var catalogItem = _catalogContext.CatalogItems.Find(orderStockItem.ProductId); var catalogItem = _catalogContext.CatalogItems.Find(orderStockItem.ProductId);
CheckValidcatalogItemId(catalogItem);
var confirmedOrderStockItem = new ConfirmedOrderStockItem(catalogItem.Id,
catalogItem.AvailableStock >= orderStockItem.Units);
var hasStock = catalogItem.AvailableStock >= orderStockItem.Units;
var confirmedOrderStockItem = new ConfirmedOrderStockItem(catalogItem.Id, hasStock);
confirmedOrderStockItems.Add(confirmedOrderStockItem); confirmedOrderStockItems.Add(confirmedOrderStockItem);
} }
var confirmedIntegrationEvent = confirmedOrderStockItems.Any(c => !c.HasStock) var confirmedIntegrationEvent = confirmedOrderStockItems.Any(c => !c.HasStock)
? (IntegrationEvent) new OrderStockNotConfirmedIntegrationEvent(command.OrderId, confirmedOrderStockItems)
? (IntegrationEvent) new OrderStockRejectedIntegrationEvent(command.OrderId, confirmedOrderStockItems)
: new OrderStockConfirmedIntegrationEvent(command.OrderId); : new OrderStockConfirmedIntegrationEvent(command.OrderId);
await _catalogIntegrationEventService.SaveEventAndCatalogContextChangesAsync(confirmedIntegrationEvent); await _catalogIntegrationEventService.SaveEventAndCatalogContextChangesAsync(confirmedIntegrationEvent);
await _catalogIntegrationEventService.PublishThroughEventBusAsync(confirmedIntegrationEvent); await _catalogIntegrationEventService.PublishThroughEventBusAsync(confirmedIntegrationEvent);
} }
private void CheckValidcatalogItemId(CatalogItem catalogItem)
{
if (catalogItem is null)
{
throw new CatalogDomainException("Not able to process catalog event. Reason: no valid catalogItemId");
}
}
} }
} }

src/Services/Catalog/Catalog.API/IntegrationCommands/CommandHandlers/DecrementOrderStockCommandHandler.cs → src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs View File

@ -1,20 +1,21 @@
namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationCommands.CommandHandlers
namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.EventHandling
{ {
using BuildingBlocks.EventBus.Abstractions; using BuildingBlocks.EventBus.Abstractions;
using System.Threading.Tasks; using System.Threading.Tasks;
using Infrastructure; using Infrastructure;
using Commands;
using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events;
public class DecrementOrderStockCommandHandler : IIntegrationEventHandler<DecrementOrderStockCommand>
public class OrderStatusChangedToPaidIntegrationEventHandler :
IIntegrationEventHandler<OrderStatusChangedToPaidIntegrationEvent>
{ {
private readonly CatalogContext _catalogContext; private readonly CatalogContext _catalogContext;
public DecrementOrderStockCommandHandler(CatalogContext catalogContext)
public OrderStatusChangedToPaidIntegrationEventHandler(CatalogContext catalogContext)
{ {
_catalogContext = catalogContext; _catalogContext = catalogContext;
} }
public async Task Handle(DecrementOrderStockCommand command)
public async Task Handle(OrderStatusChangedToPaidIntegrationEvent command)
{ {
//we're not blocking stock/inventory //we're not blocking stock/inventory
foreach (var orderStockItem in command.OrderStockItems) foreach (var orderStockItem in command.OrderStockItems)

src/Services/Catalog/Catalog.API/IntegrationCommands/Commands/ConfirmOrderStockCommand.cs → src/Services/Catalog/Catalog.API/IntegrationEvents/Events/OrderStatusChangedToAwaitingValidationIntegrationEvent.cs View File

@ -1,14 +1,14 @@
namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationCommands.Commands
namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events
{ {
using BuildingBlocks.EventBus.Events; using BuildingBlocks.EventBus.Events;
using System.Collections.Generic; using System.Collections.Generic;
public class ConfirmOrderStockCommand : IntegrationEvent
public class OrderStatusChangedToAwaitingValidationIntegrationEvent : IntegrationEvent
{ {
public int OrderId { get; } public int OrderId { get; }
public IEnumerable<OrderStockItem> OrderStockItems { get; } public IEnumerable<OrderStockItem> OrderStockItems { get; }
public ConfirmOrderStockCommand(int orderId,
public OrderStatusChangedToAwaitingValidationIntegrationEvent(int orderId,
IEnumerable<OrderStockItem> orderStockItems) IEnumerable<OrderStockItem> orderStockItems)
{ {
OrderId = orderId; OrderId = orderId;

src/Services/Catalog/Catalog.API/IntegrationCommands/Commands/DecrementOrderStockCommand.cs → src/Services/Catalog/Catalog.API/IntegrationEvents/Events/OrderStatusChangedToPaidIntegrationEvent.cs View File

@ -1,14 +1,14 @@
namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationCommands.Commands
namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events
{ {
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
public class DecrementOrderStockCommand : IntegrationEvent
public class OrderStatusChangedToPaidIntegrationEvent : IntegrationEvent
{ {
public int OrderId { get; } public int OrderId { get; }
public IEnumerable<OrderStockItem> OrderStockItems { get; } public IEnumerable<OrderStockItem> OrderStockItems { get; }
public DecrementOrderStockCommand(int orderId,
public OrderStatusChangedToPaidIntegrationEvent(int orderId,
IEnumerable<OrderStockItem> orderStockItems) IEnumerable<OrderStockItem> orderStockItems)
{ {
OrderId = orderId; OrderId = orderId;

src/Services/Catalog/Catalog.API/IntegrationEvents/Events/OrderStockNotConfirmedIntegrationEvent.cs → src/Services/Catalog/Catalog.API/IntegrationEvents/Events/OrderStockRejectedIntegrationEvent.cs View File

@ -3,13 +3,13 @@
using BuildingBlocks.EventBus.Events; using BuildingBlocks.EventBus.Events;
using System.Collections.Generic; using System.Collections.Generic;
public class OrderStockNotConfirmedIntegrationEvent : IntegrationEvent
public class OrderStockRejectedIntegrationEvent : IntegrationEvent
{ {
public int OrderId { get; } public int OrderId { get; }
public List<ConfirmedOrderStockItem> OrderStockItems { get; } public List<ConfirmedOrderStockItem> OrderStockItems { get; }
public OrderStockNotConfirmedIntegrationEvent(int orderId,
public OrderStockRejectedIntegrationEvent(int orderId,
List<ConfirmedOrderStockItem> orderStockItems) List<ConfirmedOrderStockItem> orderStockItems)
{ {
OrderId = orderId; OrderId = orderId;

+ 11
- 11
src/Services/Catalog/Catalog.API/Startup.cs View File

@ -14,9 +14,8 @@
using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF; using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF;
using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services; using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services;
using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure; using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure;
using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationCommands.Commands;
using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents;
using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationCommands.CommandHandlers;
using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.EventHandling;
using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.HealthChecks; using Microsoft.Extensions.HealthChecks;
@ -27,7 +26,7 @@
using System.Data.Common; using System.Data.Common;
using System.Data.SqlClient; using System.Data.SqlClient;
using System.Reflection; using System.Reflection;
public class Startup public class Startup
{ {
public IConfigurationRoot Configuration { get; } public IConfigurationRoot Configuration { get; }
@ -190,19 +189,20 @@
services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>(); services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>();
services.AddSingleton<IEventBus, EventBusRabbitMQ>(); services.AddSingleton<IEventBus, EventBusRabbitMQ>();
services.AddTransient<IIntegrationEventHandler<ConfirmOrderStockCommand>,
ConfirmOrderStockCommandHandler>();
services.AddTransient<IIntegrationEventHandler<DecrementOrderStockCommand>,
DecrementOrderStockCommandHandler>();
services.AddTransient<IIntegrationEventHandler<OrderStatusChangedToAwaitingValidationIntegrationEvent>,
OrderStatusChangedToAwaitingValidationIntegrationEventHandler>();
services.AddTransient<IIntegrationEventHandler<OrderStatusChangedToPaidIntegrationEvent>,
OrderStatusChangedToPaidIntegrationEventHandler>();
} }
private void ConfigureEventBus(IApplicationBuilder app) private void ConfigureEventBus(IApplicationBuilder app)
{ {
var eventBus = app.ApplicationServices.GetRequiredService<IEventBus>(); var eventBus = app.ApplicationServices.GetRequiredService<IEventBus>();
eventBus.Subscribe<ConfirmOrderStockCommand, IIntegrationEventHandler<ConfirmOrderStockCommand>>();
eventBus.Subscribe<DecrementOrderStockCommand, IIntegrationEventHandler<DecrementOrderStockCommand>>();
eventBus.Subscribe<OrderStatusChangedToAwaitingValidationIntegrationEvent,
IIntegrationEventHandler<OrderStatusChangedToAwaitingValidationIntegrationEvent>>();
eventBus.Subscribe<OrderStatusChangedToPaidIntegrationEvent,
IIntegrationEventHandler<OrderStatusChangedToPaidIntegrationEvent>>();
} }
} }
} }

+ 1
- 5
src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/BuyerAndPaymentMethodVerified/UpdateOrderWhenBuyerAndPaymentMethodVerifiedDomainEventHandler.cs View File

@ -36,11 +36,7 @@ namespace Ordering.API.Application.DomainEventHandlers.BuyerAndPaymentMethodVeri
var orderStartedIntegrationEvent = new OrderStartedIntegrationEvent(buyerPaymentMethodVerifiedEvent.Buyer.IdentityGuid); var orderStartedIntegrationEvent = new OrderStartedIntegrationEvent(buyerPaymentMethodVerifiedEvent.Buyer.IdentityGuid);
await _orderingIntegrationEventService
.SaveEventAndOrderingContextChangesAsync(orderStartedIntegrationEvent);
await _orderingIntegrationEventService
.PublishThroughEventBusAsync(orderStartedIntegrationEvent);
await _orderingIntegrationEventService.PublishThroughEventBusAsync(orderStartedIntegrationEvent);
_logger.CreateLogger(nameof(UpdateOrderWhenBuyerAndPaymentMethodVerifiedDomainEventHandler)) _logger.CreateLogger(nameof(UpdateOrderWhenBuyerAndPaymentMethodVerifiedDomainEventHandler))
.LogTrace($"Order with Id: {buyerPaymentMethodVerifiedEvent.OrderId} has been successfully updated with a payment method id: { buyerPaymentMethodVerifiedEvent.Payment.Id }"); .LogTrace($"Order with Id: {buyerPaymentMethodVerifiedEvent.OrderId} has been successfully updated with a payment method id: { buyerPaymentMethodVerifiedEvent.Payment.Id }");


+ 4
- 5
src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderGracePeriodConfirmed/OrderStatusChangedToAwaitingValidationDomainEventHandler.cs View File

@ -6,9 +6,9 @@
using Domain.Events; using Domain.Events;
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Ordering.API.Application.IntegrationCommands.Commands;
using Ordering.API.Application.IntegrationEvents; using Ordering.API.Application.IntegrationEvents;
using System.Linq; using System.Linq;
using Ordering.API.Application.IntegrationEvents.Events;
public class OrderStatusChangedToAwaitingValidationDomainEventHandler public class OrderStatusChangedToAwaitingValidationDomainEventHandler
: IAsyncNotificationHandler<OrderStatusChangedToAwaitingValidationDomainEvent> : IAsyncNotificationHandler<OrderStatusChangedToAwaitingValidationDomainEvent>
@ -35,10 +35,9 @@
var orderStockList = orderStatusChangedToAwaitingValidationDomainEvent.OrderItems var orderStockList = orderStatusChangedToAwaitingValidationDomainEvent.OrderItems
.Select(orderItem => new OrderStockItem(orderItem.ProductId, orderItem.GetUnits())); .Select(orderItem => new OrderStockItem(orderItem.ProductId, orderItem.GetUnits()));
var confirmOrderStockCommand = new ConfirmOrderStockCommand(orderStatusChangedToAwaitingValidationDomainEvent.OrderId,
orderStockList);
await _orderingIntegrationEventService.SaveEventAndOrderingContextChangesAsync(confirmOrderStockCommand);
await _orderingIntegrationEventService.PublishThroughEventBusAsync(confirmOrderStockCommand);
var orderStatusChangedToAwaitingValidationIntegrationEvent = new OrderStatusChangedToAwaitingValidationIntegrationEvent(
orderStatusChangedToAwaitingValidationDomainEvent.OrderId, orderStockList);
await _orderingIntegrationEventService.PublishThroughEventBusAsync(orderStatusChangedToAwaitingValidationIntegrationEvent);
} }
} }
} }

+ 3
- 4
src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderPaid/OrderStatusChangedToPaidDomainEventHandler.cs View File

@ -6,9 +6,9 @@
using Domain.Events; using Domain.Events;
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Ordering.API.Application.IntegrationCommands.Commands;
using Ordering.API.Application.IntegrationEvents; using Ordering.API.Application.IntegrationEvents;
using System.Linq; using System.Linq;
using Ordering.API.Application.IntegrationEvents.Events;
public class OrderStatusChangedToPaidDomainEventHandler public class OrderStatusChangedToPaidDomainEventHandler
: IAsyncNotificationHandler<OrderStatusChangedToPaidDomainEvent> : IAsyncNotificationHandler<OrderStatusChangedToPaidDomainEvent>
@ -35,10 +35,9 @@
var orderStockList = orderStatusChangedToPaidDomainEvent.OrderItems var orderStockList = orderStatusChangedToPaidDomainEvent.OrderItems
.Select(orderItem => new OrderStockItem(orderItem.ProductId, orderItem.GetUnits())); .Select(orderItem => new OrderStockItem(orderItem.ProductId, orderItem.GetUnits()));
var decrementOrderStockCommand = new DecrementOrderStockCommand(orderStatusChangedToPaidDomainEvent.OrderId,
var orderStatusChangedToPaidIntegrationEvent = new OrderStatusChangedToPaidIntegrationEvent(orderStatusChangedToPaidDomainEvent.OrderId,
orderStockList); orderStockList);
await _orderingIntegrationEventService.SaveEventAndOrderingContextChangesAsync(decrementOrderStockCommand);
await _orderingIntegrationEventService.PublishThroughEventBusAsync(decrementOrderStockCommand);
await _orderingIntegrationEventService.PublishThroughEventBusAsync(orderStatusChangedToPaidIntegrationEvent);
} }
} }
} }

+ 3
- 4
src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStockConfirmed/OrderStatusChangedToStockConfirmedDomainEventHandler.cs View File

@ -6,8 +6,8 @@
using Domain.Events; using Domain.Events;
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Ordering.API.Application.IntegrationCommands.Commands;
using Ordering.API.Application.IntegrationEvents; using Ordering.API.Application.IntegrationEvents;
using Ordering.API.Application.IntegrationEvents.Events;
public class OrderStatusChangedToStockConfirmedDomainEventHandler public class OrderStatusChangedToStockConfirmedDomainEventHandler
: IAsyncNotificationHandler<OrderStatusChangedToStockConfirmedDomainEvent> : IAsyncNotificationHandler<OrderStatusChangedToStockConfirmedDomainEvent>
@ -31,9 +31,8 @@
.LogTrace($"Order with Id: {orderStatusChangedToStockConfirmedDomainEvent.OrderId} has been successfully updated with " + .LogTrace($"Order with Id: {orderStatusChangedToStockConfirmedDomainEvent.OrderId} has been successfully updated with " +
$"a status order id: {OrderStatus.StockConfirmed.Id}"); $"a status order id: {OrderStatus.StockConfirmed.Id}");
var payOrderCommand = new PayOrderCommand(orderStatusChangedToStockConfirmedDomainEvent.OrderId);
await _orderingIntegrationEventService.SaveEventAndOrderingContextChangesAsync(payOrderCommand);
await _orderingIntegrationEventService.PublishThroughEventBusAsync(payOrderCommand);
var orderStatusChangedToStockConfirmedIntegrationEvent = new OrderStatusChangedToStockConfirmedIntegrationEvent(orderStatusChangedToStockConfirmedDomainEvent.OrderId);
await _orderingIntegrationEventService.PublishThroughEventBusAsync(orderStatusChangedToStockConfirmedIntegrationEvent);
} }
} }
} }

+ 0
- 12
src/Services/Ordering/Ordering.API/Application/IntegrationCommands/Commands/ConfirmGracePeriodCommand.cs View File

@ -1,12 +0,0 @@
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
namespace Ordering.API.Application.IntegrationCommands.Commands
{
public class ConfirmGracePeriodCommand : IntegrationEvent
{
public int OrderId { get; }
public ConfirmGracePeriodCommand(int orderId) =>
OrderId = orderId;
}
}

+ 0
- 14
src/Services/Ordering/Ordering.API/Application/IntegrationCommands/Commands/PayOrderCommand.cs View File

@ -1,14 +0,0 @@
namespace Ordering.API.Application.IntegrationCommands.Commands
{
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
public class PayOrderCommand : IntegrationEvent
{
public int OrderId { get; }
public PayOrderCommand(int orderId)
{
OrderId = orderId;
}
}
}

+ 1
- 1
src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentFailedIntegrationEventHandler.cs View File

@ -17,7 +17,7 @@
public async Task Handle(OrderPaymentFailedIntegrationEvent @event) public async Task Handle(OrderPaymentFailedIntegrationEvent @event)
{ {
var orderToUpdate = await _orderRepository.GetWithDependenciesAsync(@event.OrderId);
var orderToUpdate = await _orderRepository.GetAsync(@event.OrderId);
orderToUpdate.SetCancelledStatus(); orderToUpdate.SetCancelledStatus();


+ 1
- 1
src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentSuccededIntegrationEventHandler.cs View File

@ -17,7 +17,7 @@
public async Task Handle(OrderPaymentSuccededIntegrationEvent @event) public async Task Handle(OrderPaymentSuccededIntegrationEvent @event)
{ {
var orderToUpdate = await _orderRepository.GetWithDependenciesAsync(@event.OrderId);
var orderToUpdate = await _orderRepository.GetAsync(@event.OrderId);
orderToUpdate.SetPaidStatus(); orderToUpdate.SetPaidStatus();


+ 1
- 1
src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockConfirmedIntegrationEventHandler.cs View File

@ -17,7 +17,7 @@
public async Task Handle(OrderStockConfirmedIntegrationEvent @event) public async Task Handle(OrderStockConfirmedIntegrationEvent @event)
{ {
var orderToUpdate = await _orderRepository.GetWithDependenciesAsync(@event.OrderId);
var orderToUpdate = await _orderRepository.GetAsync(@event.OrderId);
orderToUpdate.SetStockConfirmedStatus(); orderToUpdate.SetStockConfirmedStatus();


+ 0
- 33
src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockNotConfirmedIntegrationEventHandler.cs View File

@ -1,33 +0,0 @@
using System.Linq;
using Ordering.API.Application.IntegrationCommands.Commands;
namespace Ordering.API.Application.IntegrationEvents.EventHandling
{
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using System.Threading.Tasks;
using Events;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
public class OrderStockNotConfirmedIntegrationEventHandler : IIntegrationEventHandler<OrderStockNotConfirmedIntegrationEvent>
{
private readonly IOrderRepository _orderRepository;
public OrderStockNotConfirmedIntegrationEventHandler(IOrderRepository orderRepository)
{
_orderRepository = orderRepository;
}
public async Task Handle(OrderStockNotConfirmedIntegrationEvent @event)
{
var orderToUpdate = await _orderRepository.GetWithDependenciesAsync(@event.OrderId);
var orderStockNotConfirmedItems = @event.OrderStockItems
.FindAll(c => !c.HasStock)
.Select(c => c.ProductId);
orderToUpdate.SetStockConfirmedStatus(orderStockNotConfirmedItems);
await _orderRepository.UnitOfWork.SaveEntitiesAsync();
}
}
}

+ 31
- 0
src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockRejectedIntegrationEventHandler.cs View File

@ -0,0 +1,31 @@
namespace Ordering.API.Application.IntegrationEvents.EventHandling
{
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using System.Threading.Tasks;
using Events;
using System.Linq;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
public class OrderStockRejectedIntegrationEventHandler : IIntegrationEventHandler<OrderStockRejectedIntegrationEvent>
{
private readonly IOrderRepository _orderRepository;
public OrderStockRejectedIntegrationEventHandler(IOrderRepository orderRepository)
{
_orderRepository = orderRepository;
}
public async Task Handle(OrderStockRejectedIntegrationEvent @event)
{
var orderToUpdate = await _orderRepository.GetAsync(@event.OrderId);
var orderStockRejectedItems = @event.OrderStockItems
.FindAll(c => !c.HasStock)
.Select(c => c.ProductId);
orderToUpdate.SetCancelledStatusWhenStockIsRejected(orderStockRejectedItems);
await _orderRepository.UnitOfWork.SaveEntitiesAsync();
}
}
}

+ 12
- 0
src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/GracePeriodConfirmedIntegrationEvent.cs View File

@ -0,0 +1,12 @@
namespace Ordering.API.Application.IntegrationEvents.Events
{
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
public class GracePeriodConfirmedIntegrationEvent : IntegrationEvent
{
public int OrderId { get; }
public GracePeriodConfirmedIntegrationEvent(int orderId) =>
OrderId = orderId;
}
}

+ 4
- 4
src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderPaymentFailedIntegrationEvent .cs View File

@ -1,11 +1,11 @@
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
namespace Ordering.API.Application.IntegrationEvents.Events
namespace Ordering.API.Application.IntegrationEvents.Events
{ {
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
public class OrderPaymentFailedIntegrationEvent : IntegrationEvent public class OrderPaymentFailedIntegrationEvent : IntegrationEvent
{ {
public int OrderId { get; } public int OrderId { get; }
public OrderPaymentFailedIntegrationEvent(int orderId) => OrderId = orderId; public OrderPaymentFailedIntegrationEvent(int orderId) => OrderId = orderId;
} }
}
}

+ 4
- 4
src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderPaymentSuccededIntegrationEvent.cs View File

@ -1,11 +1,11 @@
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
namespace Ordering.API.Application.IntegrationEvents.Events
namespace Ordering.API.Application.IntegrationEvents.Events
{ {
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
public class OrderPaymentSuccededIntegrationEvent : IntegrationEvent public class OrderPaymentSuccededIntegrationEvent : IntegrationEvent
{ {
public int OrderId { get; } public int OrderId { get; }
public OrderPaymentSuccededIntegrationEvent(int orderId) => OrderId = orderId; public OrderPaymentSuccededIntegrationEvent(int orderId) => OrderId = orderId;
} }
}
}

src/Services/Ordering/Ordering.API/Application/IntegrationCommands/Commands/ConfirmOrderStockCommand.cs → src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStatusChangedToAwaitingValidationIntegrationEvent.cs View File

@ -1,14 +1,14 @@
namespace Ordering.API.Application.IntegrationCommands.Commands
namespace Ordering.API.Application.IntegrationEvents.Events
{ {
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
public class ConfirmOrderStockCommand : IntegrationEvent
public class OrderStatusChangedToAwaitingValidationIntegrationEvent : IntegrationEvent
{ {
public int OrderId { get; } public int OrderId { get; }
public IEnumerable<OrderStockItem> OrderStockItems { get; } public IEnumerable<OrderStockItem> OrderStockItems { get; }
public ConfirmOrderStockCommand(int orderId,
public OrderStatusChangedToAwaitingValidationIntegrationEvent(int orderId,
IEnumerable<OrderStockItem> orderStockItems) IEnumerable<OrderStockItem> orderStockItems)
{ {
OrderId = orderId; OrderId = orderId;

src/Services/Ordering/Ordering.API/Application/IntegrationCommands/Commands/DecrementOrderStockCommand.cs → src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStatusChangedToPaidIntegrationEvent.cs View File

@ -1,14 +1,14 @@
namespace Ordering.API.Application.IntegrationCommands.Commands
namespace Ordering.API.Application.IntegrationEvents.Events
{ {
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
public class DecrementOrderStockCommand : IntegrationEvent
public class OrderStatusChangedToPaidIntegrationEvent : IntegrationEvent
{ {
public int OrderId { get; } public int OrderId { get; }
public IEnumerable<OrderStockItem> OrderStockItems { get; } public IEnumerable<OrderStockItem> OrderStockItems { get; }
public DecrementOrderStockCommand(int orderId,
public OrderStatusChangedToPaidIntegrationEvent(int orderId,
IEnumerable<OrderStockItem> orderStockItems) IEnumerable<OrderStockItem> orderStockItems)
{ {
OrderId = orderId; OrderId = orderId;

+ 12
- 0
src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStatusChangedToStockConfirmedIntegrationEvent.cs View File

@ -0,0 +1,12 @@
namespace Ordering.API.Application.IntegrationEvents.Events
{
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
public class OrderStatusChangedToStockConfirmedIntegrationEvent : IntegrationEvent
{
public int OrderId { get; }
public OrderStatusChangedToStockConfirmedIntegrationEvent(int orderId)
=> OrderId = orderId;
}
}

src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStockNotConfirmedIntegrationEvent.cs → src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStockRejectedIntegrationEvent.cs View File

@ -1,16 +1,15 @@
using System.Collections.Generic;
namespace Ordering.API.Application.IntegrationEvents.Events
namespace Ordering.API.Application.IntegrationEvents.Events
{ {
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
using System.Collections.Generic;
public class OrderStockNotConfirmedIntegrationEvent : IntegrationEvent
public class OrderStockRejectedIntegrationEvent : IntegrationEvent
{ {
public int OrderId { get; } public int OrderId { get; }
public List<ConfirmedOrderStockItem> OrderStockItems { get; } public List<ConfirmedOrderStockItem> OrderStockItems { get; }
public OrderStockNotConfirmedIntegrationEvent(int orderId,
public OrderStockRejectedIntegrationEvent(int orderId,
List<ConfirmedOrderStockItem> orderStockItems) List<ConfirmedOrderStockItem> orderStockItems)
{ {
OrderId = orderId; OrderId = orderId;

+ 0
- 1
src/Services/Ordering/Ordering.API/Application/IntegrationEvents/IOrderingIntegrationEventService.cs View File

@ -5,7 +5,6 @@ namespace Ordering.API.Application.IntegrationEvents
{ {
public interface IOrderingIntegrationEventService public interface IOrderingIntegrationEventService
{ {
Task SaveEventAndOrderingContextChangesAsync(IntegrationEvent evt);
Task PublishThroughEventBusAsync(IntegrationEvent evt); Task PublishThroughEventBusAsync(IntegrationEvent evt);
} }
} }

+ 2
- 1
src/Services/Ordering/Ordering.API/Application/IntegrationEvents/OrderingIntegrationEventService.cs View File

@ -30,11 +30,12 @@ namespace Ordering.API.Application.IntegrationEvents
public async Task PublishThroughEventBusAsync(IntegrationEvent evt) public async Task PublishThroughEventBusAsync(IntegrationEvent evt)
{ {
await SaveEventAndOrderingContextChangesAsync(evt);
_eventBus.Publish(evt); _eventBus.Publish(evt);
await _eventLogService.MarkEventAsPublishedAsync(evt); await _eventLogService.MarkEventAsPublishedAsync(evt);
} }
public async Task SaveEventAndOrderingContextChangesAsync(IntegrationEvent evt)
private async Task SaveEventAndOrderingContextChangesAsync(IntegrationEvent evt)
{ {
//Use of an EF Core resiliency strategy when using multiple DbContexts within an explicit BeginTransaction(): //Use of an EF Core resiliency strategy when using multiple DbContexts within an explicit BeginTransaction():
//See: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency //See: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency


+ 4
- 9
src/Services/Ordering/Ordering.API/Application/Sagas/OrderProcessSaga.cs View File

@ -5,8 +5,7 @@ using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.Order
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure; using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure;
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Idempotency; using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Idempotency;
using Ordering.API.Application.Commands; using Ordering.API.Application.Commands;
using Ordering.API.Application.IntegrationCommands.Commands;
using Ordering.API.Application.IntegrationEvents;
using Ordering.API.Application.IntegrationEvents.Events;
using Ordering.Domain.Exceptions; using Ordering.Domain.Exceptions;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -21,7 +20,7 @@ namespace Ordering.API.Application.Sagas
/// with the validations. /// with the validations.
/// </summary> /// </summary>
public class OrderProcessSaga : OrderSaga, public class OrderProcessSaga : OrderSaga,
IIntegrationEventHandler<ConfirmGracePeriodCommand>,
IIntegrationEventHandler<GracePeriodConfirmedIntegrationEvent>,
IAsyncRequestHandler<CancelOrderCommand, bool>, IAsyncRequestHandler<CancelOrderCommand, bool>,
IAsyncRequestHandler<ShipOrderCommand, bool> IAsyncRequestHandler<ShipOrderCommand, bool>
{ {
@ -43,9 +42,9 @@ namespace Ordering.API.Application.Sagas
/// period has completed. /// period has completed.
/// </param> /// </param>
/// <returns></returns> /// <returns></returns>
public async Task Handle(ConfirmGracePeriodCommand command)
public async Task Handle(GracePeriodConfirmedIntegrationEvent @event)
{ {
var orderSaga = FindSagaById(command.OrderId);
var orderSaga = FindSagaById(@event.OrderId);
CheckValidSagaId(orderSaga); CheckValidSagaId(orderSaga);
orderSaga.SetAwaitingValidationStatus(); orderSaga.SetAwaitingValidationStatus();
@ -96,8 +95,6 @@ namespace Ordering.API.Application.Sagas
} }
} }
#region CommandHandlerIdentifiers
public class CancelOrderCommandIdentifiedHandler : IdentifierCommandHandler<CancelOrderCommand, bool> public class CancelOrderCommandIdentifiedHandler : IdentifierCommandHandler<CancelOrderCommand, bool>
{ {
public CancelOrderCommandIdentifiedHandler(IMediator mediator, IRequestManager requestManager) : base(mediator, requestManager) public CancelOrderCommandIdentifiedHandler(IMediator mediator, IRequestManager requestManager) : base(mediator, requestManager)
@ -121,7 +118,5 @@ namespace Ordering.API.Application.Sagas
return true; // Ignore duplicate requests for processing order. return true; // Ignore duplicate requests for processing order.
} }
} }
#endregion
} }
} }

+ 2
- 3
src/Services/Ordering/Ordering.API/Application/Sagas/OrderSaga.cs View File

@ -17,12 +17,11 @@ namespace Ordering.API.Application.Sagas
public override Order FindSagaById(int id) public override Order FindSagaById(int id)
{ {
var order = _orderingContext.Orders
return _orderingContext.Orders
.Include(c => c.OrderStatus) .Include(c => c.OrderStatus)
.Include(c => c.OrderItems) .Include(c => c.OrderItems)
.Include(c => c.Address)
.Single(c => c.Id == id); .Single(c => c.Id == id);
return order;
} }
public override async Task<bool> SaveChangesAsync() public override async Task<bool> SaveChangesAsync()


+ 0
- 1
src/Services/Ordering/Ordering.API/Ordering.API.csproj View File

@ -79,7 +79,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="Application\IntegrationCommands\CommandHandlers\" />
<Folder Include="Infrastructure\IntegrationEventMigrations\" /> <Folder Include="Infrastructure\IntegrationEventMigrations\" />
</ItemGroup> </ItemGroup>


+ 6
- 14
src/Services/Ordering/Ordering.API/Startup.cs View File

@ -3,11 +3,9 @@
using AspNetCore.Http; using AspNetCore.Http;
using Autofac; using Autofac;
using Autofac.Extensions.DependencyInjection; using Autofac.Extensions.DependencyInjection;
using global::Ordering.API.Application.IntegrationCommands.Commands;
using global::Ordering.API.Application.IntegrationEvents; using global::Ordering.API.Application.IntegrationEvents;
using global::Ordering.API.Application.IntegrationEvents.EventHandling; using global::Ordering.API.Application.IntegrationEvents.EventHandling;
using global::Ordering.API.Application.IntegrationEvents.Events; using global::Ordering.API.Application.IntegrationEvents.Events;
using global::Ordering.API.Application.Sagas;
using global::Ordering.API.Infrastructure.Middlewares; using global::Ordering.API.Infrastructure.Middlewares;
using Infrastructure; using Infrastructure;
using Infrastructure.Auth; using Infrastructure.Auth;
@ -169,24 +167,18 @@
{ {
services.AddSingleton<IEventBus, EventBusRabbitMQ>(); services.AddSingleton<IEventBus, EventBusRabbitMQ>();
services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>(); services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>();
services.AddTransient<IIntegrationEventHandler<ConfirmGracePeriodCommand>, OrderProcessSaga>();
services.AddTransient<UserCheckoutAcceptedIntegrationEventHandler>();
services.AddTransient<OrderStockConfirmedIntegrationEventHandler>();
services.AddTransient<OrderStockNotConfirmedIntegrationEventHandler>();
services.AddTransient<OrderPaymentFailedIntegrationEventHandler>();
services.AddTransient<OrderPaymentSuccededIntegrationEventHandler>();
} }
private void ConfigureEventBus(IApplicationBuilder app) private void ConfigureEventBus(IApplicationBuilder app)
{ {
var eventBus = app.ApplicationServices.GetRequiredService<IEventBus>(); var eventBus = app.ApplicationServices.GetRequiredService<IEventBus>();
eventBus.Subscribe<ConfirmGracePeriodCommand, IIntegrationEventHandler<ConfirmGracePeriodCommand>>();
eventBus.Subscribe<UserCheckoutAcceptedIntegrationEvent, UserCheckoutAcceptedIntegrationEventHandler>();
eventBus.Subscribe<OrderStockConfirmedIntegrationEvent, OrderStockConfirmedIntegrationEventHandler>();
eventBus.Subscribe<OrderStockNotConfirmedIntegrationEvent, OrderStockNotConfirmedIntegrationEventHandler>();
eventBus.Subscribe<OrderPaymentFailedIntegrationEvent, OrderPaymentFailedIntegrationEventHandler>();
eventBus.Subscribe<OrderPaymentSuccededIntegrationEvent, OrderPaymentSuccededIntegrationEventHandler>();
eventBus.Subscribe<UserCheckoutAcceptedIntegrationEvent, IIntegrationEventHandler<UserCheckoutAcceptedIntegrationEvent>>();
eventBus.Subscribe<GracePeriodConfirmedIntegrationEvent, IIntegrationEventHandler<GracePeriodConfirmedIntegrationEvent>>();
eventBus.Subscribe<OrderStockConfirmedIntegrationEvent, IIntegrationEventHandler<OrderStockConfirmedIntegrationEvent>>();
eventBus.Subscribe<OrderStockRejectedIntegrationEvent, IIntegrationEventHandler<OrderStockRejectedIntegrationEvent>>();
eventBus.Subscribe<OrderPaymentFailedIntegrationEvent, IIntegrationEventHandler<OrderPaymentFailedIntegrationEvent>>();
eventBus.Subscribe<OrderPaymentSuccededIntegrationEvent, IIntegrationEventHandler<OrderPaymentSuccededIntegrationEvent>>();
} }
protected virtual void ConfigureAuth(IApplicationBuilder app) protected virtual void ConfigureAuth(IApplicationBuilder app)


+ 2
- 0
src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Address.cs View File

@ -17,6 +17,8 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
public String ZipCode { get; private set; } public String ZipCode { get; private set; }
private Address() { }
public Address(string street, string city, string state, string country, string zipcode) public Address(string street, string city, string state, string country, string zipcode)
{ {
Street = street; Street = street;


+ 0
- 2
src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/IOrderRepository.cs View File

@ -13,7 +13,5 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
void Update(Order order); void Update(Order order);
Task<Order> GetAsync(int orderId); Task<Order> GetAsync(int orderId);
Task<Order> GetWithDependenciesAsync(int orderId);
} }
} }

+ 32
- 47
src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs View File

@ -94,14 +94,12 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
_buyerId = id; _buyerId = id;
} }
#region Status Changes
public void SetAwaitingValidationStatus() public void SetAwaitingValidationStatus()
{ {
if (_orderStatusId != OrderStatus.Submited.Id &&
_orderStatusId != OrderStatus.Cancelled.Id)
if (_orderStatusId == OrderStatus.Cancelled.Id ||
_orderStatusId != OrderStatus.Submited.Id)
{ {
StatusChangeException();
StatusChangeException(OrderStatus.AwaitingValidation);
} }
AddDomainEvent(new OrderStatusChangedToAwaitingValidationDomainEvent(Id, _orderItems)); AddDomainEvent(new OrderStatusChangedToAwaitingValidationDomainEvent(Id, _orderItems));
@ -109,38 +107,24 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
_orderStatusId = OrderStatus.AwaitingValidation.Id; _orderStatusId = OrderStatus.AwaitingValidation.Id;
} }
public void SetStockConfirmedStatus(IEnumerable<int> orderStockNotConfirmedItems = null)
public void SetStockConfirmedStatus()
{ {
if (_orderStatusId != OrderStatus.AwaitingValidation.Id) if (_orderStatusId != OrderStatus.AwaitingValidation.Id)
{ {
StatusChangeException();
}
if (orderStockNotConfirmedItems is null)
{
AddDomainEvent(new OrderStatusChangedToStockConfirmedDomainEvent(Id));
_orderStatusId = OrderStatus.StockConfirmed.Id;
_description = "All the items were confirmed with available stock.";
StatusChangeException(OrderStatus.StockConfirmed);
} }
else
{
_orderStatusId = OrderStatus.Cancelled.Id;
var itemsStockNotConfirmedProductNames = OrderItems
.Where(c => orderStockNotConfirmedItems.Contains(c.ProductId))
.Select(c => c.GetOrderItemProductName());
AddDomainEvent(new OrderStatusChangedToStockConfirmedDomainEvent(Id));
var itemsStockNotConfirmedDescription = string.Join(", ", itemsStockNotConfirmedProductNames);
_description = $"The product items don't have stock: ({itemsStockNotConfirmedDescription}).";
}
_orderStatusId = OrderStatus.StockConfirmed.Id;
_description = "All the items were confirmed with available stock.";
} }
public void SetPaidStatus() public void SetPaidStatus()
{ {
if (_orderStatusId != OrderStatus.StockConfirmed.Id) if (_orderStatusId != OrderStatus.StockConfirmed.Id)
{ {
StatusChangeException();
StatusChangeException(OrderStatus.Paid);
} }
AddDomainEvent(new OrderStatusChangedToPaidDomainEvent(Id, OrderItems)); AddDomainEvent(new OrderStatusChangedToPaidDomainEvent(Id, OrderItems));
@ -153,40 +137,41 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
{ {
if (_orderStatusId != OrderStatus.Paid.Id) if (_orderStatusId != OrderStatus.Paid.Id)
{ {
StatusChangeException();
StatusChangeException(OrderStatus.Shipped);
} }
_orderStatusId = OrderStatus.Shipped.Id; _orderStatusId = OrderStatus.Shipped.Id;
_description = "";
_description = "The order was shipped.";
} }
public void SetCancelledStatus() public void SetCancelledStatus()
{ {
if (_orderStatusId == OrderStatus.Submited.Id)
{
_description = "The order was cancelled before the grace period was confirmed.";
}
else if (_orderStatusId == OrderStatus.AwaitingValidation.Id)
{
_description = "The order was cancelled before to check the order stock items.";
}
else if (_orderStatusId == OrderStatus.StockConfirmed.Id)
if (_orderStatusId == OrderStatus.Paid.Id ||
_orderStatusId == OrderStatus.Shipped.Id)
{ {
_description = "The order was cancelled before to pay the order.";
StatusChangeException(OrderStatus.Cancelled);
} }
else if (_orderStatusId == OrderStatus.Paid.Id)
{
_description = "The order was cancelled before to ship the order.";
}
else if(_orderStatusId == OrderStatus.Shipped.Id)
_orderStatusId = OrderStatus.Cancelled.Id;
_description = $"The order was cancelled.";
}
public void SetCancelledStatusWhenStockIsRejected(IEnumerable<int> orderStockRejectedItems)
{
if (_orderStatusId != OrderStatus.AwaitingValidation.Id)
{ {
throw new OrderingDomainException("Not possible to change order status. Reason: cannot cancel order it is already shipped.");
StatusChangeException(OrderStatus.Cancelled);
} }
_orderStatusId = OrderStatus.Cancelled.Id; _orderStatusId = OrderStatus.Cancelled.Id;
}
#endregion
var itemsStockRejectedProductNames = OrderItems
.Where(c => orderStockRejectedItems.Contains(c.ProductId))
.Select(c => c.GetOrderItemProductName());
var itemsStockRejectedDescription = string.Join(", ", itemsStockRejectedProductNames);
_description = $"The product items don't have stock: ({itemsStockRejectedDescription}).";
}
private void AddOrderStartedDomainEvent(string userId, int cardTypeId, string cardNumber, private void AddOrderStartedDomainEvent(string userId, int cardTypeId, string cardNumber,
string cardSecurityNumber, string cardHolderName, DateTime cardExpiration) string cardSecurityNumber, string cardHolderName, DateTime cardExpiration)
@ -198,9 +183,9 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
this.AddDomainEvent(orderStartedDomainEvent); this.AddDomainEvent(orderStartedDomainEvent);
} }
private void StatusChangeException()
private void StatusChangeException(OrderStatus orderStatusToChange)
{ {
throw new OrderingDomainException("Not able to process order event. Reason: no valid order status change");
throw new OrderingDomainException($"Not possible to change order status from {OrderStatus.Name} to {orderStatusToChange.Name}.");
} }
} }
} }


+ 11
- 8
src/Services/Ordering/Ordering.Infrastructure/Repositories/OrderRepository.cs View File

@ -33,15 +33,18 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Repositor
public async Task<Order> GetAsync(int orderId) public async Task<Order> GetAsync(int orderId)
{ {
return await _context.Orders.FindAsync(orderId);
}
var order = await _context.Orders.FindAsync(orderId);
if (order != null)
{
await _context.Entry(order)
.Collection(i => i.OrderItems).LoadAsync();
await _context.Entry(order)
.Reference(i => i.OrderStatus).LoadAsync();
await _context.Entry(order)
.Reference(i => i.Address).LoadAsync();
}
public async Task<Order> GetWithDependenciesAsync(int orderId)
{
return await _context.Orders
.Include(c => c.OrderStatus)
.Include(c => c.OrderItems)
.SingleAsync(c => c.Id == orderId);
return order;
} }
public void Update(Order order) public void Update(Order order)


+ 0
- 27
src/Services/Payment/Payment.API/IntegrationCommands/CommandHandlers/PayOrderCommandHandler.cs View File

@ -1,27 +0,0 @@
namespace Payment.API.IntegrationCommands.CommandHandlers
{
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Payment.API.IntegrationCommands.Commands;
using System.Threading.Tasks;
using Payment.API.IntegrationEvents;
using Payment.API.IntegrationEvents.Events;
public class PayOrderCommandHandler : IIntegrationEventHandler<PayOrderCommand>
{
private readonly IPaymentIntegrationEventService _paymentIntegrationEventService;
public PayOrderCommandHandler(IPaymentIntegrationEventService paymentIntegrationEventService)
=> _paymentIntegrationEventService = paymentIntegrationEventService;
public async Task Handle(PayOrderCommand @event)
{
//PAYMENT SUCCESSED
var orderPaymentSuccededIntegrationEvent = new OrderPaymentSuccededIntegrationEvent(@event.OrderId);
_paymentIntegrationEventService.PublishThroughEventBus(orderPaymentSuccededIntegrationEvent);
//PAYMENT FAILED
//var orderPaymentFailedIntegrationEvent = new OrderPaymentFailedIntegrationEvent(@event.OrderId);
//_paymentIntegrationEventService.PublishThroughEventBus(orderPaymentFailedIntegrationEvent);
}
}
}

+ 0
- 11
src/Services/Payment/Payment.API/IntegrationCommands/Commands/PayOrderCommand.cs View File

@ -1,11 +0,0 @@
namespace Payment.API.IntegrationCommands.Commands
{
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
public class PayOrderCommand : IntegrationEvent
{
public int OrderId { get; }
public PayOrderCommand(int orderId) => OrderId = orderId;
}
}

+ 37
- 0
src/Services/Payment/Payment.API/IntegrationEvents/EventHandling/OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs View File

@ -0,0 +1,37 @@
namespace Payment.API.IntegrationEvents.EventHandling
{
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using System.Threading.Tasks;
using Payment.API.IntegrationEvents.Events;
using Microsoft.Extensions.Options;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
public class OrderStatusChangedToStockConfirmedIntegrationEventHandler :
IIntegrationEventHandler<OrderStatusChangedToStockConfirmedIntegrationEvent>
{
private readonly IEventBus _eventBus;
private readonly PaymentSettings _settings;
public OrderStatusChangedToStockConfirmedIntegrationEventHandler(IEventBus eventBus,
IOptionsSnapshot<PaymentSettings> settings)
{
_eventBus = eventBus;
_settings = settings.Value;
}
public async Task Handle(OrderStatusChangedToStockConfirmedIntegrationEvent @event)
{
IntegrationEvent orderPaymentIntegrationEvent;
if(_settings.SuccessPayment)
{
orderPaymentIntegrationEvent = new OrderPaymentSuccededIntegrationEvent(@event.OrderId);
}
else
{
orderPaymentIntegrationEvent = new OrderPaymentFailedIntegrationEvent(@event.OrderId);
}
_eventBus.Publish(orderPaymentIntegrationEvent);
}
}
}

+ 12
- 0
src/Services/Payment/Payment.API/IntegrationEvents/Events/OrderStatusChangedToStockConfirmedIntegrationEvent.cs View File

@ -0,0 +1,12 @@
namespace Payment.API.IntegrationEvents.Events
{
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
public class OrderStatusChangedToStockConfirmedIntegrationEvent : IntegrationEvent
{
public int OrderId { get; }
public OrderStatusChangedToStockConfirmedIntegrationEvent(int orderId)
=> OrderId = orderId;
}
}

+ 0
- 9
src/Services/Payment/Payment.API/IntegrationEvents/IPaymentIntegrationEventService.cs View File

@ -1,9 +0,0 @@
namespace Payment.API.IntegrationEvents
{
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
public interface IPaymentIntegrationEventService
{
void PublishThroughEventBus(IntegrationEvent evt);
}
}

+ 0
- 21
src/Services/Payment/Payment.API/IntegrationEvents/PaymentIntegrationEventService.cs View File

@ -1,21 +0,0 @@
namespace Payment.API.IntegrationEvents
{
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
using System;
public class PaymentIntegrationEventService : IPaymentIntegrationEventService
{
private readonly IEventBus _eventBus;
public PaymentIntegrationEventService(IEventBus eventBus)
{
_eventBus = eventBus ?? throw new ArgumentNullException(nameof(eventBus));
}
public void PublishThroughEventBus(IntegrationEvent evt)
{
_eventBus.Publish(evt); ;
}
}
}

+ 8
- 0
src/Services/Payment/Payment.API/PaymentSettings.cs View File

@ -0,0 +1,8 @@
namespace Payment.API
{
public class PaymentSettings
{
public bool SuccessPayment { get; set; }
public string EventBusConnection { get; set; }
}
}

+ 8
- 8
src/Services/Payment/Payment.API/Startup.cs View File

@ -7,12 +7,11 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System; using System;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Payment.API.IntegrationCommands.Commands;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ; using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ;
using RabbitMQ.Client; using RabbitMQ.Client;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus;
using Payment.API.IntegrationEvents;
using Payment.API.IntegrationCommands.CommandHandlers;
using Payment.API.IntegrationEvents.Events;
using Payment.API.IntegrationEvents.EventHandling;
namespace Payment.API namespace Payment.API
{ {
@ -35,8 +34,7 @@ namespace Payment.API
{ {
// Add framework services. // Add framework services.
services.AddMvc(); services.AddMvc();
services.AddTransient<IPaymentIntegrationEventService, PaymentIntegrationEventService>();
services.Configure<PaymentSettings>(Configuration);
services.AddSingleton<IRabbitMQPersistentConnection>(sp => services.AddSingleton<IRabbitMQPersistentConnection>(sp =>
{ {
var logger = sp.GetRequiredService<ILogger<DefaultRabbitMQPersistentConnection>>(); var logger = sp.GetRequiredService<ILogger<DefaultRabbitMQPersistentConnection>>();
@ -88,13 +86,15 @@ namespace Payment.API
services.AddSingleton<IEventBus, EventBusRabbitMQ>(); services.AddSingleton<IEventBus, EventBusRabbitMQ>();
services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>(); services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>();
services.AddTransient<IIntegrationEventHandler<PayOrderCommand>, PayOrderCommandHandler>();
services.AddTransient<IIntegrationEventHandler<OrderStatusChangedToStockConfirmedIntegrationEvent>,
OrderStatusChangedToStockConfirmedIntegrationEventHandler>();
} }
private void ConfigureEventBus(IApplicationBuilder app) private void ConfigureEventBus(IApplicationBuilder app)
{ {
var eventBus = app.ApplicationServices.GetRequiredService<IEventBus>(); var eventBus = app.ApplicationServices.GetRequiredService<IEventBus>();
eventBus.Subscribe<PayOrderCommand, IIntegrationEventHandler<PayOrderCommand>>();
eventBus.Subscribe<OrderStatusChangedToStockConfirmedIntegrationEvent,
IIntegrationEventHandler<OrderStatusChangedToStockConfirmedIntegrationEvent>>();
} }
} }
}
}

+ 2
- 1
src/Services/Payment/Payment.API/appsettings.json View File

@ -4,5 +4,6 @@
"LogLevel": { "LogLevel": {
"Default": "Warning" "Default": "Warning"
} }
}
},
"SuccessPayment": "true"
} }

src/Services/SagaManager/SagaManager/IntegrationEvents/Events/ConfirmGracePeriodCommand.cs → src/Services/SagaManager/SagaManager/IntegrationEvents/Events/GracePeriodConfirmedIntegrationEvent.cs View File

@ -2,10 +2,10 @@
{ {
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
public class ConfirmGracePeriodCommand : IntegrationEvent
public class GracePeriodConfirmedIntegrationEvent : IntegrationEvent
{ {
public int OrderId { get;} public int OrderId { get;}
public ConfirmGracePeriodCommand(int orderId) => OrderId = orderId;
public GracePeriodConfirmedIntegrationEvent(int orderId) => OrderId = orderId;
} }
} }

+ 0
- 9
src/Services/SagaManager/SagaManager/IntegrationEvents/ISagaManagerIntegrationEventService.cs View File

@ -1,9 +0,0 @@
namespace SagaManager.IntegrationEvents
{
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
public interface ISagaManagerIntegrationEventService
{
void PublishThroughEventBus(IntegrationEvent evt);
}
}

+ 0
- 17
src/Services/SagaManager/SagaManager/IntegrationEvents/SagaManagerIntegrationEventService.cs View File

@ -1,17 +0,0 @@
namespace SagaManager.IntegrationEvents
{
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
using System;
public class SagaManagerIntegrationEventService : ISagaManagerIntegrationEventService
{
private readonly IEventBus _eventBus;
public SagaManagerIntegrationEventService(IEventBus eventBus)
=> _eventBus = eventBus ?? throw new ArgumentNullException(nameof(eventBus));
public void PublishThroughEventBus(IntegrationEvent evt) => _eventBus.Publish(evt);
}
}

+ 3
- 4
src/Services/SagaManager/SagaManager/Program.cs View File

@ -14,7 +14,6 @@
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using RabbitMQ.Client; using RabbitMQ.Client;
using Services; using Services;
using IntegrationEvents;
public class Program public class Program
{ {
@ -34,11 +33,13 @@
var sagaManagerService = serviceProvider var sagaManagerService = serviceProvider
.GetRequiredService<ISagaManagerService>(); .GetRequiredService<ISagaManagerService>();
var checkUpdateTime = serviceProvider
.GetRequiredService<IOptions<SagaManagerSettings>>().Value.CheckUpdateTime;
while (true) while (true)
{ {
sagaManagerService.CheckConfirmedGracePeriodOrders(); sagaManagerService.CheckConfirmedGracePeriodOrders();
await Task.Delay(90000);
await Task.Delay(checkUpdateTime);
} }
} }
@ -58,8 +59,6 @@
.AddOptions() .AddOptions()
.Configure<SagaManagerSettings>(Configuration) .Configure<SagaManagerSettings>(Configuration)
.AddSingleton<ISagaManagerService, SagaManagerService>() .AddSingleton<ISagaManagerService, SagaManagerService>()
.AddSingleton<ISagaManagerIntegrationEventService, SagaManagerIntegrationEventService>()
.AddSingleton<IRabbitMQPersistentConnection>(sp => .AddSingleton<IRabbitMQPersistentConnection>(sp =>
{ {
var settings = sp.GetRequiredService<IOptions<SagaManagerSettings>>().Value; var settings = sp.GetRequiredService<IOptions<SagaManagerSettings>>().Value;


+ 3
- 1
src/Services/SagaManager/SagaManager/SagaManagerSettings.cs View File

@ -6,6 +6,8 @@
public string EventBusConnection { get; set; } public string EventBusConnection { get; set; }
public int GracePeriod { get; set; }
public int GracePeriodTime { get; set; }
public int CheckUpdateTime { get; set; }
} }
} }

+ 8
- 8
src/Services/SagaManager/SagaManager/Services/SagaManagerService.cs View File

@ -5,21 +5,21 @@
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Dapper; using Dapper;
using IntegrationEvents;
using IntegrationEvents.Events; using IntegrationEvents.Events;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
public class SagaManagerService : ISagaManagerService public class SagaManagerService : ISagaManagerService
{ {
private readonly SagaManagerSettings _settings; private readonly SagaManagerSettings _settings;
private readonly ISagaManagerIntegrationEventService _sagaManagerIntegrationEventService;
private readonly IEventBus _eventBus;
private readonly ILogger<SagaManagerService> _logger; private readonly ILogger<SagaManagerService> _logger;
public SagaManagerService(IOptions<SagaManagerSettings> settings, public SagaManagerService(IOptions<SagaManagerSettings> settings,
ISagaManagerIntegrationEventService sagaManagerIntegrationEventService,
IEventBus eventBus,
ILogger<SagaManagerService> logger) ILogger<SagaManagerService> logger)
{ {
_settings = settings.Value; _settings = settings.Value;
_sagaManagerIntegrationEventService = sagaManagerIntegrationEventService;
_eventBus = eventBus;
_logger = logger; _logger = logger;
} }
@ -29,8 +29,8 @@
foreach (var orderId in orderIds) foreach (var orderId in orderIds)
{ {
var confirmGracePeriodEvent = new ConfirmGracePeriodCommand(orderId);
_sagaManagerIntegrationEventService.PublishThroughEventBus(confirmGracePeriodEvent);
var confirmGracePeriodEvent = new GracePeriodConfirmedIntegrationEvent(orderId);
_eventBus.Publish(confirmGracePeriodEvent);
} }
} }
@ -45,9 +45,9 @@
conn.Open(); conn.Open();
orderIds = conn.Query<int>( orderIds = conn.Query<int>(
@"SELECT Id FROM [Microsoft.eShopOnContainers.Services.OrderingDb].[ordering].[orders] @"SELECT Id FROM [Microsoft.eShopOnContainers.Services.OrderingDb].[ordering].[orders]
WHERE DATEDIFF(hour, [OrderDate], GETDATE()) >= @GracePeriod
WHERE DATEDIFF(hour, [OrderDate], GETDATE()) >= @GracePeriodTime
AND [OrderStatusId] = 1", AND [OrderStatusId] = 1",
new { GracePeriod = _settings.GracePeriod });
new { GracePeriodTime = _settings.GracePeriodTime });
} }
catch (SqlException exception) catch (SqlException exception)
{ {


+ 3
- 1
src/Services/SagaManager/SagaManager/appsettings.json View File

@ -7,5 +7,7 @@
"Microsoft": "Information" "Microsoft": "Information"
} }
}, },
"ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;"
"ConnectionString": "Server=tcp:127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;",
"GracePeriodTime": "15",
"CheckUpdateTime": "30000"
} }

+ 2
- 2
src/Web/WebMVC/Views/Order/Index.cshtml View File

@ -31,9 +31,9 @@
<a class="esh-orders-link" asp-controller="Order" asp-action="Detail" asp-route-orderId="@item.OrderNumber">Detail</a> <a class="esh-orders-link" asp-controller="Order" asp-action="Detail" asp-route-orderId="@item.OrderNumber">Detail</a>
</section> </section>
<section class="esh-orders-item col-xs-1"> <section class="esh-orders-item col-xs-1">
@if ((item.Status.ToLower() != "shipped") && (item.Status.ToLower() != "cancelled"))
@if (item.Status.ToLower() == "submited")
{ {
<a class="esh-orders-link" asp-controller="Order" asp-action="Cancel" asp-route-orderId="@item.OrderNumber">Cancel</a>
<a class="esh-orders-link" asp-controller="Order" asp-action="cancel" asp-route-orderId="@item.OrderNumber">Cancel</a>
} }
</section> </section>
</article> </article>


Loading…
Cancel
Save