Skip to content
This repository was archived by the owner on Nov 17, 2023. It is now read-only.

Commit adafb9a

Browse files
author
Ramón Tomás
committed
Send commands for modifying state in IntegrationEventHandlers
1 parent 9adda02 commit adafb9a

13 files changed

+347
-46
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using MediatR;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Runtime.Serialization;
6+
using System.Threading.Tasks;
7+
8+
namespace Ordering.API.Application.Commands
9+
{
10+
public class SetAwaitingValidationOrderStatusCommand : IRequest<bool>
11+
{
12+
13+
[DataMember]
14+
public int OrderNumber { get; private set; }
15+
16+
public SetAwaitingValidationOrderStatusCommand(int orderNumber)
17+
{
18+
OrderNumber = orderNumber;
19+
}
20+
}
21+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
using MediatR;
2+
using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands;
3+
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
4+
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Idempotency;
5+
using System.Threading;
6+
using System.Threading.Tasks;
7+
8+
namespace Ordering.API.Application.Commands
9+
{
10+
// Regular CommandHandler
11+
public class SetAwaitingValidationOrderStatusCommandHandler : IRequestHandler<SetAwaitingValidationOrderStatusCommand, bool>
12+
{
13+
private readonly IOrderRepository _orderRepository;
14+
15+
public SetAwaitingValidationOrderStatusCommandHandler(IOrderRepository orderRepository)
16+
{
17+
_orderRepository = orderRepository;
18+
}
19+
20+
/// <summary>
21+
/// Handler which processes the command when
22+
/// graceperiod has finished
23+
/// </summary>
24+
/// <param name="command"></param>
25+
/// <returns></returns>
26+
public async Task<bool> Handle(SetAwaitingValidationOrderStatusCommand command, CancellationToken cancellationToken)
27+
{
28+
var orderToUpdate = await _orderRepository.GetAsync(command.OrderNumber);
29+
if(orderToUpdate == null)
30+
{
31+
return false;
32+
}
33+
34+
orderToUpdate.SetAwaitingValidationStatus();
35+
return await _orderRepository.UnitOfWork.SaveEntitiesAsync();
36+
}
37+
}
38+
39+
40+
// Use for Idempotency in Command process
41+
public class SetAwaitingValidationIdentifiedOrderStatusCommandHandler : IdentifiedCommandHandler<SetAwaitingValidationOrderStatusCommand, bool>
42+
{
43+
public SetAwaitingValidationIdentifiedOrderStatusCommandHandler(IMediator mediator, IRequestManager requestManager) : base(mediator, requestManager)
44+
{
45+
}
46+
47+
protected override bool CreateResultForDuplicateRequest()
48+
{
49+
return true; // Ignore duplicate requests for processing order.
50+
}
51+
}
52+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using MediatR;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Runtime.Serialization;
6+
using System.Threading.Tasks;
7+
8+
namespace Ordering.API.Application.Commands
9+
{
10+
public class SetPaidOrderStatusCommand : IRequest<bool>
11+
{
12+
13+
[DataMember]
14+
public int OrderNumber { get; private set; }
15+
16+
public SetPaidOrderStatusCommand(int orderNumber)
17+
{
18+
OrderNumber = orderNumber;
19+
}
20+
}
21+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
using MediatR;
2+
using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands;
3+
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
4+
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Idempotency;
5+
using System.Threading;
6+
using System.Threading.Tasks;
7+
8+
namespace Ordering.API.Application.Commands
9+
{
10+
// Regular CommandHandler
11+
public class SetPaidOrderStatusCommandHandler : IRequestHandler<SetPaidOrderStatusCommand, bool>
12+
{
13+
private readonly IOrderRepository _orderRepository;
14+
15+
public SetPaidOrderStatusCommandHandler(IOrderRepository orderRepository)
16+
{
17+
_orderRepository = orderRepository;
18+
}
19+
20+
/// <summary>
21+
/// Handler which processes the command when
22+
/// Shipment service confirms the payment
23+
/// </summary>
24+
/// <param name="command"></param>
25+
/// <returns></returns>
26+
public async Task<bool> Handle(SetPaidOrderStatusCommand command, CancellationToken cancellationToken)
27+
{
28+
// Simulate a work time for validating the payment
29+
await Task.Delay(10000);
30+
31+
var orderToUpdate = await _orderRepository.GetAsync(command.OrderNumber);
32+
if(orderToUpdate == null)
33+
{
34+
return false;
35+
}
36+
37+
orderToUpdate.SetPaidStatus();
38+
return await _orderRepository.UnitOfWork.SaveEntitiesAsync();
39+
}
40+
}
41+
42+
43+
// Use for Idempotency in Command process
44+
public class SetPaidIdentifiedOrderStatusCommandHandler : IdentifiedCommandHandler<SetPaidOrderStatusCommand, bool>
45+
{
46+
public SetPaidIdentifiedOrderStatusCommandHandler(IMediator mediator, IRequestManager requestManager) : base(mediator, requestManager)
47+
{
48+
}
49+
50+
protected override bool CreateResultForDuplicateRequest()
51+
{
52+
return true; // Ignore duplicate requests for processing order.
53+
}
54+
}
55+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using MediatR;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Runtime.Serialization;
6+
using System.Threading.Tasks;
7+
8+
namespace Ordering.API.Application.Commands
9+
{
10+
public class SetStockConfirmedOrderStatusCommand : IRequest<bool>
11+
{
12+
13+
[DataMember]
14+
public int OrderNumber { get; private set; }
15+
16+
public SetStockConfirmedOrderStatusCommand(int orderNumber)
17+
{
18+
OrderNumber = orderNumber;
19+
}
20+
}
21+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
using MediatR;
2+
using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands;
3+
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
4+
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Idempotency;
5+
using System.Threading;
6+
using System.Threading.Tasks;
7+
8+
namespace Ordering.API.Application.Commands
9+
{
10+
// Regular CommandHandler
11+
public class SetStockConfirmedOrderStatusCommandHandler : IRequestHandler<SetStockConfirmedOrderStatusCommand, bool>
12+
{
13+
private readonly IOrderRepository _orderRepository;
14+
15+
public SetStockConfirmedOrderStatusCommandHandler(IOrderRepository orderRepository)
16+
{
17+
_orderRepository = orderRepository;
18+
}
19+
20+
/// <summary>
21+
/// Handler which processes the command when
22+
/// Stock service confirms the request
23+
/// </summary>
24+
/// <param name="command"></param>
25+
/// <returns></returns>
26+
public async Task<bool> Handle(SetStockConfirmedOrderStatusCommand command, CancellationToken cancellationToken)
27+
{
28+
// Simulate a work time for confirming the stock
29+
await Task.Delay(10000);
30+
31+
var orderToUpdate = await _orderRepository.GetAsync(command.OrderNumber);
32+
if(orderToUpdate == null)
33+
{
34+
return false;
35+
}
36+
37+
orderToUpdate.SetStockConfirmedStatus();
38+
return await _orderRepository.UnitOfWork.SaveEntitiesAsync();
39+
}
40+
}
41+
42+
43+
// Use for Idempotency in Command process
44+
public class SetStockConfirmedOrderStatusIdenfifiedCommandHandler : IdentifiedCommandHandler<SetStockConfirmedOrderStatusCommand, bool>
45+
{
46+
public SetStockConfirmedOrderStatusIdenfifiedCommandHandler(IMediator mediator, IRequestManager requestManager) : base(mediator, requestManager)
47+
{
48+
}
49+
50+
protected override bool CreateResultForDuplicateRequest()
51+
{
52+
return true; // Ignore duplicate requests for processing order.
53+
}
54+
}
55+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using MediatR;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Runtime.Serialization;
6+
using System.Threading.Tasks;
7+
8+
namespace Ordering.API.Application.Commands
9+
{
10+
public class SetStockRejectedOrderStatusCommand : IRequest<bool>
11+
{
12+
13+
[DataMember]
14+
public int OrderNumber { get; private set; }
15+
16+
[DataMember]
17+
public List<int> OrderStockItems { get; private set; }
18+
19+
public SetStockRejectedOrderStatusCommand(int orderNumber, List<int> orderStockItems)
20+
{
21+
OrderNumber = orderNumber;
22+
OrderStockItems = orderStockItems;
23+
}
24+
}
25+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
using MediatR;
2+
using Microsoft.eShopOnContainers.Services.Ordering.API.Application.Commands;
3+
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
4+
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Idempotency;
5+
using System.Threading;
6+
using System.Threading.Tasks;
7+
8+
namespace Ordering.API.Application.Commands
9+
{
10+
// Regular CommandHandler
11+
public class SetStockRejectedOrderStatusCommandHandler : IRequestHandler<SetStockRejectedOrderStatusCommand, bool>
12+
{
13+
private readonly IOrderRepository _orderRepository;
14+
15+
public SetStockRejectedOrderStatusCommandHandler(IOrderRepository orderRepository)
16+
{
17+
_orderRepository = orderRepository;
18+
}
19+
20+
/// <summary>
21+
/// Handler which processes the command when
22+
/// Stock service rejects the request
23+
/// </summary>
24+
/// <param name="command"></param>
25+
/// <returns></returns>
26+
public async Task<bool> Handle(SetStockRejectedOrderStatusCommand command, CancellationToken cancellationToken)
27+
{
28+
// Simulate a work time for rejecting the stock
29+
await Task.Delay(10000);
30+
31+
var orderToUpdate = await _orderRepository.GetAsync(command.OrderNumber);
32+
if(orderToUpdate == null)
33+
{
34+
return false;
35+
}
36+
37+
orderToUpdate.SetCancelledStatusWhenStockIsRejected(command.OrderStockItems);
38+
39+
return await _orderRepository.UnitOfWork.SaveEntitiesAsync();
40+
}
41+
}
42+
43+
44+
// Use for Idempotency in Command process
45+
public class SetStockRejectedOrderStatusIdenfifiedCommandHandler : IdentifiedCommandHandler<SetStockRejectedOrderStatusCommand, bool>
46+
{
47+
public SetStockRejectedOrderStatusIdenfifiedCommandHandler(IMediator mediator, IRequestManager requestManager) : base(mediator, requestManager)
48+
{
49+
}
50+
51+
protected override bool CreateResultForDuplicateRequest()
52+
{
53+
return true; // Ignore duplicate requests for processing order.
54+
}
55+
}
56+
}
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
1-
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
1+
using MediatR;
2+
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
23
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
4+
using Ordering.API.Application.Commands;
35
using Ordering.API.Application.IntegrationEvents.Events;
46
using System.Threading.Tasks;
57

68
namespace Ordering.API.Application.IntegrationEvents.EventHandling
79
{
810
public class GracePeriodConfirmedIntegrationEventHandler : IIntegrationEventHandler<GracePeriodConfirmedIntegrationEvent>
911
{
10-
private readonly IOrderRepository _orderRepository;
12+
private readonly IMediator _mediator;
1113

12-
public GracePeriodConfirmedIntegrationEventHandler(IOrderRepository orderRepository)
14+
public GracePeriodConfirmedIntegrationEventHandler(IMediator mediator)
1315
{
14-
_orderRepository = orderRepository;
16+
_mediator = mediator;
1517
}
1618

1719
/// <summary>
@@ -24,9 +26,8 @@ public GracePeriodConfirmedIntegrationEventHandler(IOrderRepository orderReposit
2426
/// <returns></returns>
2527
public async Task Handle(GracePeriodConfirmedIntegrationEvent @event)
2628
{
27-
var orderToUpdate = await _orderRepository.GetAsync(@event.OrderId);
28-
orderToUpdate.SetAwaitingValidationStatus();
29-
await _orderRepository.UnitOfWork.SaveEntitiesAsync();
29+
var command = new SetAwaitingValidationOrderStatusCommand(@event.OrderId);
30+
await _mediator.Send(command);
3031
}
3132
}
3233
}
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
11
namespace Ordering.API.Application.IntegrationEvents.EventHandling
22
{
3+
using MediatR;
34
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
45
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
6+
using Ordering.API.Application.Commands;
57
using Ordering.API.Application.IntegrationEvents.Events;
8+
using System;
69
using System.Threading.Tasks;
710

811
public class OrderPaymentFailedIntegrationEventHandler :
912
IIntegrationEventHandler<OrderPaymentFailedIntegrationEvent>
1013
{
11-
private readonly IOrderRepository _orderRepository;
14+
private readonly IMediator _mediator;
1215

13-
public OrderPaymentFailedIntegrationEventHandler(IOrderRepository orderRepository)
16+
public OrderPaymentFailedIntegrationEventHandler(IMediator mediator)
1417
{
15-
_orderRepository = orderRepository;
18+
_mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
1619
}
1720

1821
public async Task Handle(OrderPaymentFailedIntegrationEvent @event)
1922
{
20-
var orderToUpdate = await _orderRepository.GetAsync(@event.OrderId);
21-
22-
orderToUpdate.SetCancelledStatus();
23-
24-
await _orderRepository.UnitOfWork.SaveEntitiesAsync();
23+
var command = new CancelOrderCommand(@event.OrderId);
24+
await _mediator.Send(command);
2525
}
2626
}
2727
}

0 commit comments

Comments
 (0)