Merge
This commit is contained in:
commit
90daff2f29
@ -107,7 +107,7 @@ services:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=linux"
|
||||
|
||||
payment.api:
|
||||
image: payment.api:dev
|
||||
image: eshop/payment.api:dev
|
||||
build:
|
||||
args:
|
||||
source: ${DOCKER_BUILD_SOURCE}
|
||||
|
@ -86,7 +86,7 @@ services:
|
||||
dockerfile: Dockerfile
|
||||
|
||||
payment.api:
|
||||
image: payment.api
|
||||
image: eshop/payment.api
|
||||
build:
|
||||
context: ./src/Services/Payment/Payment.API
|
||||
dockerfile: Dockerfile
|
||||
|
@ -1,4 +1,4 @@
|
||||
namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.EventHandling
|
||||
namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationCommands.CommandHandlers
|
||||
{
|
||||
using BuildingBlocks.EventBus.Abstractions;
|
||||
using System.Threading.Tasks;
|
||||
@ -9,21 +9,22 @@
|
||||
using global::Catalog.API.Infrastructure.Exceptions;
|
||||
using global::Catalog.API.IntegrationEvents;
|
||||
using Model;
|
||||
using Events;
|
||||
using Commands;
|
||||
using IntegrationEvents.Events;
|
||||
|
||||
public class ConfirmOrderStockIntegrationEventHandler : IIntegrationEventHandler<ConfirmOrderStockIntegrationEvent>
|
||||
public class ConfirmOrderStockCommandMsgHandler : IIntegrationEventHandler<ConfirmOrderStockCommandMsg>
|
||||
{
|
||||
private readonly CatalogContext _catalogContext;
|
||||
private readonly ICatalogIntegrationEventService _catalogIntegrationEventService;
|
||||
|
||||
public ConfirmOrderStockIntegrationEventHandler(CatalogContext catalogContext,
|
||||
public ConfirmOrderStockCommandMsgHandler(CatalogContext catalogContext,
|
||||
ICatalogIntegrationEventService catalogIntegrationEventService)
|
||||
{
|
||||
_catalogContext = catalogContext;
|
||||
_catalogIntegrationEventService = catalogIntegrationEventService;
|
||||
}
|
||||
|
||||
public async Task Handle(ConfirmOrderStockIntegrationEvent @event)
|
||||
public async Task Handle(ConfirmOrderStockCommandMsg @event)
|
||||
{
|
||||
var confirmedOrderStockItems = new List<ConfirmedOrderStockItem>();
|
||||
|
||||
@ -38,15 +39,11 @@
|
||||
confirmedOrderStockItems.Add(confirmedOrderStockItem);
|
||||
}
|
||||
|
||||
//Create Integration Event to be published through the Event Bus
|
||||
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(confirmedIntegrationEvent);
|
||||
}
|
||||
|
@ -0,0 +1,42 @@
|
||||
namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationCommands.CommandHandlers
|
||||
{
|
||||
using BuildingBlocks.EventBus.Abstractions;
|
||||
using System.Threading.Tasks;
|
||||
using Infrastructure;
|
||||
using global::Catalog.API.Infrastructure.Exceptions;
|
||||
using global::Catalog.API.IntegrationEvents;
|
||||
using Model;
|
||||
using Commands;
|
||||
|
||||
public class DecrementOrderStockCommandMsgHandler : IIntegrationEventHandler<DecrementOrderStockCommandMsg>
|
||||
{
|
||||
private readonly CatalogContext _catalogContext;
|
||||
|
||||
public DecrementOrderStockCommandMsgHandler(CatalogContext catalogContext)
|
||||
{
|
||||
_catalogContext = catalogContext;
|
||||
}
|
||||
|
||||
public async Task Handle(DecrementOrderStockCommandMsg @event)
|
||||
{
|
||||
//we're not blocking stock/inventory
|
||||
foreach (var orderStockItem in @event.OrderStockItems)
|
||||
{
|
||||
var catalogItem = _catalogContext.CatalogItems.Find(orderStockItem.ProductId);
|
||||
CheckValidcatalogItemId(catalogItem);
|
||||
|
||||
catalogItem.RemoveStock(orderStockItem.Units);
|
||||
}
|
||||
|
||||
await _catalogContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
private void CheckValidcatalogItemId(CatalogItem catalogItem)
|
||||
{
|
||||
if (catalogItem is null)
|
||||
{
|
||||
throw new CatalogDomainException("Not able to process catalog event. Reason: no valid catalogItemId");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,14 +1,14 @@
|
||||
namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events
|
||||
namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationCommands.Commands
|
||||
{
|
||||
using BuildingBlocks.EventBus.Events;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class ConfirmOrderStockIntegrationEvent : IntegrationEvent
|
||||
public class ConfirmOrderStockCommandMsg : IntegrationEvent
|
||||
{
|
||||
public int OrderId { get; }
|
||||
public IEnumerable<OrderStockItem> OrderStockItems { get; }
|
||||
|
||||
public ConfirmOrderStockIntegrationEvent(int orderId,
|
||||
public ConfirmOrderStockCommandMsg(int orderId,
|
||||
IEnumerable<OrderStockItem> orderStockItems)
|
||||
{
|
||||
OrderId = orderId;
|
@ -0,0 +1,18 @@
|
||||
namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationCommands.Commands
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
|
||||
|
||||
public class DecrementOrderStockCommandMsg : IntegrationEvent
|
||||
{
|
||||
public int OrderId { get; }
|
||||
public IEnumerable<OrderStockItem> OrderStockItems { get; }
|
||||
|
||||
public DecrementOrderStockCommandMsg(int orderId,
|
||||
IEnumerable<OrderStockItem> orderStockItems)
|
||||
{
|
||||
OrderId = orderId;
|
||||
OrderStockItems = orderStockItems;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events
|
||||
{
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
|
||||
using BuildingBlocks.EventBus.Events;
|
||||
|
||||
public class OrderStockConfirmedIntegrationEvent : IntegrationEvent
|
||||
{
|
||||
|
@ -1,10 +1,7 @@
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events
|
||||
namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events
|
||||
{
|
||||
using BuildingBlocks.EventBus.Events;
|
||||
|
||||
// Integration Events notes:
|
||||
// An Event is “something that has happened in the past”, therefore its name has to be
|
||||
// An Integration Event is an event that can cause side effects to other microsrvices, Bounded-Contexts or external systems.
|
||||
@ -23,4 +20,4 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Eve
|
||||
OldPrice = oldPrice;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -14,6 +14,9 @@
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF;
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services;
|
||||
using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure;
|
||||
using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationCommands.Commands;
|
||||
using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents;
|
||||
using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationCommands.CommandHandlers;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.HealthChecks;
|
||||
@ -24,7 +27,7 @@
|
||||
using System.Data.Common;
|
||||
using System.Data.SqlClient;
|
||||
using System.Reflection;
|
||||
|
||||
|
||||
public class Startup
|
||||
{
|
||||
public IConfigurationRoot Configuration { get; }
|
||||
@ -120,6 +123,8 @@
|
||||
|
||||
services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>();
|
||||
services.AddSingleton<IEventBus, EventBusRabbitMQ>();
|
||||
services.AddTransient<IIntegrationEventHandler<ConfirmOrderStockCommandMsg>, ConfirmOrderStockCommandMsgHandler>();
|
||||
services.AddTransient<IIntegrationEventHandler<DecrementOrderStockCommandMsg>, DecrementOrderStockCommandMsgHandler>();
|
||||
|
||||
var container = new ContainerBuilder();
|
||||
container.Populate(services);
|
||||
@ -149,6 +154,8 @@
|
||||
CatalogContextSeed.SeedAsync(app, loggerFactory)
|
||||
.Wait();
|
||||
|
||||
ConfigureEventBus(app);
|
||||
|
||||
var integrationEventLogContext = new IntegrationEventLogContext(
|
||||
new DbContextOptionsBuilder<IntegrationEventLogContext>()
|
||||
.UseSqlServer(Configuration["ConnectionString"], b => b.MigrationsAssembly("Catalog.API"))
|
||||
@ -180,5 +187,13 @@
|
||||
ctx.Database.CloseConnection();
|
||||
}
|
||||
}
|
||||
|
||||
private void ConfigureEventBus(IApplicationBuilder app)
|
||||
{
|
||||
var eventBus = app.ApplicationServices.GetRequiredService<IEventBus>();
|
||||
|
||||
eventBus.Subscribe<ConfirmOrderStockCommandMsg, IIntegrationEventHandler<ConfirmOrderStockCommandMsg>>();
|
||||
eventBus.Subscribe<DecrementOrderStockCommandMsg, IIntegrationEventHandler<DecrementOrderStockCommandMsg>>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,7 @@
|
||||
// make sure that consistency is preserved across the whole aggregate
|
||||
var address = new Address(message.Street, message.City, message.State, message.Country, message.ZipCode);
|
||||
var order = new Order(message.UserId, address, message.CardTypeId, message.CardNumber, message.CardSecurityNumber, message.CardHolderName, message.CardExpiration);
|
||||
order.SetOrderStatusId(OrderStatus.Submited.Id);
|
||||
order.SetSubmitedStatus();
|
||||
foreach (var item in message.OrderItems)
|
||||
{
|
||||
order.AddOrderItem(item.ProductId, item.ProductName, item.UnitPrice, item.Discount, item.PictureUrl, item.Units);
|
||||
|
@ -0,0 +1,46 @@
|
||||
namespace Ordering.API.Application.DomainEventHandlers.OrderGracePeriodConfirmed
|
||||
{
|
||||
using MediatR;
|
||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Domain.Events;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Ordering.API.Application.IntegrationCommands.Commands;
|
||||
using Ordering.API.Application.IntegrationEvents;
|
||||
using System.Linq;
|
||||
|
||||
public class OrderStatusChangedToAwaitingValidationDomainEventHandler
|
||||
: IAsyncNotificationHandler<OrderStatusChangedToAwaitingValidationDomainEvent>
|
||||
{
|
||||
private readonly IOrderRepository _orderRepository;
|
||||
private readonly ILoggerFactory _logger;
|
||||
private readonly IOrderingIntegrationEventService _orderingIntegrationEventService;
|
||||
|
||||
public OrderStatusChangedToAwaitingValidationDomainEventHandler(
|
||||
IOrderRepository orderRepository, ILoggerFactory logger,
|
||||
IOrderingIntegrationEventService orderingIntegrationEventService)
|
||||
{
|
||||
_orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository));
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
_orderingIntegrationEventService = orderingIntegrationEventService;
|
||||
}
|
||||
|
||||
public async Task Handle(OrderStatusChangedToAwaitingValidationDomainEvent orderStatusChangedToAwaitingValidationDomainEvent)
|
||||
{
|
||||
await _orderRepository.UnitOfWork.SaveEntitiesAsync();
|
||||
|
||||
_logger.CreateLogger(nameof(OrderStatusChangedToAwaitingValidationDomainEvent))
|
||||
.LogTrace($"Order with Id: {orderStatusChangedToAwaitingValidationDomainEvent.OrderId} has been successfully updated with " +
|
||||
$"a status order id: {OrderStatus.AwaitingValidation.Id}");
|
||||
|
||||
var orderStockList = orderStatusChangedToAwaitingValidationDomainEvent.OrderItems
|
||||
.Select(orderItem => new OrderStockItem(orderItem.ProductId, orderItem.GetUnits()));
|
||||
|
||||
var confirmOrderStockEvent = new ConfirmOrderStockCommandMsg(orderStatusChangedToAwaitingValidationDomainEvent.OrderId,
|
||||
orderStockList);
|
||||
await _orderingIntegrationEventService.SaveEventAndOrderingContextChangesAsync(confirmOrderStockEvent);
|
||||
await _orderingIntegrationEventService.PublishThroughEventBusAsync(confirmOrderStockEvent);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
namespace Ordering.API.Application.DomainEventHandlers.OrderPaid
|
||||
{
|
||||
using MediatR;
|
||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Domain.Events;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Ordering.API.Application.IntegrationCommands.Commands;
|
||||
using Ordering.API.Application.IntegrationEvents;
|
||||
using System.Linq;
|
||||
|
||||
public class OrderStatusChangedToPaidDomainEventHandler
|
||||
: IAsyncNotificationHandler<OrderStatusChangedToPaidDomainEvent>
|
||||
{
|
||||
private readonly IOrderRepository _orderRepository;
|
||||
private readonly ILoggerFactory _logger;
|
||||
private readonly IOrderingIntegrationEventService _orderingIntegrationEventService;
|
||||
|
||||
public OrderStatusChangedToPaidDomainEventHandler(
|
||||
IOrderRepository orderRepository, ILoggerFactory logger,
|
||||
IOrderingIntegrationEventService orderingIntegrationEventService)
|
||||
{
|
||||
_orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository));
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
_orderingIntegrationEventService = orderingIntegrationEventService;
|
||||
}
|
||||
|
||||
public async Task Handle(OrderStatusChangedToPaidDomainEvent orderStatusChangedToPaidDomainEvent)
|
||||
{
|
||||
await _orderRepository.UnitOfWork.SaveEntitiesAsync();
|
||||
|
||||
_logger.CreateLogger(nameof(OrderStatusChangedToPaidDomainEventHandler))
|
||||
.LogTrace($"Order with Id: {orderStatusChangedToPaidDomainEvent.OrderId} has been successfully updated with " +
|
||||
$"a status order id: {OrderStatus.Paid.Id}");
|
||||
|
||||
var orderStockList = orderStatusChangedToPaidDomainEvent.OrderItems
|
||||
.Select(orderItem => new OrderStockItem(orderItem.ProductId, orderItem.GetUnits()));
|
||||
|
||||
var decrementOrderStockCommandMsg = new DecrementOrderStockCommandMsg(orderStatusChangedToPaidDomainEvent.OrderId,
|
||||
orderStockList);
|
||||
await _orderingIntegrationEventService.SaveEventAndOrderingContextChangesAsync(decrementOrderStockCommandMsg);
|
||||
await _orderingIntegrationEventService.PublishThroughEventBusAsync(decrementOrderStockCommandMsg);
|
||||
|
||||
//is it necessary get a DecrementOrderStockSuccessIntegrationEvent/DecrementOrderStockFailedIntegrationEvent before to call ShipOrderCommandMsg???
|
||||
var shipOrderCommandMsg = new ShipOrderCommandMsg(orderStatusChangedToPaidDomainEvent.OrderId);
|
||||
await _orderingIntegrationEventService.SaveEventAndOrderingContextChangesAsync(shipOrderCommandMsg);
|
||||
await _orderingIntegrationEventService.PublishThroughEventBusAsync(shipOrderCommandMsg);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
namespace Ordering.API.Application.DomainEventHandlers.OrderStartedEvent
|
||||
namespace Ordering.API.Application.DomainEventHandlers.OrderStockConfirmed
|
||||
{
|
||||
using MediatR;
|
||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
|
||||
@ -9,14 +9,14 @@
|
||||
using Ordering.API.Application.IntegrationCommands.Commands;
|
||||
using Ordering.API.Application.IntegrationEvents;
|
||||
|
||||
public class UpdateOrderWhenOrderStockMethodVerifiedDomainEventHandler
|
||||
: IAsyncNotificationHandler<OrderStockMethodVerifiedDomainEvent>
|
||||
public class OrderStatusChangedToStockConfirmedDomainEventHandler
|
||||
: IAsyncNotificationHandler<OrderStatusChangedToStockConfirmedDomainEvent>
|
||||
{
|
||||
private readonly IOrderRepository _orderRepository;
|
||||
private readonly ILoggerFactory _logger;
|
||||
private readonly IOrderingIntegrationEventService _orderingIntegrationEventService;
|
||||
|
||||
public UpdateOrderWhenOrderStockMethodVerifiedDomainEventHandler(
|
||||
public OrderStatusChangedToStockConfirmedDomainEventHandler(
|
||||
IOrderRepository orderRepository, ILoggerFactory logger,
|
||||
IOrderingIntegrationEventService orderingIntegrationEventService)
|
||||
{
|
||||
@ -25,21 +25,15 @@
|
||||
_orderingIntegrationEventService = orderingIntegrationEventService;
|
||||
}
|
||||
|
||||
public async Task Handle(OrderStockMethodVerifiedDomainEvent orderStockMethodVerifiedDomainEvent)
|
||||
public async Task Handle(OrderStatusChangedToStockConfirmedDomainEvent orderStatusChangedToStockConfirmedDomainEvent)
|
||||
{
|
||||
var orderToUpdate = await _orderRepository.GetAsync(orderStockMethodVerifiedDomainEvent.OrderId);
|
||||
orderToUpdate.SetOrderStatusId(orderStockMethodVerifiedDomainEvent.OrderStatus.Id);
|
||||
|
||||
_orderRepository.Update(orderToUpdate);
|
||||
await _orderRepository.UnitOfWork.SaveEntitiesAsync();
|
||||
|
||||
await _orderRepository.UnitOfWork
|
||||
.SaveEntitiesAsync();
|
||||
_logger.CreateLogger(nameof(OrderStatusChangedToStockConfirmedDomainEventHandler))
|
||||
.LogTrace($"Order with Id: {orderStatusChangedToStockConfirmedDomainEvent.OrderId} has been successfully updated with " +
|
||||
$"a status order id: {OrderStatus.StockConfirmed.Id}");
|
||||
|
||||
_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(orderToUpdate.Id);
|
||||
var payOrderCommandMsg = new PayOrderCommandMsg(orderStatusChangedToStockConfirmedDomainEvent.OrderId);
|
||||
await _orderingIntegrationEventService.SaveEventAndOrderingContextChangesAsync(payOrderCommandMsg);
|
||||
await _orderingIntegrationEventService.PublishThroughEventBusAsync(payOrderCommandMsg);
|
||||
}
|
@ -6,13 +6,13 @@
|
||||
public class ConfirmOrderStockCommandMsg : IntegrationEvent
|
||||
{
|
||||
public int OrderId { get; }
|
||||
public IEnumerable<OrderStockItem> OrderStockItem { get; }
|
||||
public IEnumerable<OrderStockItem> OrderStockItems { get; }
|
||||
|
||||
public ConfirmOrderStockCommandMsg(int orderId,
|
||||
IEnumerable<OrderStockItem> orderStockItem)
|
||||
IEnumerable<OrderStockItem> orderStockItems)
|
||||
{
|
||||
OrderId = orderId;
|
||||
OrderStockItem = orderStockItem;
|
||||
OrderStockItems = orderStockItems;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,18 @@
|
||||
namespace Ordering.API.Application.IntegrationCommands.Commands
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
|
||||
|
||||
public class DecrementOrderStockCommandMsg : IntegrationEvent
|
||||
{
|
||||
public int OrderId { get; }
|
||||
public IEnumerable<OrderStockItem> OrderStockItems { get; }
|
||||
|
||||
public DecrementOrderStockCommandMsg(int orderId,
|
||||
IEnumerable<OrderStockItem> orderStockItems)
|
||||
{
|
||||
OrderId = orderId;
|
||||
OrderStockItems = orderStockItems;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
namespace Ordering.API.Application.IntegrationCommands.Commands
|
||||
{
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
|
||||
|
||||
public class ShipOrderCommandMsg : IntegrationEvent
|
||||
{
|
||||
public int OrderId { get; }
|
||||
|
||||
public ShipOrderCommandMsg(int orderId)
|
||||
{
|
||||
OrderId = orderId;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,14 +1,23 @@
|
||||
namespace Ordering.API.Application.IntegrationEvents.EventHandling
|
||||
{
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
|
||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
|
||||
using Ordering.API.Application.IntegrationEvents.Events;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public class OrderPaymentFailedIntegrationEventHandler :
|
||||
IIntegrationEventHandler<OrderPaymentFailedIntegrationEvent>
|
||||
{
|
||||
private readonly IOrderRepository _orderRepository;
|
||||
|
||||
public OrderPaymentFailedIntegrationEventHandler(IOrderRepository orderRepository)
|
||||
{
|
||||
_orderRepository = orderRepository;
|
||||
}
|
||||
|
||||
public async Task Handle(OrderPaymentFailedIntegrationEvent @event)
|
||||
{
|
||||
//TODO: Cancel Order
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,35 @@
|
||||
namespace Ordering.API.Application.IntegrationEvents.EventHandling
|
||||
{
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
|
||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
|
||||
using Ordering.API.Application.IntegrationEvents.Events;
|
||||
using Ordering.Domain.Exceptions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public class OrderPaymentSuccededIntegrationEventHandler :
|
||||
IIntegrationEventHandler<OrderPaymentSuccededIntegrationEvent>
|
||||
{
|
||||
private readonly IOrderRepository _orderRepository;
|
||||
|
||||
public OrderPaymentSuccededIntegrationEventHandler(IOrderRepository orderRepository)
|
||||
{
|
||||
_orderRepository = orderRepository;
|
||||
}
|
||||
|
||||
public async Task Handle(OrderPaymentSuccededIntegrationEvent @event)
|
||||
{
|
||||
var order = await _orderRepository.GetAsync(@event.OrderId);
|
||||
CheckValidSagaId(order);
|
||||
|
||||
order.SetPaidStatus();
|
||||
}
|
||||
|
||||
private void CheckValidSagaId(Order orderSaga)
|
||||
{
|
||||
if (orderSaga is null)
|
||||
{
|
||||
throw new OrderingDomainException("Not able to process order saga event. Reason: no valid orderId");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -10,32 +10,19 @@
|
||||
public class OrderStockConfirmedIntegrationEventHandler :
|
||||
IIntegrationEventHandler<OrderStockConfirmedIntegrationEvent>
|
||||
{
|
||||
private readonly IOrderingIntegrationEventService _orderingIntegrationEventService;
|
||||
private readonly IOrderRepository _orderRepository;
|
||||
|
||||
public OrderStockConfirmedIntegrationEventHandler(IOrderRepository orderRepository,
|
||||
IOrderingIntegrationEventService orderingIntegrationEventService)
|
||||
public OrderStockConfirmedIntegrationEventHandler(IOrderRepository orderRepository)
|
||||
{
|
||||
_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
|
||||
var order = await _orderRepository.GetAsync(@event.OrderId);
|
||||
CheckValidSagaId(order);
|
||||
|
||||
order.SetOrderStockConfirmed();
|
||||
|
||||
//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);
|
||||
order.SetStockConfirmedStatus();
|
||||
}
|
||||
|
||||
private void CheckValidSagaId(Order orderSaga)
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.Linq;
|
||||
using Ordering.API.Application.IntegrationCommands.Commands;
|
||||
|
||||
namespace Ordering.API.Application.IntegrationEvents.EventHandling
|
||||
{
|
||||
@ -7,33 +8,27 @@ namespace Ordering.API.Application.IntegrationEvents.EventHandling
|
||||
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;
|
||||
using Domain.Exceptions;
|
||||
|
||||
public class OrderStockNotConfirmedIntegrationEventHandler : IIntegrationEventHandler<OrderStockNotConfirmedIntegrationEvent>
|
||||
{
|
||||
private readonly IOrderingIntegrationEventService _orderingIntegrationEventService;
|
||||
private readonly IOrderRepository _orderRepository;
|
||||
|
||||
public OrderStockNotConfirmedIntegrationEventHandler(IOrderRepository orderRepository,
|
||||
IOrderingIntegrationEventService orderingIntegrationEventService)
|
||||
public OrderStockNotConfirmedIntegrationEventHandler(IOrderRepository orderRepository)
|
||||
{
|
||||
_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
|
||||
var order = await _orderRepository.GetAsync(@event.OrderId);
|
||||
CheckValidSagaId(order);
|
||||
var orderToUpdate = await _orderRepository.GetAsync(@event.OrderId);
|
||||
CheckValidSagaId(orderToUpdate);
|
||||
|
||||
var orderStockNotConfirmedItems = @event.OrderStockItems
|
||||
.FindAll(c => !c.Confirmed)
|
||||
.Select(c => c.ProductId);
|
||||
|
||||
order.SetOrderStockConfirmed(orderStockNotConfirmedItems);
|
||||
orderToUpdate.SetStockConfirmedStatus(orderStockNotConfirmedItems);
|
||||
}
|
||||
|
||||
private void CheckValidSagaId(Order orderSaga)
|
||||
|
@ -8,8 +8,10 @@ using Ordering.API.Application.Commands;
|
||||
using Ordering.API.Application.IntegrationCommands.Commands;
|
||||
using Ordering.API.Application.IntegrationEvents;
|
||||
using Ordering.Domain.Exceptions;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Ordering.API.Application.IntegrationEvents;
|
||||
|
||||
namespace Ordering.API.Application.Sagas
|
||||
{
|
||||
@ -21,7 +23,7 @@ namespace Ordering.API.Application.Sagas
|
||||
/// the opportunity to cancel the order before proceeding
|
||||
/// with the validations.
|
||||
/// </summary>
|
||||
public class OrderProcessSaga : Saga<Order>,
|
||||
public class OrderProcessSaga : OrderSaga,
|
||||
IIntegrationEventHandler<ConfirmGracePeriodCommandMsg>,
|
||||
IAsyncRequestHandler<CancelOrderCommand, bool>,
|
||||
IAsyncRequestHandler<ShipOrderCommand, bool>
|
||||
@ -54,17 +56,9 @@ namespace Ordering.API.Application.Sagas
|
||||
|
||||
if (orderSaga.OrderStatus != OrderStatus.Cancelled)
|
||||
{
|
||||
orderSaga.SetOrderStatusId(OrderStatus.AwaitingValidation.Id);
|
||||
orderSaga.SetAwaitingValidationStatus();
|
||||
|
||||
await SaveChangesAsync();
|
||||
|
||||
var orderStockList = orderSaga.OrderItems
|
||||
.Select(orderItem => new OrderStockItem(orderItem.ProductId, orderItem.GetUnits()));
|
||||
|
||||
var confirmOrderStockEvent = new ConfirmOrderStockCommandMsg(orderSaga.Id, orderStockList);
|
||||
|
||||
await _orderingIntegrationEventService.SaveEventAndOrderingContextChangesAsync(confirmOrderStockEvent);
|
||||
|
||||
await _orderingIntegrationEventService.PublishThroughEventBusAsync(confirmOrderStockEvent);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
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<Order>
|
||||
{
|
||||
private OrderingContext _orderingContext;
|
||||
|
||||
public OrderSaga(OrderingContext orderingContext) : base(orderingContext)
|
||||
{
|
||||
_orderingContext = orderingContext;
|
||||
}
|
||||
|
||||
public override Order FindSagaById(int id)
|
||||
{
|
||||
var order = _orderingContext.Orders
|
||||
.Single(c => c.Id == id);
|
||||
|
||||
_orderingContext.Entry(order)
|
||||
.Member("OrderStatus");
|
||||
|
||||
return order;
|
||||
}
|
||||
|
||||
public override async Task<bool> SaveChangesAsync()
|
||||
{
|
||||
return await _orderingContext.SaveEntitiesAsync();
|
||||
}
|
||||
}
|
||||
}
|
@ -14,17 +14,8 @@ namespace Ordering.API.Application.Sagas
|
||||
_dbContext = dbContext;
|
||||
}
|
||||
|
||||
protected TEntity FindSagaById(int id, DbContext context = null)
|
||||
{
|
||||
var ctx = context ?? _dbContext;
|
||||
return ctx.Set<TEntity>().Where(x => x.Id == id).SingleOrDefault();
|
||||
}
|
||||
public abstract TEntity FindSagaById(int id);
|
||||
|
||||
protected async Task<bool> SaveChangesAsync(DbContext context = null)
|
||||
{
|
||||
var ctx = context ?? _dbContext;
|
||||
var result = await ctx.SaveChangesAsync();
|
||||
return result > 0;
|
||||
}
|
||||
public abstract Task<bool> SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@
|
||||
{
|
||||
context.OrderStatus.Add(OrderStatus.Submited);
|
||||
context.OrderStatus.Add(OrderStatus.AwaitingValidation);
|
||||
context.OrderStatus.Add(OrderStatus.StockValidated);
|
||||
context.OrderStatus.Add(OrderStatus.StockConfirmed);
|
||||
context.OrderStatus.Add(OrderStatus.Paid);
|
||||
context.OrderStatus.Add(OrderStatus.Shipped);
|
||||
context.OrderStatus.Add(OrderStatus.Cancelled);
|
||||
|
@ -8,6 +8,8 @@
|
||||
using global::Ordering.API.Application.IntegrationEvents.Events;
|
||||
using global::Ordering.API.Application.Sagas;
|
||||
using global::Ordering.API.Infrastructure.Middlewares;
|
||||
using global::Ordering.API.Application.IntegrationCommands.Commands;
|
||||
using global::Ordering.API.Application.Sagas;
|
||||
using Infrastructure;
|
||||
using Infrastructure.Auth;
|
||||
using Infrastructure.AutofacModules;
|
||||
@ -108,7 +110,7 @@
|
||||
services.AddTransient<IIdentityService, IdentityService>();
|
||||
services.AddTransient<Func<DbConnection, IIntegrationEventLogService>>(
|
||||
sp => (DbConnection c) => new IntegrationEventLogService(c));
|
||||
var serviceProvider = services.BuildServiceProvider();
|
||||
|
||||
services.AddTransient<IOrderingIntegrationEventService, OrderingIntegrationEventService>();
|
||||
|
||||
services.AddSingleton<IRabbitMQPersistentConnection>(sp =>
|
||||
|
@ -1,5 +1,6 @@
|
||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.Seedwork;
|
||||
using Ordering.Domain.Events;
|
||||
using Ordering.Domain.Exceptions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@ -93,33 +94,80 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
|
||||
_buyerId = id;
|
||||
}
|
||||
|
||||
public void SetOrderStatusId(int id)
|
||||
#region Status Changes
|
||||
public void SetSubmitedStatus()
|
||||
{
|
||||
_orderStatusId = id;
|
||||
_orderStatusId = OrderStatus.Submited.Id;
|
||||
}
|
||||
|
||||
public void SetOrderStockConfirmed(IEnumerable<int> orderStockNotConfirmedItems = null)
|
||||
public void SetAwaitingValidationStatus()
|
||||
{
|
||||
if(orderStockNotConfirmedItems is null)
|
||||
if (_orderStatusId != OrderStatus.Submited.Id)
|
||||
{
|
||||
OrderStatus = OrderStatus.StockValidated;
|
||||
StatusChangeException();
|
||||
}
|
||||
|
||||
_orderStatusId = OrderStatus.AwaitingValidation.Id;
|
||||
|
||||
AddDomainEvent(new OrderStatusChangedToAwaitingValidationDomainEvent(Id, OrderItems));
|
||||
}
|
||||
|
||||
public void SetStockConfirmedStatus(IEnumerable<int> orderStockNotConfirmedItems = null)
|
||||
{
|
||||
if (_orderStatusId != OrderStatus.AwaitingValidation.Id)
|
||||
{
|
||||
StatusChangeException();
|
||||
}
|
||||
|
||||
if (orderStockNotConfirmedItems is null)
|
||||
{
|
||||
OrderStatus = OrderStatus.StockConfirmed;
|
||||
|
||||
_description = "All the items were confirmed with available stock.";
|
||||
//AddDomainEvent(new OrderStockMethodVerifiedDomainEvent(Id, OrderStatus.StockValidated));
|
||||
|
||||
AddDomainEvent(new OrderStatusChangedToStockConfirmedDomainEvent(Id));
|
||||
}
|
||||
else
|
||||
{
|
||||
OrderStatus = OrderStatus.Cancelled;
|
||||
|
||||
var itemsStockNotConfirmedProductNames = OrderItems
|
||||
.Where(c => orderStockNotConfirmedItems.Contains(c.ProductId))
|
||||
.Select(c => c.GetOrderItemProductName());
|
||||
|
||||
var itemsStockNotConfirmedDescription = string.Join(", ", itemsStockNotConfirmedProductNames);
|
||||
|
||||
OrderStatus = OrderStatus.Cancelled;
|
||||
_description = $"The product items don't have stock: ({itemsStockNotConfirmedDescription}).";
|
||||
//AddDomainEvent(new OrderStockMethodVerifiedDomainEvent(Id, OrderStatus.Cancelled));
|
||||
_description = $"The product items don't have stock: ({itemsStockNotConfirmedDescription}).";
|
||||
}
|
||||
}
|
||||
|
||||
public void SetPaidStatus()
|
||||
{
|
||||
if (_orderStatusId != OrderStatus.StockConfirmed.Id)
|
||||
{
|
||||
StatusChangeException();
|
||||
}
|
||||
|
||||
_orderStatusId = OrderStatus.Paid.Id;
|
||||
_description = "The payment was performed at a simulated \"American Bank checking bank account endinf on XX35071\"";
|
||||
|
||||
AddDomainEvent(new OrderStatusChangedToPaidDomainEvent(Id, OrderItems));
|
||||
}
|
||||
|
||||
public void SetShippedStatus()
|
||||
{
|
||||
if (_orderStatusId != OrderStatus.Paid.Id)
|
||||
{
|
||||
StatusChangeException();
|
||||
}
|
||||
|
||||
_orderStatusId = OrderStatus.Shipped.Id;
|
||||
_description = "";
|
||||
|
||||
//Call Domain Event
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public int GetOrderStatusId()
|
||||
{
|
||||
return _orderStatusId;
|
||||
@ -134,6 +182,11 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.O
|
||||
|
||||
this.AddDomainEvent(orderStartedDomainEvent);
|
||||
}
|
||||
|
||||
private void StatusChangeException()
|
||||
{
|
||||
throw new OrderingDomainException("Not able to process order event. Reason: no valid order status change");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
{
|
||||
public static OrderStatus Submited = new OrderStatus(1, nameof(Submited).ToLowerInvariant());
|
||||
public static OrderStatus AwaitingValidation = new OrderStatus(2, nameof(AwaitingValidation).ToLowerInvariant());
|
||||
public static OrderStatus StockValidated = new OrderStatus(3, nameof(StockValidated).ToLowerInvariant());
|
||||
public static OrderStatus StockConfirmed = new OrderStatus(3, nameof(StockConfirmed).ToLowerInvariant());
|
||||
public static OrderStatus Paid = new OrderStatus(4, nameof(Paid).ToLowerInvariant());
|
||||
public static OrderStatus Shipped = new OrderStatus(5, nameof(Shipped).ToLowerInvariant());
|
||||
public static OrderStatus Cancelled = new OrderStatus(6, nameof(Cancelled).ToLowerInvariant());
|
||||
@ -27,7 +27,7 @@
|
||||
}
|
||||
|
||||
public static IEnumerable<OrderStatus> List() =>
|
||||
new[] { Submited, AwaitingValidation, StockValidated, Paid, Shipped, Cancelled };
|
||||
new[] { Submited, AwaitingValidation, StockConfirmed, Paid, Shipped, Cancelled };
|
||||
|
||||
public static OrderStatus FromName(string name)
|
||||
{
|
||||
|
@ -0,0 +1,23 @@
|
||||
namespace Ordering.Domain.Events
|
||||
{
|
||||
using MediatR;
|
||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
|
||||
using System.Collections.Generic;
|
||||
|
||||
/// <summary>
|
||||
/// Event used when the grace period order is confirmed
|
||||
/// </summary>
|
||||
public class OrderStatusChangedToAwaitingValidationDomainEvent
|
||||
: IAsyncNotification
|
||||
{
|
||||
public int OrderId { get; }
|
||||
public IEnumerable<OrderItem> OrderItems { get; }
|
||||
|
||||
public OrderStatusChangedToAwaitingValidationDomainEvent(int orderId,
|
||||
IEnumerable<OrderItem> orderItems)
|
||||
{
|
||||
OrderId = orderId;
|
||||
OrderItems = orderItems;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
namespace Ordering.Domain.Events
|
||||
{
|
||||
using MediatR;
|
||||
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
|
||||
using System.Collections.Generic;
|
||||
|
||||
/// <summary>
|
||||
/// Event used when the order is paid
|
||||
/// </summary>
|
||||
public class OrderStatusChangedToPaidDomainEvent
|
||||
: IAsyncNotification
|
||||
{
|
||||
public int OrderId { get; }
|
||||
public IEnumerable<OrderItem> OrderItems { get; }
|
||||
|
||||
public OrderStatusChangedToPaidDomainEvent(int orderId,
|
||||
IEnumerable<OrderItem> orderItems)
|
||||
{
|
||||
OrderId = orderId;
|
||||
OrderItems = orderItems;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
namespace Ordering.Domain.Events
|
||||
{
|
||||
using MediatR;
|
||||
|
||||
/// <summary>
|
||||
/// Event used when the order stock items are confirmed
|
||||
/// </summary>
|
||||
public class OrderStatusChangedToStockConfirmedDomainEvent
|
||||
: IAsyncNotification
|
||||
{
|
||||
public int OrderId { get; }
|
||||
|
||||
public OrderStatusChangedToStockConfirmedDomainEvent(int orderId)
|
||||
=> OrderId = orderId;
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
namespace Payment.API.IntegrationCommands.CommandHandlers
|
||||
{
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
|
||||
using Payment.API.IntegrationCommands.Commands;
|
||||
using System.Threading.Tasks;
|
||||
using System;
|
||||
|
||||
public class PayOrderCommandMsgHandler : IIntegrationEventHandler<PayOrderCommandMsg>
|
||||
{
|
||||
public PayOrderCommandMsgHandler()
|
||||
{
|
||||
}
|
||||
|
||||
public async Task Handle(PayOrderCommandMsg @event)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
namespace Payment.API.IntegrationCommands.Commands
|
||||
{
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
|
||||
|
||||
public class PayOrderCommandMsg : IntegrationEvent
|
||||
{
|
||||
public int OrderId { get; }
|
||||
|
||||
public PayOrderCommandMsg(int orderId) => OrderId = orderId;
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
namespace Payment.API.IntegrationEvents.Events
|
||||
{
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
|
||||
|
||||
public class OrderPaymentFailedIntegrationEvent : IntegrationEvent
|
||||
{
|
||||
public int OrderId { get; }
|
||||
|
||||
public OrderPaymentFailedIntegrationEvent(int orderId) => OrderId = orderId;
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
namespace Payment.API.IntegrationEvents.Events
|
||||
{
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
|
||||
|
||||
public class OrderPaymentSuccededIntegrationEvent : IntegrationEvent
|
||||
{
|
||||
public int OrderId { get; }
|
||||
|
||||
public OrderPaymentSuccededIntegrationEvent(int orderId) => OrderId = orderId;
|
||||
}
|
||||
}
|
@ -25,5 +25,10 @@
|
||||
<ItemGroup>
|
||||
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="1.0.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBusRabbitMQ\EventBusRabbitMQ.csproj" />
|
||||
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\EventBus\EventBus.csproj" />
|
||||
<ProjectReference Include="..\..\..\BuildingBlocks\EventBus\IntegrationEventLogEF\IntegrationEventLogEF.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@ -6,6 +6,11 @@ using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
|
||||
using Payment.API.IntegrationCommands.Commands;
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ;
|
||||
using RabbitMQ.Client;
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus;
|
||||
|
||||
namespace Payment.API
|
||||
{
|
||||
@ -29,6 +34,21 @@ namespace Payment.API
|
||||
// Add framework services.
|
||||
services.AddMvc();
|
||||
|
||||
services.AddSingleton<IRabbitMQPersistentConnection>(sp =>
|
||||
{
|
||||
var logger = sp.GetRequiredService<ILogger<DefaultRabbitMQPersistentConnection>>();
|
||||
|
||||
var factory = new ConnectionFactory()
|
||||
{
|
||||
HostName = Configuration["EventBusConnection"]
|
||||
};
|
||||
|
||||
return new DefaultRabbitMQPersistentConnection(factory, logger);
|
||||
});
|
||||
|
||||
services.AddSingleton<IEventBus, EventBusRabbitMQ>();
|
||||
services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>();
|
||||
|
||||
services.AddSwaggerGen();
|
||||
services.ConfigureSwaggerGen(options =>
|
||||
{
|
||||
@ -47,6 +67,8 @@ namespace Payment.API
|
||||
return new AutofacServiceProvider(container.Build());
|
||||
}
|
||||
|
||||
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
|
||||
{
|
||||
@ -57,6 +79,14 @@ namespace Payment.API
|
||||
|
||||
app.UseSwagger()
|
||||
.UseSwaggerUi();
|
||||
|
||||
ConfigureEventBus(app);
|
||||
}
|
||||
|
||||
private void ConfigureEventBus(IApplicationBuilder app)
|
||||
{
|
||||
var eventBus = app.ApplicationServices.GetRequiredService<IEventBus>();
|
||||
eventBus.Subscribe<PayOrderCommandMsg, IIntegrationEventHandler<PayOrderCommandMsg>>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ namespace SagaManager
|
||||
using Services;
|
||||
using Autofac.Extensions.DependencyInjection;
|
||||
using Autofac;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public class Program
|
||||
{
|
||||
@ -25,7 +26,12 @@ namespace SagaManager
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
StartUp();
|
||||
MainAsync().Wait();
|
||||
}
|
||||
|
||||
static async Task MainAsync()
|
||||
{
|
||||
StartUp();
|
||||
|
||||
IServiceCollection services = new ServiceCollection();
|
||||
var serviceProvider = ConfigureServices(services);
|
||||
@ -39,7 +45,7 @@ namespace SagaManager
|
||||
while (true)
|
||||
{
|
||||
sagaManagerService.CheckFinishedGracePeriodOrders();
|
||||
System.Threading.Thread.Sleep(30000);
|
||||
await Task.Delay(30000);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,7 +96,8 @@ public class OrderAggregateTest
|
||||
[Fact]
|
||||
public void Add_new_Order_raises_new_event()
|
||||
{
|
||||
//Arrange
|
||||
//Arrange
|
||||
var userId = new Guid();
|
||||
var street = "fakeStreet";
|
||||
var city = "FakeCity";
|
||||
var state = "fakeState";
|
||||
@ -119,7 +120,8 @@ public class OrderAggregateTest
|
||||
[Fact]
|
||||
public void Add_event_Order_explicitly_raises_new_event()
|
||||
{
|
||||
//Arrange
|
||||
//Arrange
|
||||
var userId = new Guid();
|
||||
var street = "fakeStreet";
|
||||
var city = "FakeCity";
|
||||
var state = "fakeState";
|
||||
@ -143,6 +145,7 @@ public class OrderAggregateTest
|
||||
public void Remove_event_Order_explicitly()
|
||||
{
|
||||
//Arrange
|
||||
var userId = new Guid();
|
||||
var street = "fakeStreet";
|
||||
var city = "FakeCity";
|
||||
var state = "fakeState";
|
||||
|
Loading…
x
Reference in New Issue
Block a user