Browse Source

Continue implementing OrderStockConfirmed events

pull/809/head
Christian Arenas 7 years ago
parent
commit
9a6ad2cc85
11 changed files with 189 additions and 29 deletions
  1. +12
    -11
      src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/ConfirmOrderStockIntegrationEventHandler.cs
  2. +50
    -0
      src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStockConfirmation/UpdateOrderWhenOrderStockMethodVerifiedDomainEventHandler.cs
  3. +14
    -0
      src/Services/Ordering/Ordering.API/Application/IntegrationCommands/Commands/PayOrderCommandMsg.cs
  4. +33
    -3
      src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockConfirmedIntegrationEventHandler.cs
  5. +32
    -2
      src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockNotConfirmedIntegrationEventHandler.cs
  6. +3
    -3
      src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStockNotConfirmedIntegrationEvent.cs
  7. +8
    -8
      src/Services/Ordering/Ordering.API/Application/Sagas/OrderProcessSaga.cs
  8. +0
    -1
      src/Services/Ordering/Ordering.API/Ordering.API.csproj
  9. +1
    -1
      src/Services/Ordering/Ordering.API/Startup.cs
  10. +14
    -0
      src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs
  11. +22
    -0
      src/Services/Ordering/Ordering.Domain/Events/OrderStockMethodVerifiedDomainEvent.cs

+ 12
- 11
src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/ConfirmOrderStockIntegrationEventHandler.cs View File

@ -1,16 +1,14 @@
using System.Collections.Generic;
using System.Linq;
using Catalog.API.Infrastructure.Exceptions;
using Catalog.API.IntegrationEvents;
using Microsoft.eShopOnContainers.Services.Catalog.API.Model;
namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.EventHandling
namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.EventHandling
{
using BuildingBlocks.EventBus.Abstractions;
using System.Threading.Tasks;
using BuildingBlocks.EventBus.Events;
using Infrastructure;
using System.Collections.Generic;
using System.Linq;
using global::Catalog.API.Infrastructure.Exceptions;
using global::Catalog.API.IntegrationEvents;
using Model;
using Events;
public class ConfirmOrderStockIntegrationEventHandler : IIntegrationEventHandler<ConfirmOrderStockIntegrationEvent>
@ -41,12 +39,15 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Eve
}
//Create Integration Event to be published through the Event Bus
var integrationEvent = confirmedOrderStockItems.Any(c => !c.Confirmed)
var confirmedIntegrationEvent = confirmedOrderStockItems.Any(c => !c.Confirmed)
? (IntegrationEvent) new OrderStockNotConfirmedIntegrationEvent(@event.OrderId, confirmedOrderStockItems)
: new OrderStockConfirmedIntegrationEvent(@event.OrderId);
// Achieving atomicity between original Catalog database operation and the IntegrationEventLog thanks to a local transaction
await _catalogIntegrationEventService.SaveEventAndCatalogContextChangesAsync(confirmedIntegrationEvent);
// Publish through the Event Bus and mark the saved event as published
await _catalogIntegrationEventService.PublishThroughEventBusAsync(integrationEvent);
await _catalogIntegrationEventService.PublishThroughEventBusAsync(confirmedIntegrationEvent);
}
private void CheckValidcatalogItemId(CatalogItem catalogItem)


+ 50
- 0
src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStockConfirmation/UpdateOrderWhenOrderStockMethodVerifiedDomainEventHandler.cs View File

@ -0,0 +1,50 @@
namespace Ordering.API.Application.DomainEventHandlers.OrderStartedEvent
{
using MediatR;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
using Microsoft.Extensions.Logging;
using Domain.Events;
using System;
using System.Threading.Tasks;
public class UpdateOrderWhenOrderStockMethodVerifiedDomainEventHandler
: IAsyncNotificationHandler<OrderStockMethodVerifiedDomainEvent>
{
private readonly IOrderRepository _orderRepository;
private readonly ILoggerFactory _logger;
public UpdateOrderWhenOrderStockMethodVerifiedDomainEventHandler(
IOrderRepository orderRepository, ILoggerFactory logger)
{
_orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
// Domain Logic comment:
// When the Order Stock items method have been validate and confirmed,
// then we can update the original Order with the new order status
public async Task Handle(OrderStockMethodVerifiedDomainEvent orderStockMethodVerifiedDomainEvent)
{
var orderToUpdate = await _orderRepository.GetAsync(orderStockMethodVerifiedDomainEvent.OrderId);
orderToUpdate.SetOrderStatusId(orderStockMethodVerifiedDomainEvent.OrderStatus.Id);
_orderRepository.Update(orderToUpdate);
await _orderRepository.UnitOfWork
.SaveEntitiesAsync();
_logger.CreateLogger(nameof(UpdateOrderWhenOrderStockMethodVerifiedDomainEventHandler))
.LogTrace($"Order with Id: {orderStockMethodVerifiedDomainEvent.OrderId} has been successfully updated with " +
$"a status order id: { orderStockMethodVerifiedDomainEvent.OrderStatus.Id }");
//var payOrderCommandMsg = new PayOrderCommandMsg(order.Id);
//// Achieving atomicity between original Catalog database operation and the IntegrationEventLog thanks to a local transaction
//await _orderingIntegrationEventService.SaveEventAndOrderingContextChangesAsync(payOrderCommandMsg);
//// Publish through the Event Bus and mark the saved event as published
//await _orderingIntegrationEventService.PublishThroughEventBusAsync(payOrderCommandMsg);
}
}
}

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

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

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

@ -1,18 +1,48 @@
namespace Ordering.API.Application.IntegrationEvents.EventHandling
{
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using System;
using System.Threading.Tasks;
using Events;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
using Ordering.API.Application.IntegrationCommands.Commands;
using Ordering.Domain.Exceptions;
public class OrderStockConfirmedIntegrationEventHandler : IIntegrationEventHandler<OrderStockConfirmedIntegrationEvent>
{
private readonly IOrderingIntegrationEventService _orderingIntegrationEventService;
private readonly IOrderRepository _orderRepository;
public OrderStockConfirmedIntegrationEventHandler(IOrderRepository orderRepository,
IOrderingIntegrationEventService orderingIntegrationEventService)
{
_orderRepository = orderRepository;
_orderingIntegrationEventService = orderingIntegrationEventService;
}
public async Task Handle(OrderStockConfirmedIntegrationEvent @event)
{
//TODO: 1) Updates the state to "StockValidated" and any meaningful OrderContextDescription message saying that all the items were confirmed with available stock, etc
//TODO: 2) Sends a Command-message (PayOrderCommand msg/bus) to the Payment svc. from Ordering micro (thru Command Bus, as a message, NOT http)
var order = await _orderRepository.GetAsync(@event.OrderId);
CheckValidSagaId(order);
order.SetOrderStockConfirmed(true);
throw new NotImplementedException();
//Create Integration Event to be published through the Event Bus
var payOrderCommandMsg = new PayOrderCommandMsg(order.Id);
// Achieving atomicity between original Catalog database operation and the IntegrationEventLog thanks to a local transaction
await _orderingIntegrationEventService.SaveEventAndOrderingContextChangesAsync(payOrderCommandMsg);
// Publish through the Event Bus and mark the saved event as published
await _orderingIntegrationEventService.PublishThroughEventBusAsync(payOrderCommandMsg);
}
private void CheckValidSagaId(Order orderSaga)
{
if (orderSaga is null)
{
throw new OrderingDomainException("Not able to process order saga event. Reason: no valid orderId");
}
}
}
}

+ 32
- 2
src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockNotConfirmedIntegrationEventHandler.cs View File

@ -4,15 +4,45 @@
using System;
using System.Threading.Tasks;
using Events;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
using Ordering.API.Application.Sagas;
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure;
using Ordering.Domain.Exceptions;
public class OrderStockNotConfirmedIntegrationEventHandler : IIntegrationEventHandler<OrderStockNotConfirmedIntegrationEvent>
{
private readonly IOrderingIntegrationEventService _orderingIntegrationEventService;
private readonly IOrderRepository _orderRepository;
public OrderStockNotConfirmedIntegrationEventHandler(IOrderRepository orderRepository,
IOrderingIntegrationEventService orderingIntegrationEventService)
{
_orderRepository = orderRepository;
_orderingIntegrationEventService = orderingIntegrationEventService;
}
public async Task Handle(OrderStockNotConfirmedIntegrationEvent @event)
{
//TODO: must update the order state to cancelled and the CurrentOrderStateContextDescription with the reasons of no-stock confirm
//TODO: for this/that articles which is info coming in that integration event. --> ORDER PROCESS
var order = await _orderRepository.GetAsync(@event.OrderId);
CheckValidSagaId(order);
order.SetOrderStockConfirmed(false);
throw new NotImplementedException();
var orderStockNotConfirmedItems = @event.OrderStockItems.FindAll(c => !c.Confirmed);
foreach (var orderStockNotConfirmedItem in orderStockNotConfirmedItems)
{
//TODO: Add messages
}
}
private void CheckValidSagaId(Order orderSaga)
{
if (orderSaga is null)
{
throw new OrderingDomainException("Not able to process order saga event. Reason: no valid orderId");
}
}
}
}

+ 3
- 3
src/Services/Ordering/Ordering.API/Application/IntegrationEvents/Events/OrderStockNotConfirmedIntegrationEvent.cs View File

@ -8,13 +8,13 @@ namespace Ordering.API.Application.IntegrationEvents.Events
{
public int OrderId { get; }
public IEnumerable<ConfirmedOrderStockItem> OrderStockItem { get; }
public List<ConfirmedOrderStockItem> OrderStockItems { get; }
public OrderStockNotConfirmedIntegrationEvent(int orderId,
IEnumerable<ConfirmedOrderStockItem> orderStockItem)
List<ConfirmedOrderStockItem> orderStockItems)
{
OrderId = orderId;
OrderStockItem = orderStockItem;
OrderStockItems = orderStockItems;
}
}


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

@ -78,9 +78,9 @@ namespace Ordering.API.Application.Sagas
/// period has completed.
/// </param>
/// <returns></returns>
public async Task Handle(ConfirmGracePeriodCommandMsg command)
public async Task Handle(ConfirmGracePeriodCommandMsg @event)
{
var orderSaga = FindSagaById(command.OrderId);
var orderSaga = FindSagaById(@event.OrderId);
CheckValidSagaId(orderSaga);
if (orderSaga.OrderStatus != OrderStatus.Cancelled)
@ -88,14 +88,14 @@ namespace Ordering.API.Application.Sagas
orderSaga.SetOrderStatusId(OrderStatus.AwaitingValidation.Id);
await SaveChangesAsync();
var orderStockList = orderSaga.OrderItems
.Select(orderItem => new OrderStockItem(orderItem.ProductId, orderItem.GetUnits()));
var orderStockList = orderSaga.OrderItems
.Select(orderItem => new OrderStockItem(orderItem.ProductId, orderItem.GetUnits()));
//Create Integration Event to be published through the Event Bus
var confirmOrderStockEvent = new ConfirmOrderStockCommandMsg(orderSaga.Id, orderStockList);
//Create Integration Event to be published through the Event Bus
var confirmOrderStockEvent = new ConfirmOrderStockCommandMsg(orderSaga.Id, orderStockList);
// Publish through the Event Bus and mark the saved event as published
await _orderingIntegrationEventService.PublishThroughEventBusAsync(confirmOrderStockEvent);
// Publish through the Event Bus and mark the saved event as published
await _orderingIntegrationEventService.PublishThroughEventBusAsync(confirmOrderStockEvent);
}
}


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

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


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

@ -127,9 +127,9 @@
services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>();
services.AddSingleton<IEventBus, EventBusRabbitMQ>();
services.AddTransient<UserCheckoutAcceptedIntegrationEventHandler>();
services.AddTransient<IIntegrationEventHandler<ConfirmGracePeriodCommandMsg>, OrderProcessSaga>();
services.AddTransient<IIntegrationEventHandler<SubmitOrderCommandMsg>, OrderProcessSaga>();
services.AddTransient<OrderStockConfirmedIntegrationEventHandler>();
services.AddTransient<OrderStockNotConfirmedIntegrationEventHandler>();
services.AddOptions();


+ 14
- 0
src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs View File

@ -99,6 +99,20 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
_orderStatusId = id;
}
public void SetOrderStockConfirmed(bool confirmed)
{
if(confirmed)
{
OrderStatus = OrderStatus.StockValidated;
AddDomainEvent(new OrderStockMethodVerifiedDomainEvent(Id, OrderStatus.StockValidated));
}
else
{
OrderStatus = OrderStatus.Cancelled;
AddDomainEvent(new OrderStockMethodVerifiedDomainEvent(Id, OrderStatus.Cancelled));
}
}
private void AddOrderStartedDomainEvent(int cardTypeId, string cardNumber,
string cardSecurityNumber, string cardHolderName, DateTime cardExpiration)
{


+ 22
- 0
src/Services/Ordering/Ordering.Domain/Events/OrderStockMethodVerifiedDomainEvent.cs View File

@ -0,0 +1,22 @@
namespace Ordering.Domain.Events
{
using MediatR;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
/// <summary>
/// Event used when the order stock items are verified
/// </summary>
public class OrderStockMethodVerifiedDomainEvent
: IAsyncNotification
{
public int OrderId { get; }
public OrderStatus OrderStatus { get; }
public OrderStockMethodVerifiedDomainEvent(int orderId,
OrderStatus orderStatus)
{
OrderId = orderId;
OrderStatus = orderStatus;
}
}
}

Loading…
Cancel
Save