Continue implementing OrderStockConfirmed events
This commit is contained in:
parent
23bb012074
commit
10e2427253
@ -1,16 +1,14 @@
|
|||||||
using System.Collections.Generic;
|
namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.EventHandling
|
||||||
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
|
|
||||||
{
|
{
|
||||||
using BuildingBlocks.EventBus.Abstractions;
|
using BuildingBlocks.EventBus.Abstractions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BuildingBlocks.EventBus.Events;
|
using BuildingBlocks.EventBus.Events;
|
||||||
using Infrastructure;
|
using Infrastructure;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using global::Catalog.API.Infrastructure.Exceptions;
|
||||||
|
using global::Catalog.API.IntegrationEvents;
|
||||||
|
using Model;
|
||||||
using Events;
|
using Events;
|
||||||
|
|
||||||
public class ConfirmOrderStockIntegrationEventHandler : IIntegrationEventHandler<ConfirmOrderStockIntegrationEvent>
|
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
|
//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)
|
? (IntegrationEvent) new OrderStockNotConfirmedIntegrationEvent(@event.OrderId, confirmedOrderStockItems)
|
||||||
: new OrderStockConfirmedIntegrationEvent(@event.OrderId);
|
: 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
|
// 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)
|
private void CheckValidcatalogItemId(CatalogItem catalogItem)
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,18 +1,48 @@
|
|||||||
namespace Ordering.API.Application.IntegrationEvents.EventHandling
|
namespace Ordering.API.Application.IntegrationEvents.EventHandling
|
||||||
{
|
{
|
||||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
|
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
|
||||||
using System;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Events;
|
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>
|
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)
|
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: 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);
|
||||||
|
|
||||||
throw new NotImplementedException();
|
order.SetOrderStockConfirmed(true);
|
||||||
|
|
||||||
|
//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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,15 +4,45 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Events;
|
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>
|
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)
|
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: 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);
|
||||||
|
|
||||||
throw new NotImplementedException();
|
order.SetOrderStockConfirmed(false);
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -8,13 +8,13 @@ namespace Ordering.API.Application.IntegrationEvents.Events
|
|||||||
{
|
{
|
||||||
public int OrderId { get; }
|
public int OrderId { get; }
|
||||||
|
|
||||||
public IEnumerable<ConfirmedOrderStockItem> OrderStockItem { get; }
|
public List<ConfirmedOrderStockItem> OrderStockItems { get; }
|
||||||
|
|
||||||
public OrderStockNotConfirmedIntegrationEvent(int orderId,
|
public OrderStockNotConfirmedIntegrationEvent(int orderId,
|
||||||
IEnumerable<ConfirmedOrderStockItem> orderStockItem)
|
List<ConfirmedOrderStockItem> orderStockItems)
|
||||||
{
|
{
|
||||||
OrderId = orderId;
|
OrderId = orderId;
|
||||||
OrderStockItem = orderStockItem;
|
OrderStockItems = orderStockItems;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,9 +78,9 @@ namespace Ordering.API.Application.Sagas
|
|||||||
/// period has completed.
|
/// period has completed.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <returns></returns>
|
/// <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);
|
CheckValidSagaId(orderSaga);
|
||||||
|
|
||||||
if (orderSaga.OrderStatus != OrderStatus.Cancelled)
|
if (orderSaga.OrderStatus != OrderStatus.Cancelled)
|
||||||
@ -88,14 +88,14 @@ namespace Ordering.API.Application.Sagas
|
|||||||
orderSaga.SetOrderStatusId(OrderStatus.AwaitingValidation.Id);
|
orderSaga.SetOrderStatusId(OrderStatus.AwaitingValidation.Id);
|
||||||
await SaveChangesAsync();
|
await SaveChangesAsync();
|
||||||
|
|
||||||
var orderStockList = orderSaga.OrderItems
|
var orderStockList = orderSaga.OrderItems
|
||||||
.Select(orderItem => new OrderStockItem(orderItem.ProductId, orderItem.GetUnits()));
|
.Select(orderItem => new OrderStockItem(orderItem.ProductId, orderItem.GetUnits()));
|
||||||
|
|
||||||
//Create Integration Event to be published through the Event Bus
|
//Create Integration Event to be published through the Event Bus
|
||||||
var confirmOrderStockEvent = new ConfirmOrderStockCommandMsg(orderSaga.Id, orderStockList);
|
var confirmOrderStockEvent = new ConfirmOrderStockCommandMsg(orderSaga.Id, orderStockList);
|
||||||
|
|
||||||
// Publish through the Event Bus and mark the saved event as published
|
// Publish through the Event Bus and mark the saved event as published
|
||||||
await _orderingIntegrationEventService.PublishThroughEventBusAsync(confirmOrderStockEvent);
|
await _orderingIntegrationEventService.PublishThroughEventBusAsync(confirmOrderStockEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +79,6 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="Application\DomainEventHandlers\OrderStockMethodVerified\" />
|
|
||||||
<Folder Include="Application\IntegrationCommands\CommandHandlers\" />
|
<Folder Include="Application\IntegrationCommands\CommandHandlers\" />
|
||||||
<Folder Include="Infrastructure\IntegrationEventMigrations\" />
|
<Folder Include="Infrastructure\IntegrationEventMigrations\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -127,9 +127,9 @@
|
|||||||
|
|
||||||
services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>();
|
services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>();
|
||||||
services.AddSingleton<IEventBus, EventBusRabbitMQ>();
|
services.AddSingleton<IEventBus, EventBusRabbitMQ>();
|
||||||
|
|
||||||
services.AddTransient<UserCheckoutAcceptedIntegrationEventHandler>();
|
services.AddTransient<UserCheckoutAcceptedIntegrationEventHandler>();
|
||||||
services.AddTransient<IIntegrationEventHandler<ConfirmGracePeriodCommandMsg>, OrderProcessSaga>();
|
services.AddTransient<IIntegrationEventHandler<ConfirmGracePeriodCommandMsg>, OrderProcessSaga>();
|
||||||
services.AddTransient<IIntegrationEventHandler<SubmitOrderCommandMsg>, OrderProcessSaga>();
|
|
||||||
services.AddTransient<OrderStockConfirmedIntegrationEventHandler>();
|
services.AddTransient<OrderStockConfirmedIntegrationEventHandler>();
|
||||||
services.AddTransient<OrderStockNotConfirmedIntegrationEventHandler>();
|
services.AddTransient<OrderStockNotConfirmedIntegrationEventHandler>();
|
||||||
services.AddOptions();
|
services.AddOptions();
|
||||||
|
@ -99,6 +99,20 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
|
|||||||
_orderStatusId = id;
|
_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,
|
private void AddOrderStartedDomainEvent(int cardTypeId, string cardNumber,
|
||||||
string cardSecurityNumber, string cardHolderName, DateTime cardExpiration)
|
string cardSecurityNumber, string cardHolderName, DateTime cardExpiration)
|
||||||
{
|
{
|
||||||
|
@ -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…
x
Reference in New Issue
Block a user