diff --git a/src/Services/Ordering/Ordering.API/Application/Commands/CancelOrderCommandHandler.cs b/src/Services/Ordering/Ordering.API/Application/Commands/CancelOrderCommandHandler.cs new file mode 100644 index 000000000..f8ea7ad40 --- /dev/null +++ b/src/Services/Ordering/Ordering.API/Application/Commands/CancelOrderCommandHandler.cs @@ -0,0 +1,46 @@ +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; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Ordering.API.Application.Commands +{ + public class CancelOrderCommandIdentifiedHandler : IdentifierCommandHandler + { + public CancelOrderCommandIdentifiedHandler(IMediator mediator, IRequestManager requestManager) : base(mediator, requestManager) + { + } + + protected override bool CreateResultForDuplicateRequest() + { + return true; // Ignore duplicate requests for processing order. + } + } + + public class CancelOrderCommandHandler : IAsyncRequestHandler + { + private readonly IOrderRepository _orderRepository; + + public CancelOrderCommandHandler(IOrderRepository orderRepository) + { + _orderRepository = orderRepository; + } + + /// + /// Handler which processes the command when + /// customer executes cancel order from app + /// + /// + /// + public async Task Handle(CancelOrderCommand command) + { + var orderToUpdate = await _orderRepository.GetAsync(command.OrderNumber); + orderToUpdate.SetCancelledStatus(); + return await _orderRepository.UnitOfWork.SaveEntitiesAsync(); + } + } +} diff --git a/src/Services/Ordering/Ordering.API/Application/Commands/ShipOrderCommandHandler.cs b/src/Services/Ordering/Ordering.API/Application/Commands/ShipOrderCommandHandler.cs new file mode 100644 index 000000000..47f1f5d54 --- /dev/null +++ b/src/Services/Ordering/Ordering.API/Application/Commands/ShipOrderCommandHandler.cs @@ -0,0 +1,43 @@ +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.Tasks; + +namespace Ordering.API.Application.Commands +{ + public class ShipOrderCommandIdentifiedHandler : IdentifierCommandHandler + { + public ShipOrderCommandIdentifiedHandler(IMediator mediator, IRequestManager requestManager) : base(mediator, requestManager) + { + } + + protected override bool CreateResultForDuplicateRequest() + { + return true; // Ignore duplicate requests for processing order. + } + } + + public class ShipOrderCommandHandler : IAsyncRequestHandler + { + private readonly IOrderRepository _orderRepository; + + public ShipOrderCommandHandler(IOrderRepository orderRepository) + { + _orderRepository = orderRepository; + } + + /// + /// Handler which processes the command when + /// administrator executes ship order from app + /// + /// + /// + public async Task Handle(ShipOrderCommand command) + { + var orderToUpdate = await _orderRepository.GetAsync(command.OrderNumber); + orderToUpdate.SetShippedStatus(); + return await _orderRepository.UnitOfWork.SaveEntitiesAsync(); + } + } +} diff --git a/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/GracePeriodConfirmedIntegrationEventHandler.cs b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/GracePeriodConfirmedIntegrationEventHandler.cs new file mode 100644 index 000000000..c51619ff6 --- /dev/null +++ b/src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/GracePeriodConfirmedIntegrationEventHandler.cs @@ -0,0 +1,32 @@ +using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; +using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate; +using Ordering.API.Application.IntegrationEvents.Events; +using System.Threading.Tasks; + +namespace Ordering.API.Application.IntegrationEvents.EventHandling +{ + public class GracePeriodConfirmedIntegrationEventHandler : IIntegrationEventHandler + { + private readonly IOrderRepository _orderRepository; + + public GracePeriodConfirmedIntegrationEventHandler(IOrderRepository orderRepository) + { + _orderRepository = orderRepository; + } + + /// + /// Event handler which confirms that the grace period + /// has been completed and order will not initially be cancelled. + /// Therefore, the order process continues for validation. + /// + /// + /// + /// + public async Task Handle(GracePeriodConfirmedIntegrationEvent @event) + { + var orderToUpdate = await _orderRepository.GetAsync(@event.OrderId); + orderToUpdate.SetAwaitingValidationStatus(); + await _orderRepository.UnitOfWork.SaveEntitiesAsync(); + } + } +} diff --git a/src/Services/Ordering/Ordering.API/Application/Sagas/OrderProcessSaga.cs b/src/Services/Ordering/Ordering.API/Application/Sagas/OrderProcessSaga.cs deleted file mode 100644 index e91b52ae9..000000000 --- a/src/Services/Ordering/Ordering.API/Application/Sagas/OrderProcessSaga.cs +++ /dev/null @@ -1,121 +0,0 @@ -using MediatR; -using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; -using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands; -using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate; -using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure; -using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Idempotency; -using Ordering.API.Application.Commands; -using Ordering.API.Application.IntegrationEvents.Events; -using Ordering.Domain.Exceptions; -using System.Threading.Tasks; - -namespace Ordering.API.Application.Sagas -{ - /// - /// Saga for handling the place order process - /// and which is started once the basket.api has - /// successfully processed the items ordered. - /// Saga provides a period of grace to give the customer - /// the opportunity to cancel the order before proceeding - /// with the validations. - /// - public class OrderProcessSaga : OrderSaga, - IIntegrationEventHandler, - IAsyncRequestHandler, - IAsyncRequestHandler - { - - public OrderProcessSaga( - OrderingContext orderingContext) - : base(orderingContext) - { - } - - /// - /// Event handler which confirms that the grace period - /// has been completed and order will not initially be cancelled. - /// Therefore, the order process continues for validation. - /// - /// - /// Integration event message which is sent by a saga scheduler - /// telling us that the saga's grace period has completed. - /// - /// - public async Task Handle(GracePeriodConfirmedIntegrationEvent @event) - { - var orderSaga = FindSagaById(@event.OrderId); - CheckValidSagaId(orderSaga); - - orderSaga.SetAwaitingValidationStatus(); - await SaveChangesAsync(); - } - - /// - /// Handler which processes the command when - /// customer executes cancel order from app - /// - /// - /// - public async Task Handle(CancelOrderCommand command) - { - var result = false; - var orderSaga = FindSagaById(command.OrderNumber); - CheckValidSagaId(orderSaga); - - orderSaga.SetCancelledStatus(); - result = await SaveChangesAsync(); - - return result; - } - - /// - /// Handler which processes the command when - /// administrator executes ship order from app - /// - /// - /// - public async Task Handle(ShipOrderCommand command) - { - var result = false; - var orderSaga = FindSagaById(command.OrderNumber); - CheckValidSagaId(orderSaga); - - orderSaga.SetShippedStatus(); - result = await SaveChangesAsync(); - - return result; - } - - private void CheckValidSagaId(Order orderSaga) - { - if (orderSaga is null) - { - throw new OrderingDomainException("Not able to process order saga event. Reason: no valid orderId"); - } - } - - public class CancelOrderCommandIdentifiedHandler : IdentifierCommandHandler - { - public CancelOrderCommandIdentifiedHandler(IMediator mediator, IRequestManager requestManager) : base(mediator, requestManager) - { - } - - protected override bool CreateResultForDuplicateRequest() - { - return true; // Ignore duplicate requests for processing order. - } - } - - public class ShipOrderCommandIdentifiedHandler : IdentifierCommandHandler - { - public ShipOrderCommandIdentifiedHandler(IMediator mediator, IRequestManager requestManager) : base(mediator, requestManager) - { - } - - protected override bool CreateResultForDuplicateRequest() - { - return true; // Ignore duplicate requests for processing order. - } - } - } -} diff --git a/src/Services/Ordering/Ordering.API/Application/Sagas/OrderSaga.cs b/src/Services/Ordering/Ordering.API/Application/Sagas/OrderSaga.cs deleted file mode 100644 index a570d7eca..000000000 --- a/src/Services/Ordering/Ordering.API/Application/Sagas/OrderSaga.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Linq; -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; -using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate; -using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure; - -namespace Ordering.API.Application.Sagas -{ - public abstract class OrderSaga : Saga - { - private OrderingContext _orderingContext; - - public OrderSaga(OrderingContext orderingContext) : base(orderingContext) - { - _orderingContext = orderingContext; - } - - public override Order FindSagaById(int id) - { - return _orderingContext.Orders - .Include(c => c.OrderStatus) - .Include(c => c.OrderItems) - .Include(c => c.Address) - .Single(c => c.Id == id); - } - - public override async Task SaveChangesAsync() - { - return await _orderingContext.SaveEntitiesAsync(); - } - } -} diff --git a/src/Services/Ordering/Ordering.API/Application/Sagas/Saga.cs b/src/Services/Ordering/Ordering.API/Application/Sagas/Saga.cs deleted file mode 100644 index b03fb18fa..000000000 --- a/src/Services/Ordering/Ordering.API/Application/Sagas/Saga.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.eShopOnContainers.Services.Ordering.Domain.Seedwork; -using System.Linq; -using System.Threading.Tasks; - -namespace Ordering.API.Application.Sagas -{ - public abstract class Saga where TEntity : Entity - { - private readonly DbContext _dbContext; - - public Saga(DbContext dbContext) - { - _dbContext = dbContext; - } - - public abstract TEntity FindSagaById(int id); - - public abstract Task SaveChangesAsync(); - } -}