Browse Source

Send commands for modifying state in IntegrationEventHandlers

pull/813/head
Ramón Tomás 6 years ago
parent
commit
adafb9abf4
13 changed files with 347 additions and 46 deletions
  1. +21
    -0
      src/Services/Ordering/Ordering.API/Application/Commands/SetAwaitingValidationOrderStatusCommand.cs
  2. +52
    -0
      src/Services/Ordering/Ordering.API/Application/Commands/SetAwaitingValidationOrderStatusCommandHandler.cs
  3. +21
    -0
      src/Services/Ordering/Ordering.API/Application/Commands/SetPaidOrderStatusCommand.cs
  4. +55
    -0
      src/Services/Ordering/Ordering.API/Application/Commands/SetPaidOrderStatusCommandHandler.cs
  5. +21
    -0
      src/Services/Ordering/Ordering.API/Application/Commands/SetStockConfirmedOrderStatusCommand.cs
  6. +55
    -0
      src/Services/Ordering/Ordering.API/Application/Commands/SetStockConfirmedOrderStatusCommandHandler.cs
  7. +25
    -0
      src/Services/Ordering/Ordering.API/Application/Commands/SetStockRejectedOrderStatusCommand.cs
  8. +56
    -0
      src/Services/Ordering/Ordering.API/Application/Commands/SetStockRejectedOrderStatusCommandHandler.cs
  9. +8
    -7
      src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/GracePeriodConfirmedIntegrationEventHandler.cs
  10. +8
    -8
      src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentFailedIntegrationEventHandler.cs
  11. +8
    -11
      src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentSuccededIntegrationEventHandler.cs
  12. +8
    -11
      src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockConfirmedIntegrationEventHandler.cs
  13. +9
    -9
      src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockRejectedIntegrationEventHandler.cs

+ 21
- 0
src/Services/Ordering/Ordering.API/Application/Commands/SetAwaitingValidationOrderStatusCommand.cs View File

@ -0,0 +1,21 @@
using MediatR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Threading.Tasks;
namespace Ordering.API.Application.Commands
{
public class SetAwaitingValidationOrderStatusCommand : IRequest<bool>
{
[DataMember]
public int OrderNumber { get; private set; }
public SetAwaitingValidationOrderStatusCommand(int orderNumber)
{
OrderNumber = orderNumber;
}
}
}

+ 52
- 0
src/Services/Ordering/Ordering.API/Application/Commands/SetAwaitingValidationOrderStatusCommandHandler.cs View File

@ -0,0 +1,52 @@
using MediatR;
using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Idempotency;
using System.Threading;
using System.Threading.Tasks;
namespace Ordering.API.Application.Commands
{
// Regular CommandHandler
public class SetAwaitingValidationOrderStatusCommandHandler : IRequestHandler<SetAwaitingValidationOrderStatusCommand, bool>
{
private readonly IOrderRepository _orderRepository;
public SetAwaitingValidationOrderStatusCommandHandler(IOrderRepository orderRepository)
{
_orderRepository = orderRepository;
}
/// <summary>
/// Handler which processes the command when
/// graceperiod has finished
/// </summary>
/// <param name="command"></param>
/// <returns></returns>
public async Task<bool> Handle(SetAwaitingValidationOrderStatusCommand command, CancellationToken cancellationToken)
{
var orderToUpdate = await _orderRepository.GetAsync(command.OrderNumber);
if(orderToUpdate == null)
{
return false;
}
orderToUpdate.SetAwaitingValidationStatus();
return await _orderRepository.UnitOfWork.SaveEntitiesAsync();
}
}
// Use for Idempotency in Command process
public class SetAwaitingValidationIdentifiedOrderStatusCommandHandler : IdentifiedCommandHandler<SetAwaitingValidationOrderStatusCommand, bool>
{
public SetAwaitingValidationIdentifiedOrderStatusCommandHandler(IMediator mediator, IRequestManager requestManager) : base(mediator, requestManager)
{
}
protected override bool CreateResultForDuplicateRequest()
{
return true; // Ignore duplicate requests for processing order.
}
}
}

+ 21
- 0
src/Services/Ordering/Ordering.API/Application/Commands/SetPaidOrderStatusCommand.cs View File

@ -0,0 +1,21 @@
using MediatR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Threading.Tasks;
namespace Ordering.API.Application.Commands
{
public class SetPaidOrderStatusCommand : IRequest<bool>
{
[DataMember]
public int OrderNumber { get; private set; }
public SetPaidOrderStatusCommand(int orderNumber)
{
OrderNumber = orderNumber;
}
}
}

+ 55
- 0
src/Services/Ordering/Ordering.API/Application/Commands/SetPaidOrderStatusCommandHandler.cs View File

@ -0,0 +1,55 @@
using MediatR;
using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Idempotency;
using System.Threading;
using System.Threading.Tasks;
namespace Ordering.API.Application.Commands
{
// Regular CommandHandler
public class SetPaidOrderStatusCommandHandler : IRequestHandler<SetPaidOrderStatusCommand, bool>
{
private readonly IOrderRepository _orderRepository;
public SetPaidOrderStatusCommandHandler(IOrderRepository orderRepository)
{
_orderRepository = orderRepository;
}
/// <summary>
/// Handler which processes the command when
/// Shipment service confirms the payment
/// </summary>
/// <param name="command"></param>
/// <returns></returns>
public async Task<bool> Handle(SetPaidOrderStatusCommand command, CancellationToken cancellationToken)
{
// Simulate a work time for validating the payment
await Task.Delay(10000);
var orderToUpdate = await _orderRepository.GetAsync(command.OrderNumber);
if(orderToUpdate == null)
{
return false;
}
orderToUpdate.SetPaidStatus();
return await _orderRepository.UnitOfWork.SaveEntitiesAsync();
}
}
// Use for Idempotency in Command process
public class SetPaidIdentifiedOrderStatusCommandHandler : IdentifiedCommandHandler<SetPaidOrderStatusCommand, bool>
{
public SetPaidIdentifiedOrderStatusCommandHandler(IMediator mediator, IRequestManager requestManager) : base(mediator, requestManager)
{
}
protected override bool CreateResultForDuplicateRequest()
{
return true; // Ignore duplicate requests for processing order.
}
}
}

+ 21
- 0
src/Services/Ordering/Ordering.API/Application/Commands/SetStockConfirmedOrderStatusCommand.cs View File

@ -0,0 +1,21 @@
using MediatR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Threading.Tasks;
namespace Ordering.API.Application.Commands
{
public class SetStockConfirmedOrderStatusCommand : IRequest<bool>
{
[DataMember]
public int OrderNumber { get; private set; }
public SetStockConfirmedOrderStatusCommand(int orderNumber)
{
OrderNumber = orderNumber;
}
}
}

+ 55
- 0
src/Services/Ordering/Ordering.API/Application/Commands/SetStockConfirmedOrderStatusCommandHandler.cs View File

@ -0,0 +1,55 @@
using MediatR;
using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Idempotency;
using System.Threading;
using System.Threading.Tasks;
namespace Ordering.API.Application.Commands
{
// Regular CommandHandler
public class SetStockConfirmedOrderStatusCommandHandler : IRequestHandler<SetStockConfirmedOrderStatusCommand, bool>
{
private readonly IOrderRepository _orderRepository;
public SetStockConfirmedOrderStatusCommandHandler(IOrderRepository orderRepository)
{
_orderRepository = orderRepository;
}
/// <summary>
/// Handler which processes the command when
/// Stock service confirms the request
/// </summary>
/// <param name="command"></param>
/// <returns></returns>
public async Task<bool> Handle(SetStockConfirmedOrderStatusCommand command, CancellationToken cancellationToken)
{
// Simulate a work time for confirming the stock
await Task.Delay(10000);
var orderToUpdate = await _orderRepository.GetAsync(command.OrderNumber);
if(orderToUpdate == null)
{
return false;
}
orderToUpdate.SetStockConfirmedStatus();
return await _orderRepository.UnitOfWork.SaveEntitiesAsync();
}
}
// Use for Idempotency in Command process
public class SetStockConfirmedOrderStatusIdenfifiedCommandHandler : IdentifiedCommandHandler<SetStockConfirmedOrderStatusCommand, bool>
{
public SetStockConfirmedOrderStatusIdenfifiedCommandHandler(IMediator mediator, IRequestManager requestManager) : base(mediator, requestManager)
{
}
protected override bool CreateResultForDuplicateRequest()
{
return true; // Ignore duplicate requests for processing order.
}
}
}

+ 25
- 0
src/Services/Ordering/Ordering.API/Application/Commands/SetStockRejectedOrderStatusCommand.cs View File

@ -0,0 +1,25 @@
using MediatR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Threading.Tasks;
namespace Ordering.API.Application.Commands
{
public class SetStockRejectedOrderStatusCommand : IRequest<bool>
{
[DataMember]
public int OrderNumber { get; private set; }
[DataMember]
public List<int> OrderStockItems { get; private set; }
public SetStockRejectedOrderStatusCommand(int orderNumber, List<int> orderStockItems)
{
OrderNumber = orderNumber;
OrderStockItems = orderStockItems;
}
}
}

+ 56
- 0
src/Services/Ordering/Ordering.API/Application/Commands/SetStockRejectedOrderStatusCommandHandler.cs View File

@ -0,0 +1,56 @@
using MediatR;
using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Idempotency;
using System.Threading;
using System.Threading.Tasks;
namespace Ordering.API.Application.Commands
{
// Regular CommandHandler
public class SetStockRejectedOrderStatusCommandHandler : IRequestHandler<SetStockRejectedOrderStatusCommand, bool>
{
private readonly IOrderRepository _orderRepository;
public SetStockRejectedOrderStatusCommandHandler(IOrderRepository orderRepository)
{
_orderRepository = orderRepository;
}
/// <summary>
/// Handler which processes the command when
/// Stock service rejects the request
/// </summary>
/// <param name="command"></param>
/// <returns></returns>
public async Task<bool> Handle(SetStockRejectedOrderStatusCommand command, CancellationToken cancellationToken)
{
// Simulate a work time for rejecting the stock
await Task.Delay(10000);
var orderToUpdate = await _orderRepository.GetAsync(command.OrderNumber);
if(orderToUpdate == null)
{
return false;
}
orderToUpdate.SetCancelledStatusWhenStockIsRejected(command.OrderStockItems);
return await _orderRepository.UnitOfWork.SaveEntitiesAsync();
}
}
// Use for Idempotency in Command process
public class SetStockRejectedOrderStatusIdenfifiedCommandHandler : IdentifiedCommandHandler<SetStockRejectedOrderStatusCommand, bool>
{
public SetStockRejectedOrderStatusIdenfifiedCommandHandler(IMediator mediator, IRequestManager requestManager) : base(mediator, requestManager)
{
}
protected override bool CreateResultForDuplicateRequest()
{
return true; // Ignore duplicate requests for processing order.
}
}
}

+ 8
- 7
src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/GracePeriodConfirmedIntegrationEventHandler.cs View File

@ -1,5 +1,7 @@
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using MediatR;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
using Ordering.API.Application.Commands;
using Ordering.API.Application.IntegrationEvents.Events;
using System.Threading.Tasks;
@ -7,11 +9,11 @@ namespace Ordering.API.Application.IntegrationEvents.EventHandling
{
public class GracePeriodConfirmedIntegrationEventHandler : IIntegrationEventHandler<GracePeriodConfirmedIntegrationEvent>
{
private readonly IOrderRepository _orderRepository;
private readonly IMediator _mediator;
public GracePeriodConfirmedIntegrationEventHandler(IOrderRepository orderRepository)
public GracePeriodConfirmedIntegrationEventHandler(IMediator mediator)
{
_orderRepository = orderRepository;
_mediator = mediator;
}
/// <summary>
@ -24,9 +26,8 @@ namespace Ordering.API.Application.IntegrationEvents.EventHandling
/// <returns></returns>
public async Task Handle(GracePeriodConfirmedIntegrationEvent @event)
{
var orderToUpdate = await _orderRepository.GetAsync(@event.OrderId);
orderToUpdate.SetAwaitingValidationStatus();
await _orderRepository.UnitOfWork.SaveEntitiesAsync();
var command = new SetAwaitingValidationOrderStatusCommand(@event.OrderId);
await _mediator.Send(command);
}
}
}

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

@ -1,27 +1,27 @@
namespace Ordering.API.Application.IntegrationEvents.EventHandling
{
using MediatR;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
using Ordering.API.Application.Commands;
using Ordering.API.Application.IntegrationEvents.Events;
using System;
using System.Threading.Tasks;
public class OrderPaymentFailedIntegrationEventHandler :
IIntegrationEventHandler<OrderPaymentFailedIntegrationEvent>
{
private readonly IOrderRepository _orderRepository;
private readonly IMediator _mediator;
public OrderPaymentFailedIntegrationEventHandler(IOrderRepository orderRepository)
public OrderPaymentFailedIntegrationEventHandler(IMediator mediator)
{
_orderRepository = orderRepository;
_mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
}
public async Task Handle(OrderPaymentFailedIntegrationEvent @event)
{
var orderToUpdate = await _orderRepository.GetAsync(@event.OrderId);
orderToUpdate.SetCancelledStatus();
await _orderRepository.UnitOfWork.SaveEntitiesAsync();
var command = new CancelOrderCommand(@event.OrderId);
await _mediator.Send(command);
}
}
}

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

@ -1,30 +1,27 @@
namespace Ordering.API.Application.IntegrationEvents.EventHandling
{
using MediatR;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
using Ordering.API.Application.Commands;
using Ordering.API.Application.IntegrationEvents.Events;
using System;
using System.Threading.Tasks;
public class OrderPaymentSuccededIntegrationEventHandler :
IIntegrationEventHandler<OrderPaymentSuccededIntegrationEvent>
{
private readonly IOrderRepository _orderRepository;
private readonly IMediator _mediator;
public OrderPaymentSuccededIntegrationEventHandler(IOrderRepository orderRepository)
public OrderPaymentSuccededIntegrationEventHandler(IMediator mediator)
{
_orderRepository = orderRepository;
_mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
}
public async Task Handle(OrderPaymentSuccededIntegrationEvent @event)
{
// Simulate a work time for validating the payment
await Task.Delay(10000);
var orderToUpdate = await _orderRepository.GetAsync(@event.OrderId);
orderToUpdate.SetPaidStatus();
await _orderRepository.UnitOfWork.SaveEntitiesAsync();
var command = new SetPaidOrderStatusCommand(@event.OrderId);
await _mediator.Send(command);
}
}
}

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

@ -4,27 +4,24 @@
using System.Threading.Tasks;
using Events;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
using MediatR;
using System;
using Ordering.API.Application.Commands;
public class OrderStockConfirmedIntegrationEventHandler :
IIntegrationEventHandler<OrderStockConfirmedIntegrationEvent>
{
private readonly IOrderRepository _orderRepository;
private readonly IMediator _mediator;
public OrderStockConfirmedIntegrationEventHandler(IOrderRepository orderRepository)
public OrderStockConfirmedIntegrationEventHandler(IMediator mediator)
{
_orderRepository = orderRepository;
_mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
}
public async Task Handle(OrderStockConfirmedIntegrationEvent @event)
{
// Simulate a work time for confirming the stock
await Task.Delay(10000);
var orderToUpdate = await _orderRepository.GetAsync(@event.OrderId);
orderToUpdate.SetStockConfirmedStatus();
await _orderRepository.UnitOfWork.SaveEntitiesAsync();
var command = new SetStockConfirmedOrderStatusCommand(@event.OrderId);
await _mediator.Send(command);
}
}
}

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

@ -5,27 +5,27 @@
using Events;
using System.Linq;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
using MediatR;
using Ordering.API.Application.Commands;
public class OrderStockRejectedIntegrationEventHandler : IIntegrationEventHandler<OrderStockRejectedIntegrationEvent>
{
private readonly IOrderRepository _orderRepository;
private readonly IMediator _mediator;
public OrderStockRejectedIntegrationEventHandler(IOrderRepository orderRepository)
public OrderStockRejectedIntegrationEventHandler(IMediator mediator)
{
_orderRepository = orderRepository;
_mediator = mediator;
}
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);
.Select(c => c.ProductId)
.ToList();
await _orderRepository.UnitOfWork.SaveEntitiesAsync();
var command = new SetStockRejectedOrderStatusCommand(@event.OrderId, orderStockRejectedItems);
await _mediator.Send(command);
}
}
}

Loading…
Cancel
Save