Browse Source

Merge

pull/809/head
Ramón Tomás 7 years ago
parent
commit
4e79875d26
39 changed files with 547 additions and 131 deletions
  1. +1
    -1
      docker-compose.vs.debug.yml
  2. +1
    -1
      docker-compose.yml
  3. +6
    -9
      src/Services/Catalog/Catalog.API/IntegrationCommands/CommandHandlers/ConfirmOrderStockCommandMsgHandler.cs
  4. +42
    -0
      src/Services/Catalog/Catalog.API/IntegrationCommands/CommandHandlers/DecrementOrderStockCommandMsgHandler.cs
  5. +3
    -3
      src/Services/Catalog/Catalog.API/IntegrationCommands/Commands/ConfirmOrderStockCommandMsg.cs
  6. +18
    -0
      src/Services/Catalog/Catalog.API/IntegrationCommands/Commands/DecrementOrderStockCommandMsg.cs
  7. +1
    -1
      src/Services/Catalog/Catalog.API/IntegrationEvents/Events/OrderStockConfirmedIntegrationEvent.cs
  8. +4
    -7
      src/Services/Catalog/Catalog.API/IntegrationEvents/Events/ProductPriceChangedIntegrationEvent.cs
  9. +16
    -1
      src/Services/Catalog/Catalog.API/Startup.cs
  10. +1
    -1
      src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommandHandler.cs
  11. +46
    -0
      src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderGracePeriodConfirmed/OrderStatusChangedToAwaitingValidationDomainEventHandler.cs
  12. +51
    -0
      src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderPaid/OrderStatusChangedToPaidDomainEventHandler.cs
  13. +10
    -16
      src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStockConfirmed/OrderStatusChangedToStockConfirmedDomainEventHandler.cs
  14. +3
    -3
      src/Services/Ordering/Ordering.API/Application/IntegrationCommands/Commands/ConfirmOrderStockCommandMsg.cs
  15. +18
    -0
      src/Services/Ordering/Ordering.API/Application/IntegrationCommands/Commands/DecrementOrderStockCommandMsg.cs
  16. +14
    -0
      src/Services/Ordering/Ordering.API/Application/IntegrationCommands/Commands/ShipOrderCommandMsg.cs
  17. +9
    -0
      src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentFailedIntegrationEventHandler.cs
  18. +22
    -1
      src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentSuccededIntegrationEventHandler.cs
  19. +2
    -15
      src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockConfirmedIntegrationEventHandler.cs
  20. +6
    -11
      src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockNotConfirmedIntegrationEventHandler.cs
  21. +5
    -11
      src/Services/Ordering/Ordering.API/Application/Sagas/OrderProcessSaga.cs
  22. +36
    -0
      src/Services/Ordering/Ordering.API/Application/Sagas/OrderSaga.cs
  23. +2
    -11
      src/Services/Ordering/Ordering.API/Application/Sagas/Saga.cs
  24. +1
    -1
      src/Services/Ordering/Ordering.API/Infrastructure/OrderingContextSeed.cs
  25. +3
    -1
      src/Services/Ordering/Ordering.API/Startup.cs
  26. +62
    -9
      src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs
  27. +2
    -2
      src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/OrderStatus.cs
  28. +23
    -0
      src/Services/Ordering/Ordering.Domain/Events/OrderStatusChangedToAwaitingValidationDomainEvent.cs
  29. +23
    -0
      src/Services/Ordering/Ordering.Domain/Events/OrderStatusChangedToPaidDomainEvent.cs
  30. +16
    -0
      src/Services/Ordering/Ordering.Domain/Events/OrderStatusChangedToStockConfirmedDomainEvent.cs
  31. +0
    -22
      src/Services/Ordering/Ordering.Domain/Events/OrderStockMethodVerifiedDomainEvent.cs
  32. +19
    -0
      src/Services/Payment/Payment.API/IntegrationCommands/CommandHandlers/PayOrderCommandMsgHandler.cs
  33. +11
    -0
      src/Services/Payment/Payment.API/IntegrationCommands/Commands/PayOrderCommandMsg.cs
  34. +11
    -0
      src/Services/Payment/Payment.API/IntegrationEvents/Events/OrderPaymentFailedIntegrationEvent.cs
  35. +11
    -0
      src/Services/Payment/Payment.API/IntegrationEvents/Events/OrderPaymentSuccededIntegrationEvent.cs
  36. +5
    -0
      src/Services/Payment/Payment.API/Payment.API.csproj
  37. +30
    -0
      src/Services/Payment/Payment.API/Startup.cs
  38. +8
    -2
      src/Services/SagaManager/SagaManager/Program.cs
  39. +5
    -2
      test/Services/UnitTest/Ordering/Domain/OrderAggregateTest.cs

+ 1
- 1
docker-compose.vs.debug.yml View File

@ -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}


+ 1
- 1
docker-compose.yml View File

@ -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

src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/ConfirmOrderStockIntegrationEventHandler.cs → src/Services/Catalog/Catalog.API/IntegrationCommands/CommandHandlers/ConfirmOrderStockCommandMsgHandler.cs View File

@ -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);
}

+ 42
- 0
src/Services/Catalog/Catalog.API/IntegrationCommands/CommandHandlers/DecrementOrderStockCommandMsgHandler.cs View File

@ -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");
}
}
}
}

src/Services/Catalog/Catalog.API/IntegrationEvents/Events/ConfirmOrderStockIntegrationEvent.cs → src/Services/Catalog/Catalog.API/IntegrationCommands/Commands/ConfirmOrderStockCommandMsg.cs View File

@ -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;

+ 18
- 0
src/Services/Catalog/Catalog.API/IntegrationCommands/Commands/DecrementOrderStockCommandMsg.cs View File

@ -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
- 1
src/Services/Catalog/Catalog.API/IntegrationEvents/Events/OrderStockConfirmedIntegrationEvent.cs View File

@ -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
{


+ 4
- 7
src/Services/Catalog/Catalog.API/IntegrationEvents/Events/ProductPriceChangedIntegrationEvent.cs View File

@ -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;
}
}
}
}

+ 16
- 1
src/Services/Catalog/Catalog.API/Startup.cs View File

@ -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>>();
}
}
}

+ 1
- 1
src/Services/Ordering/Ordering.API/Application/Commands/CreateOrderCommandHandler.cs View File

@ -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);


+ 46
- 0
src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderGracePeriodConfirmed/OrderStatusChangedToAwaitingValidationDomainEventHandler.cs View File

@ -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);
}
}
}

+ 51
- 0
src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderPaid/OrderStatusChangedToPaidDomainEventHandler.cs View File

@ -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);
}
}
}

src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStockConfirmation/UpdateOrderWhenOrderStockMethodVerifiedDomainEventHandler.cs → src/Services/Ordering/Ordering.API/Application/DomainEventHandlers/OrderStockConfirmed/OrderStatusChangedToStockConfirmedDomainEventHandler.cs View File

@ -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);
}

+ 3
- 3
src/Services/Ordering/Ordering.API/Application/IntegrationCommands/Commands/ConfirmOrderStockCommandMsg.cs View File

@ -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;
}
}


+ 18
- 0
src/Services/Ordering/Ordering.API/Application/IntegrationCommands/Commands/DecrementOrderStockCommandMsg.cs View File

@ -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;
}
}
}

+ 14
- 0
src/Services/Ordering/Ordering.API/Application/IntegrationCommands/Commands/ShipOrderCommandMsg.cs View File

@ -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;
}
}
}

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

@ -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
}
}
}

+ 22
- 1
src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderPaymentSuccededIntegrationEventHandler.cs View File

@ -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");
}
}
}
}
}

+ 2
- 15
src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockConfirmedIntegrationEventHandler.cs View File

@ -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)


+ 6
- 11
src/Services/Ordering/Ordering.API/Application/IntegrationEvents/EventHandling/OrderStockNotConfirmedIntegrationEventHandler.cs View File

@ -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)


+ 5
- 11
src/Services/Ordering/Ordering.API/Application/Sagas/OrderProcessSaga.cs View File

@ -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);
await SaveChangesAsync();
var orderStockList = orderSaga.OrderItems
.Select(orderItem => new OrderStockItem(orderItem.ProductId, orderItem.GetUnits()));
orderSaga.SetAwaitingValidationStatus();
var confirmOrderStockEvent = new ConfirmOrderStockCommandMsg(orderSaga.Id, orderStockList);
await _orderingIntegrationEventService.SaveEventAndOrderingContextChangesAsync(confirmOrderStockEvent);
await _orderingIntegrationEventService.PublishThroughEventBusAsync(confirmOrderStockEvent);
await SaveChangesAsync();
}
}


+ 36
- 0
src/Services/Ordering/Ordering.API/Application/Sagas/OrderSaga.cs View File

@ -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();
}
}
}

+ 2
- 11
src/Services/Ordering/Ordering.API/Application/Sagas/Saga.cs View File

@ -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();
}
}

+ 1
- 1
src/Services/Ordering/Ordering.API/Infrastructure/OrderingContextSeed.cs View File

@ -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);


+ 3
- 1
src/Services/Ordering/Ordering.API/Startup.cs View File

@ -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 =>


+ 62
- 9
src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/Order.cs View File

@ -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 SetAwaitingValidationStatus()
{
if (_orderStatusId != OrderStatus.Submited.Id)
{
StatusChangeException();
}
_orderStatusId = OrderStatus.AwaitingValidation.Id;
AddDomainEvent(new OrderStatusChangedToAwaitingValidationDomainEvent(Id, OrderItems));
}
public void SetOrderStockConfirmed(IEnumerable<int> orderStockNotConfirmedItems = null)
public void SetStockConfirmedStatus(IEnumerable<int> orderStockNotConfirmedItems = null)
{
if(orderStockNotConfirmedItems is null)
if (_orderStatusId != OrderStatus.AwaitingValidation.Id)
{
StatusChangeException();
}
if (orderStockNotConfirmedItems is null)
{
OrderStatus = OrderStatus.StockValidated;
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);
_description = $"The product items don't have stock: ({itemsStockNotConfirmedDescription}).";
}
}
OrderStatus = OrderStatus.Cancelled;
_description = $"The product items don't have stock: ({itemsStockNotConfirmedDescription}).";
//AddDomainEvent(new OrderStockMethodVerifiedDomainEvent(Id, OrderStatus.Cancelled));
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");
}
}
}

+ 2
- 2
src/Services/Ordering/Ordering.Domain/AggregatesModel/OrderAggregate/OrderStatus.cs View File

@ -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)
{


+ 23
- 0
src/Services/Ordering/Ordering.Domain/Events/OrderStatusChangedToAwaitingValidationDomainEvent.cs View File

@ -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;
}
}
}

+ 23
- 0
src/Services/Ordering/Ordering.Domain/Events/OrderStatusChangedToPaidDomainEvent.cs View File

@ -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;
}
}
}

+ 16
- 0
src/Services/Ordering/Ordering.Domain/Events/OrderStatusChangedToStockConfirmedDomainEvent.cs View File

@ -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;
}
}

+ 0
- 22
src/Services/Ordering/Ordering.Domain/Events/OrderStockMethodVerifiedDomainEvent.cs View File

@ -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;
}
}
}

+ 19
- 0
src/Services/Payment/Payment.API/IntegrationCommands/CommandHandlers/PayOrderCommandMsgHandler.cs View File

@ -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();
}
}
}

+ 11
- 0
src/Services/Payment/Payment.API/IntegrationCommands/Commands/PayOrderCommandMsg.cs View File

@ -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;
}
}

+ 11
- 0
src/Services/Payment/Payment.API/IntegrationEvents/Events/OrderPaymentFailedIntegrationEvent.cs View File

@ -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;
}
}

+ 11
- 0
src/Services/Payment/Payment.API/IntegrationEvents/Events/OrderPaymentSuccededIntegrationEvent.cs View File

@ -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;
}
}

+ 5
- 0
src/Services/Payment/Payment.API/Payment.API.csproj View File

@ -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>

+ 30
- 0
src/Services/Payment/Payment.API/Startup.cs View File

@ -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>>();
}
}
}

+ 8
- 2
src/Services/SagaManager/SagaManager/Program.cs View File

@ -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);
}
}


+ 5
- 2
test/Services/UnitTest/Ordering/Domain/OrderAggregateTest.cs View File

@ -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…
Cancel
Save