Add LogContext to IntegrationEventHandlers

This commit is contained in:
Miguel Veloso 2019-02-18 19:33:04 +00:00
parent 6ccd7b6096
commit 122fab5108
27 changed files with 337 additions and 161 deletions

View File

@ -25,8 +25,8 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers
public BasketController(
ILogger<BasketController> logger,
IBasketRepository repository,
IIdentityService identityService,
IBasketRepository repository,
IIdentityService identityService,
IEventBus eventBus)
{
_logger = logger;
@ -58,7 +58,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers
public async Task<ActionResult> CheckoutAsync([FromBody]BasketCheckout basketCheckout, [FromHeader(Name = "x-requestid")] string requestId)
{
var userId = _identityService.GetUserIdentity();
basketCheckout.RequestId = (Guid.TryParse(requestId, out Guid guid) && guid != Guid.Empty) ?
guid : basketCheckout.RequestId;
@ -78,20 +78,17 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers
// Once basket is checkout, sends an integration event to
// ordering.api to convert basket to order and proceeds with
// order creation process
using (LogContext.PushProperty("IntegrationEventId", eventMessage.Id))
try
{
try
{
_logger.LogInformation("----- Publishing integration event: {IntegrationEventId} at {AppShortName} - ({@IntegrationEvent})", eventMessage.Id, Program.AppShortName, eventMessage);
_logger.LogInformation("----- Publishing integration event: {IntegrationEventId} at {AppShortName} - ({@IntegrationEvent})", eventMessage.Id, Program.AppShortName, eventMessage);
_eventBus.Publish(eventMessage);
}
catch (Exception ex)
{
_logger.LogError(ex, "----- ERROR Publishing integration event: {IntegrationEventId} at {AppShortName} - ({@IntegrationEvent})", eventMessage.Id, Program.AppShortName, eventMessage);
_eventBus.Publish(eventMessage);
}
catch (Exception ex)
{
_logger.LogError(ex, "----- ERROR Publishing integration event: {IntegrationEventId} at {AppShortName} - ({@IntegrationEvent})", eventMessage.Id, Program.AppShortName, eventMessage);
throw;
}
throw;
}
return Accepted();

View File

@ -1,6 +1,9 @@
using Basket.API.IntegrationEvents.Events;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.eShopOnContainers.Services.Basket.API;
using Microsoft.eShopOnContainers.Services.Basket.API.Model;
using Microsoft.Extensions.Logging;
using Serilog.Context;
using System;
using System.Threading.Tasks;
@ -9,15 +12,24 @@ namespace Basket.API.IntegrationEvents.EventHandling
public class OrderStartedIntegrationEventHandler : IIntegrationEventHandler<OrderStartedIntegrationEvent>
{
private readonly IBasketRepository _repository;
private readonly ILogger<OrderStartedIntegrationEventHandler> _logger;
public OrderStartedIntegrationEventHandler(IBasketRepository repository)
public OrderStartedIntegrationEventHandler(
IBasketRepository repository,
ILogger<OrderStartedIntegrationEventHandler> logger)
{
_repository = repository ?? throw new ArgumentNullException(nameof(repository));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public async Task Handle(OrderStartedIntegrationEvent @event)
{
await _repository.DeleteBasketAsync(@event.UserId.ToString());
using (LogContext.PushProperty("IntegrationEventId_Context", @event.Id))
{
_logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppShortName} - ({@IntegrationEvent})", @event.Id, Program.AppShortName, @event);
await _repository.DeleteBasketAsync(@event.UserId.ToString());
}
}
}
}

View File

@ -24,7 +24,7 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.IntegrationEvents.Even
public async Task Handle(ProductPriceChangedIntegrationEvent @event)
{
using (LogContext.PushProperty("IntegrationEventId", @event.Id))
using (LogContext.PushProperty("IntegrationEventId_Context", @event.Id))
{
_logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppShortName} - ({@IntegrationEvent})", @event.Id, Program.AppShortName, @event);

View File

@ -24,7 +24,7 @@ namespace Catalog.API.IntegrationEvents
public CatalogIntegrationEventService(
ILogger<CatalogIntegrationEventService> logger,
IEventBus eventBus,
IEventBus eventBus,
CatalogContext catalogContext,
Func<DbConnection, IIntegrationEventLogService> integrationEventLogServiceFactory)
{
@ -37,39 +37,33 @@ namespace Catalog.API.IntegrationEvents
public async Task PublishThroughEventBusAsync(IntegrationEvent evt)
{
using (LogContext.PushProperty("IntegrationEventId", evt.Id))
try
{
try
{
_logger.LogInformation("----- Publishing integration event: {IntegrationEventId} at {AppShortName} - ({@IntegrationEvent})", evt.Id, Program.AppShortName, evt);
_logger.LogInformation("----- Publishing integration event: {IntegrationEventId_published} at {AppShortName} - ({@IntegrationEvent})", evt.Id, Program.AppShortName, evt);
await _eventLogService.MarkEventAsInProgressAsync(evt.Id);
_eventBus.Publish(evt);
await _eventLogService.MarkEventAsPublishedAsync(evt.Id);
}
catch (Exception ex)
{
_logger.LogError(ex, "----- ERROR Publishing integration event: {IntegrationEventId} at {AppShortName} - ({@IntegrationEvent})", evt.Id, Program.AppShortName, evt);
await _eventLogService.MarkEventAsFailedAsync(evt.Id);
}
await _eventLogService.MarkEventAsInProgressAsync(evt.Id);
_eventBus.Publish(evt);
await _eventLogService.MarkEventAsPublishedAsync(evt.Id);
}
catch (Exception ex)
{
_logger.LogError(ex, "----- ERROR Publishing integration event: {IntegrationEventId} at {AppShortName} - ({@IntegrationEvent})", evt.Id, Program.AppShortName, evt);
await _eventLogService.MarkEventAsFailedAsync(evt.Id);
}
}
public async Task SaveEventAndCatalogContextChangesAsync(IntegrationEvent evt)
{
using (LogContext.PushProperty("IntegrationEventId", evt.Id))
{
_logger.LogInformation("----- CatalogIntegrationEventService - Saving changes and integrationEvent: {IntegrationEventId}", evt.Id);
_logger.LogInformation("----- CatalogIntegrationEventService - Saving changes and integrationEvent: {IntegrationEventId}", evt.Id);
//Use of an EF Core resiliency strategy when using multiple DbContexts within an explicit BeginTransaction():
//See: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency
await ResilientTransaction.New(_catalogContext).ExecuteAsync(async () =>
{
// Achieving atomicity between original catalog database operation and the IntegrationEventLog thanks to a local transaction
await _catalogContext.SaveChangesAsync();
await _eventLogService.SaveEventAsync(evt, _catalogContext.Database.CurrentTransaction.GetDbTransaction());
});
}
//Use of an EF Core resiliency strategy when using multiple DbContexts within an explicit BeginTransaction():
//See: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency
await ResilientTransaction.New(_catalogContext).ExecuteAsync(async () =>
{
// Achieving atomicity between original catalog database operation and the IntegrationEventLog thanks to a local transaction
await _catalogContext.SaveChangesAsync();
await _eventLogService.SaveEventAsync(evt, _catalogContext.Database.CurrentTransaction.GetDbTransaction());
});
}
}
}

View File

@ -8,39 +8,51 @@
using System.Linq;
using global::Catalog.API.IntegrationEvents;
using IntegrationEvents.Events;
using Serilog.Context;
using Microsoft.Extensions.Logging;
public class OrderStatusChangedToAwaitingValidationIntegrationEventHandler :
IIntegrationEventHandler<OrderStatusChangedToAwaitingValidationIntegrationEvent>
{
private readonly CatalogContext _catalogContext;
private readonly ICatalogIntegrationEventService _catalogIntegrationEventService;
private readonly ILogger<OrderStatusChangedToAwaitingValidationIntegrationEventHandler> _logger;
public OrderStatusChangedToAwaitingValidationIntegrationEventHandler(CatalogContext catalogContext,
ICatalogIntegrationEventService catalogIntegrationEventService)
public OrderStatusChangedToAwaitingValidationIntegrationEventHandler(
CatalogContext catalogContext,
ICatalogIntegrationEventService catalogIntegrationEventService,
ILogger<OrderStatusChangedToAwaitingValidationIntegrationEventHandler> logger)
{
_catalogContext = catalogContext;
_catalogIntegrationEventService = catalogIntegrationEventService;
_logger = logger ?? throw new System.ArgumentNullException(nameof(logger));
}
public async Task Handle(OrderStatusChangedToAwaitingValidationIntegrationEvent command)
public async Task Handle(OrderStatusChangedToAwaitingValidationIntegrationEvent @event)
{
var confirmedOrderStockItems = new List<ConfirmedOrderStockItem>();
foreach (var orderStockItem in command.OrderStockItems)
using (LogContext.PushProperty("IntegrationEventId_Context", @event.Id))
{
var catalogItem = _catalogContext.CatalogItems.Find(orderStockItem.ProductId);
var hasStock = catalogItem.AvailableStock >= orderStockItem.Units;
var confirmedOrderStockItem = new ConfirmedOrderStockItem(catalogItem.Id, hasStock);
_logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppShortName} - ({@IntegrationEvent})", @event.Id, Program.AppShortName, @event);
var confirmedOrderStockItems = new List<ConfirmedOrderStockItem>();
foreach (var orderStockItem in @event.OrderStockItems)
{
var catalogItem = _catalogContext.CatalogItems.Find(orderStockItem.ProductId);
var hasStock = catalogItem.AvailableStock >= orderStockItem.Units;
var confirmedOrderStockItem = new ConfirmedOrderStockItem(catalogItem.Id, hasStock);
confirmedOrderStockItems.Add(confirmedOrderStockItem);
}
var confirmedIntegrationEvent = confirmedOrderStockItems.Any(c => !c.HasStock)
? (IntegrationEvent)new OrderStockRejectedIntegrationEvent(@event.OrderId, confirmedOrderStockItems)
: new OrderStockConfirmedIntegrationEvent(@event.OrderId);
await _catalogIntegrationEventService.SaveEventAndCatalogContextChangesAsync(confirmedIntegrationEvent);
await _catalogIntegrationEventService.PublishThroughEventBusAsync(confirmedIntegrationEvent);
confirmedOrderStockItems.Add(confirmedOrderStockItem);
}
var confirmedIntegrationEvent = confirmedOrderStockItems.Any(c => !c.HasStock)
? (IntegrationEvent) new OrderStockRejectedIntegrationEvent(command.OrderId, confirmedOrderStockItems)
: new OrderStockConfirmedIntegrationEvent(command.OrderId);
await _catalogIntegrationEventService.SaveEventAndCatalogContextChangesAsync(confirmedIntegrationEvent);
await _catalogIntegrationEventService.PublishThroughEventBusAsync(confirmedIntegrationEvent);
}
}
}

View File

@ -4,28 +4,40 @@
using System.Threading.Tasks;
using Infrastructure;
using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events;
using Microsoft.Extensions.Logging;
using Serilog.Context;
public class OrderStatusChangedToPaidIntegrationEventHandler :
IIntegrationEventHandler<OrderStatusChangedToPaidIntegrationEvent>
{
private readonly CatalogContext _catalogContext;
private readonly ILogger<OrderStatusChangedToPaidIntegrationEventHandler> _logger;
public OrderStatusChangedToPaidIntegrationEventHandler(CatalogContext catalogContext)
public OrderStatusChangedToPaidIntegrationEventHandler(
CatalogContext catalogContext,
ILogger<OrderStatusChangedToPaidIntegrationEventHandler> logger)
{
_catalogContext = catalogContext;
_logger = logger ?? throw new System.ArgumentNullException(nameof(logger));
}
public async Task Handle(OrderStatusChangedToPaidIntegrationEvent command)
public async Task Handle(OrderStatusChangedToPaidIntegrationEvent @event)
{
//we're not blocking stock/inventory
foreach (var orderStockItem in command.OrderStockItems)
using (LogContext.PushProperty("IntegrationEventId_Context", @event.Id))
{
var catalogItem = _catalogContext.CatalogItems.Find(orderStockItem.ProductId);
_logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppShortName} - ({@IntegrationEvent})", @event.Id, Program.AppShortName, @event);
//we're not blocking stock/inventory
foreach (var orderStockItem in @event.OrderStockItems)
{
var catalogItem = _catalogContext.CatalogItems.Find(orderStockItem.ProductId);
catalogItem.RemoveStock(orderStockItem.Units);
}
await _catalogContext.SaveChangesAsync();
catalogItem.RemoveStock(orderStockItem.Units);
}
await _catalogContext.SaveChangesAsync();
}
}
}

View File

@ -4,6 +4,8 @@
using Marketing.API.Model;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure.Repositories;
using Microsoft.Extensions.Logging;
using Serilog.Context;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
@ -12,20 +14,29 @@
: IIntegrationEventHandler<UserLocationUpdatedIntegrationEvent>
{
private readonly IMarketingDataRepository _marketingDataRepository;
private readonly ILogger<UserLocationUpdatedIntegrationEventHandler> _logger;
public UserLocationUpdatedIntegrationEventHandler(IMarketingDataRepository repository)
public UserLocationUpdatedIntegrationEventHandler(
IMarketingDataRepository repository,
ILogger<UserLocationUpdatedIntegrationEventHandler> logger)
{
_marketingDataRepository = repository ?? throw new ArgumentNullException(nameof(repository));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public async Task Handle(UserLocationUpdatedIntegrationEvent @event)
{
var userMarketingData = await _marketingDataRepository.GetAsync(@event.UserId);
userMarketingData = userMarketingData ??
new MarketingData() { UserId = @event.UserId };
using (LogContext.PushProperty("IntegrationEventId_Context", @event.Id))
{
_logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppShortName} - ({@IntegrationEvent})", @event.Id, Program.AppShortName, @event);
userMarketingData.Locations = MapUpdatedUserLocations(@event.LocationList);
await _marketingDataRepository.UpdateLocationAsync(userMarketingData);
var userMarketingData = await _marketingDataRepository.GetAsync(@event.UserId);
userMarketingData = userMarketingData ??
new MarketingData() { UserId = @event.UserId };
userMarketingData.Locations = MapUpdatedUserLocations(@event.LocationList);
await _marketingDataRepository.UpdateLocationAsync(userMarketingData);
}
}
private List<Location> MapUpdatedUserLocations(List<UserLocationDetails> newUserLocations)

View File

@ -13,7 +13,7 @@
public class Program
{
public static readonly string AppName = typeof(Program).Namespace;
public static readonly string ShortAppName = AppName.Substring(AppName.LastIndexOf('.', AppName.LastIndexOf('.') - 1) + 1);
public static readonly string AppShortName = AppName.Substring(AppName.LastIndexOf('.', AppName.LastIndexOf('.') - 1) + 1);
public static int Main(string[] args)
{

View File

@ -7,7 +7,7 @@ namespace Ordering.API.Application.Behaviors
{
internal static class BehaviorsHelperExtensions
{
internal static string GetTypeName(this object @object)
internal static string GetGenericTypeName(this object @object)
{
var typeName = string.Empty;
var type = @object.GetType();

View File

@ -13,9 +13,9 @@ namespace Ordering.API.Application.Behaviors
public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)
{
_logger.LogInformation("----- Handling command {CommandName} ({@Command})", request.GetTypeName(), request);
_logger.LogInformation("----- Handling command {CommandName} ({@Command})", request.GetGenericTypeName(), request);
var response = await next();
_logger.LogInformation("----- Command {CommandName} handled - response: {@Response}", request.GetTypeName(), response);
_logger.LogInformation("----- Command {CommandName} handled - response: {@Response}", request.GetGenericTypeName(), response);
return response;
}

View File

@ -27,7 +27,7 @@ namespace Ordering.API.Application.Behaviors
public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)
{
TResponse response = default(TResponse);
var typeName = request.GetTypeName();
var typeName = request.GetGenericTypeName();
try
{

View File

@ -21,7 +21,7 @@ namespace Ordering.API.Application.Behaviors
public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)
{
var typeName = request.GetTypeName();
var typeName = request.GetGenericTypeName();
_logger.LogInformation("----- Validating command {CommandType}", typeName);

View File

@ -1,8 +1,11 @@
using MediatR;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.eShopOnContainers.Services.Ordering.API;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
using Microsoft.Extensions.Logging;
using Ordering.API.Application.Commands;
using Ordering.API.Application.IntegrationEvents.Events;
using Serilog.Context;
using System.Threading.Tasks;
namespace Ordering.API.Application.IntegrationEvents.EventHandling
@ -10,10 +13,14 @@ namespace Ordering.API.Application.IntegrationEvents.EventHandling
public class GracePeriodConfirmedIntegrationEventHandler : IIntegrationEventHandler<GracePeriodConfirmedIntegrationEvent>
{
private readonly IMediator _mediator;
private readonly ILogger<GracePeriodConfirmedIntegrationEventHandler> _logger;
public GracePeriodConfirmedIntegrationEventHandler(IMediator mediator)
public GracePeriodConfirmedIntegrationEventHandler(
IMediator mediator,
ILogger<GracePeriodConfirmedIntegrationEventHandler> logger)
{
_mediator = mediator;
_logger = logger ?? throw new System.ArgumentNullException(nameof(logger));
}
/// <summary>
@ -26,8 +33,13 @@ namespace Ordering.API.Application.IntegrationEvents.EventHandling
/// <returns></returns>
public async Task Handle(GracePeriodConfirmedIntegrationEvent @event)
{
var command = new SetAwaitingValidationOrderStatusCommand(@event.OrderId);
await _mediator.Send(command);
using (LogContext.PushProperty("IntegrationEventId_Context", @event.Id))
{
_logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppShortName} - ({@IntegrationEvent})", @event.Id, Program.AppShortName, @event);
var command = new SetAwaitingValidationOrderStatusCommand(@event.OrderId);
await _mediator.Send(command);
}
}
}
}

View File

@ -2,9 +2,12 @@
{
using MediatR;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.eShopOnContainers.Services.Ordering.API;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
using Microsoft.Extensions.Logging;
using Ordering.API.Application.Commands;
using Ordering.API.Application.IntegrationEvents.Events;
using Serilog.Context;
using System;
using System.Threading.Tasks;
@ -12,16 +15,25 @@
IIntegrationEventHandler<OrderPaymentFailedIntegrationEvent>
{
private readonly IMediator _mediator;
private readonly ILogger<OrderPaymentFailedIntegrationEventHandler> _logger;
public OrderPaymentFailedIntegrationEventHandler(IMediator mediator)
public OrderPaymentFailedIntegrationEventHandler(
IMediator mediator,
ILogger<OrderPaymentFailedIntegrationEventHandler> logger)
{
_mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public async Task Handle(OrderPaymentFailedIntegrationEvent @event)
{
var command = new CancelOrderCommand(@event.OrderId);
await _mediator.Send(command);
using (LogContext.PushProperty("IntegrationEventId_Context", @event.Id))
{
_logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppShortName} - ({@IntegrationEvent})", @event.Id, Program.AppShortName, @event);
var command = new CancelOrderCommand(@event.OrderId);
await _mediator.Send(command);
}
}
}
}

View File

@ -2,9 +2,12 @@
{
using MediatR;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.eShopOnContainers.Services.Ordering.API;
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
using Microsoft.Extensions.Logging;
using Ordering.API.Application.Commands;
using Ordering.API.Application.IntegrationEvents.Events;
using Serilog.Context;
using System;
using System.Threading.Tasks;
@ -12,16 +15,25 @@
IIntegrationEventHandler<OrderPaymentSuccededIntegrationEvent>
{
private readonly IMediator _mediator;
private readonly ILogger<OrderPaymentSuccededIntegrationEventHandler> _logger;
public OrderPaymentSuccededIntegrationEventHandler(IMediator mediator)
public OrderPaymentSuccededIntegrationEventHandler(
IMediator mediator,
ILogger<OrderPaymentSuccededIntegrationEventHandler> logger)
{
_mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public async Task Handle(OrderPaymentSuccededIntegrationEvent @event)
{
var command = new SetPaidOrderStatusCommand(@event.OrderId);
await _mediator.Send(command);
using (LogContext.PushProperty("IntegrationEventId_Context", @event.Id))
{
_logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppShortName} - ({@IntegrationEvent})", @event.Id, Program.AppShortName, @event);
var command = new SetPaidOrderStatusCommand(@event.OrderId);
await _mediator.Send(command);
}
}
}
}

View File

@ -7,21 +7,33 @@
using MediatR;
using System;
using Ordering.API.Application.Commands;
using Microsoft.Extensions.Logging;
using Serilog.Context;
using Microsoft.eShopOnContainers.Services.Ordering.API;
public class OrderStockConfirmedIntegrationEventHandler :
public class OrderStockConfirmedIntegrationEventHandler :
IIntegrationEventHandler<OrderStockConfirmedIntegrationEvent>
{
private readonly IMediator _mediator;
private readonly ILogger<OrderStockConfirmedIntegrationEventHandler> _logger;
public OrderStockConfirmedIntegrationEventHandler(IMediator mediator)
public OrderStockConfirmedIntegrationEventHandler(
IMediator mediator,
ILogger<OrderStockConfirmedIntegrationEventHandler> logger)
{
_mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public async Task Handle(OrderStockConfirmedIntegrationEvent @event)
{
var command = new SetStockConfirmedOrderStatusCommand(@event.OrderId);
await _mediator.Send(command);
using (LogContext.PushProperty("IntegrationEventId_Context", @event.Id))
{
_logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppShortName} - ({@IntegrationEvent})", @event.Id, Program.AppShortName, @event);
var command = new SetStockConfirmedOrderStatusCommand(@event.OrderId);
await _mediator.Send(command);
}
}
}
}

View File

@ -7,25 +7,37 @@
using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate;
using MediatR;
using Ordering.API.Application.Commands;
using Microsoft.Extensions.Logging;
using Serilog.Context;
using Microsoft.eShopOnContainers.Services.Ordering.API;
public class OrderStockRejectedIntegrationEventHandler : IIntegrationEventHandler<OrderStockRejectedIntegrationEvent>
{
private readonly IMediator _mediator;
private readonly ILogger<OrderStockRejectedIntegrationEventHandler> _logger;
public OrderStockRejectedIntegrationEventHandler(IMediator mediator)
public OrderStockRejectedIntegrationEventHandler(
IMediator mediator,
ILogger<OrderStockRejectedIntegrationEventHandler> logger)
{
_mediator = mediator;
_logger = logger ?? throw new System.ArgumentNullException(nameof(logger));
}
public async Task Handle(OrderStockRejectedIntegrationEvent @event)
{
var orderStockRejectedItems = @event.OrderStockItems
.FindAll(c => !c.HasStock)
.Select(c => c.ProductId)
.ToList();
using (LogContext.PushProperty("IntegrationEventId_Context", @event.Id))
{
_logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppShortName} - ({@IntegrationEvent})", @event.Id, Program.AppShortName, @event);
var command = new SetStockRejectedOrderStatusCommand(@event.OrderId, orderStockRejectedItems);
await _mediator.Send(command);
var orderStockRejectedItems = @event.OrderStockItems
.FindAll(c => !c.HasStock)
.Select(c => c.ProductId)
.ToList();
var command = new SetStockRejectedOrderStatusCommand(@event.OrderId, orderStockRejectedItems);
await _mediator.Send(command);
}
}
}
}

View File

@ -26,30 +26,30 @@ namespace Ordering.API.Application.IntegrationEvents.EventHandling
/// <summary>
/// Integration event handler which starts the create order process
/// </summary>
/// <param name="eventMsg">
/// <param name="@event">
/// Integration event message which is sent by the
/// basket.api once it has successfully process the
/// order items.
/// </param>
/// <returns></returns>
public async Task Handle(UserCheckoutAcceptedIntegrationEvent eventMsg)
public async Task Handle(UserCheckoutAcceptedIntegrationEvent @event)
{
using (LogContext.PushProperty("IntegrationEventId", eventMsg.Id))
using (LogContext.PushProperty("IntegrationEventId_Context", @event.Id))
{
_logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppShortName} - ({@IntegrationEvent})", eventMsg.Id, Program.AppShortName, eventMsg);
_logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppShortName} - ({@IntegrationEvent})", @event.Id, Program.AppShortName, @event);
var result = false;
if (eventMsg.RequestId != Guid.Empty)
if (@event.RequestId != Guid.Empty)
{
using (LogContext.PushProperty("IdentifiedCommandId", eventMsg.RequestId))
using (LogContext.PushProperty("IdentifiedCommandId", @event.RequestId))
{
var createOrderCommand = new CreateOrderCommand(eventMsg.Basket.Items, eventMsg.UserId, eventMsg.UserName, eventMsg.City, eventMsg.Street,
eventMsg.State, eventMsg.Country, eventMsg.ZipCode,
eventMsg.CardNumber, eventMsg.CardHolderName, eventMsg.CardExpiration,
eventMsg.CardSecurityNumber, eventMsg.CardTypeId);
var createOrderCommand = new CreateOrderCommand(@event.Basket.Items, @event.UserId, @event.UserName, @event.City, @event.Street,
@event.State, @event.Country, @event.ZipCode,
@event.CardNumber, @event.CardHolderName, @event.CardExpiration,
@event.CardSecurityNumber, @event.CardTypeId);
var requestCreateOrder = new IdentifiedCommand<CreateOrderCommand, bool>(createOrderCommand, eventMsg.RequestId);
var requestCreateOrder = new IdentifiedCommand<CreateOrderCommand, bool>(createOrderCommand, @event.RequestId);
_logger.LogInformation("----- IdentifiedCreateOrderCommand: {@IdentifiedCreateOrderCommand}", requestCreateOrder);
@ -57,17 +57,17 @@ namespace Ordering.API.Application.IntegrationEvents.EventHandling
if (result)
{
_logger.LogInformation("----- CreateOrderCommand suceeded - RequestId: {RequestId}", eventMsg.RequestId);
_logger.LogInformation("----- CreateOrderCommand suceeded - RequestId: {RequestId}", @event.RequestId);
}
else
{
_logger.LogWarning("----- CreateOrderCommand failed - RequestId: {RequestId}", eventMsg.RequestId);
_logger.LogWarning("----- CreateOrderCommand failed - RequestId: {RequestId}", @event.RequestId);
}
}
}
else
{
_logger.LogWarning("----- Invalid IntegrationEvent - RequestId is missing - {@IntegrationEvent}", eventMsg);
_logger.LogWarning("----- Invalid IntegrationEvent - RequestId is missing - {@IntegrationEvent}", @event);
}
}
}

View File

@ -5,6 +5,7 @@ using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF;
using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services;
using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Utilities;
using Microsoft.eShopOnContainers.Services.Ordering.API;
using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure;
using Microsoft.Extensions.Logging;
using System;
@ -44,7 +45,7 @@ namespace Ordering.API.Application.IntegrationEvents
foreach (var logEvt in pendindLogEvents)
{
_logger.LogInformation("----- Publishing integration event {IntegrationEventId} ({@IntegrationEvent})", logEvt.EventId, logEvt);
_logger.LogInformation("----- Publishing integration event: {IntegrationEventId} at {AppShortName} - ({@IntegrationEvent})", logEvt.EventId, Program.AppShortName, logEvt);
try
{

View File

@ -1,6 +1,8 @@
using Microsoft.AspNetCore.SignalR;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.Extensions.Logging;
using Ordering.SignalrHub.IntegrationEvents.Events;
using Serilog.Context;
using System;
using System.Collections.Generic;
using System.Linq;
@ -11,18 +13,27 @@ namespace Ordering.SignalrHub.IntegrationEvents.EventHandling
public class OrderStatusChangedToCancelledIntegrationEventHandler : IIntegrationEventHandler<OrderStatusChangedToCancelledIntegrationEvent>
{
private readonly IHubContext<NotificationsHub> _hubContext;
private readonly ILogger<OrderStatusChangedToCancelledIntegrationEventHandler> _logger;
public OrderStatusChangedToCancelledIntegrationEventHandler(IHubContext<NotificationsHub> hubContext)
public OrderStatusChangedToCancelledIntegrationEventHandler(
IHubContext<NotificationsHub> hubContext,
ILogger<OrderStatusChangedToCancelledIntegrationEventHandler> logger)
{
_hubContext = hubContext ?? throw new ArgumentNullException(nameof(hubContext));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public async Task Handle(OrderStatusChangedToCancelledIntegrationEvent @event)
{
await _hubContext.Clients
.Group(@event.BuyerName)
.SendAsync("UpdatedOrderState", new { OrderId = @event.OrderId, Status = @event.OrderStatus });
using (LogContext.PushProperty("IntegrationEventId_Context", @event.Id))
{
_logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppShortName} - ({@IntegrationEvent})", @event.Id, Program.AppShortName, @event);
await _hubContext.Clients
.Group(@event.BuyerName)
.SendAsync("UpdatedOrderState", new { OrderId = @event.OrderId, Status = @event.OrderStatus });
}
}
}
}

View File

@ -1,6 +1,8 @@
using Microsoft.AspNetCore.SignalR;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.Extensions.Logging;
using Ordering.SignalrHub.IntegrationEvents.Events;
using Serilog.Context;
using System;
using System.Threading.Tasks;
@ -9,18 +11,27 @@ namespace Ordering.SignalrHub.IntegrationEvents.EventHandling
public class OrderStatusChangedToPaidIntegrationEventHandler : IIntegrationEventHandler<OrderStatusChangedToPaidIntegrationEvent>
{
private readonly IHubContext<NotificationsHub> _hubContext;
private readonly ILogger<OrderStatusChangedToPaidIntegrationEventHandler> _logger;
public OrderStatusChangedToPaidIntegrationEventHandler(IHubContext<NotificationsHub> hubContext)
public OrderStatusChangedToPaidIntegrationEventHandler(
IHubContext<NotificationsHub> hubContext,
ILogger<OrderStatusChangedToPaidIntegrationEventHandler> logger)
{
_hubContext = hubContext ?? throw new ArgumentNullException(nameof(hubContext));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public async Task Handle(OrderStatusChangedToPaidIntegrationEvent @event)
{
await _hubContext.Clients
.Group(@event.BuyerName)
.SendAsync("UpdatedOrderState", new { OrderId = @event.OrderId, Status = @event.OrderStatus });
using (LogContext.PushProperty("IntegrationEventId_Context", @event.Id))
{
_logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppShortName} - ({@IntegrationEvent})", @event.Id, Program.AppShortName, @event);
await _hubContext.Clients
.Group(@event.BuyerName)
.SendAsync("UpdatedOrderState", new { OrderId = @event.OrderId, Status = @event.OrderStatus });
}
}
}
}

View File

@ -1,6 +1,8 @@
using Microsoft.AspNetCore.SignalR;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.Extensions.Logging;
using Ordering.SignalrHub.IntegrationEvents.Events;
using Serilog.Context;
using System;
using System.Collections.Generic;
using System.Linq;
@ -11,18 +13,27 @@ namespace Ordering.SignalrHub.IntegrationEvents.EventHandling
public class OrderStatusChangedToShippedIntegrationEventHandler : IIntegrationEventHandler<OrderStatusChangedToShippedIntegrationEvent>
{
private readonly IHubContext<NotificationsHub> _hubContext;
private readonly ILogger<OrderStatusChangedToShippedIntegrationEventHandler> _logger;
public OrderStatusChangedToShippedIntegrationEventHandler(IHubContext<NotificationsHub> hubContext)
public OrderStatusChangedToShippedIntegrationEventHandler(
IHubContext<NotificationsHub> hubContext,
ILogger<OrderStatusChangedToShippedIntegrationEventHandler> logger)
{
_hubContext = hubContext ?? throw new ArgumentNullException(nameof(hubContext));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public async Task Handle(OrderStatusChangedToShippedIntegrationEvent @event)
{
await _hubContext.Clients
.Group(@event.BuyerName)
.SendAsync("UpdatedOrderState", new { OrderId = @event.OrderId, Status = @event.OrderStatus });
using (LogContext.PushProperty("IntegrationEventId_Context", @event.Id))
{
_logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppShortName} - ({@IntegrationEvent})", @event.Id, Program.AppShortName, @event);
await _hubContext.Clients
.Group(@event.BuyerName)
.SendAsync("UpdatedOrderState", new { OrderId = @event.OrderId, Status = @event.OrderStatus });
}
}
}
}

View File

@ -1,6 +1,8 @@
using Microsoft.AspNetCore.SignalR;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.Extensions.Logging;
using Ordering.SignalrHub.IntegrationEvents.Events;
using Serilog.Context;
using System;
using System.Collections.Generic;
using System.Linq;
@ -12,18 +14,27 @@ namespace Ordering.SignalrHub.IntegrationEvents.EventHandling
IIntegrationEventHandler<OrderStatusChangedToStockConfirmedIntegrationEvent>
{
private readonly IHubContext<NotificationsHub> _hubContext;
private readonly ILogger<OrderStatusChangedToStockConfirmedIntegrationEventHandler> _logger;
public OrderStatusChangedToStockConfirmedIntegrationEventHandler(IHubContext<NotificationsHub> hubContext)
public OrderStatusChangedToStockConfirmedIntegrationEventHandler(
IHubContext<NotificationsHub> hubContext,
ILogger<OrderStatusChangedToStockConfirmedIntegrationEventHandler> logger)
{
_hubContext = hubContext ?? throw new ArgumentNullException(nameof(hubContext));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public async Task Handle(OrderStatusChangedToStockConfirmedIntegrationEvent @event)
{
await _hubContext.Clients
.Group(@event.BuyerName)
.SendAsync("UpdatedOrderState", new { OrderId = @event.OrderId, Status = @event.OrderStatus });
using (LogContext.PushProperty("IntegrationEventId_Context", @event.Id))
{
_logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppShortName} - ({@IntegrationEvent})", @event.Id, Program.AppShortName, @event);
await _hubContext.Clients
.Group(@event.BuyerName)
.SendAsync("UpdatedOrderState", new { OrderId = @event.OrderId, Status = @event.OrderStatus });
}
}
}
}

View File

@ -1,6 +1,8 @@
using Microsoft.AspNetCore.SignalR;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.Extensions.Logging;
using Ordering.SignalrHub.IntegrationEvents.Events;
using Serilog.Context;
using System;
using System.Collections.Generic;
using System.Linq;
@ -12,18 +14,27 @@ namespace Ordering.SignalrHub.IntegrationEvents.EventHandling
IIntegrationEventHandler<OrderStatusChangedToSubmittedIntegrationEvent>
{
private readonly IHubContext<NotificationsHub> _hubContext;
private readonly ILogger<OrderStatusChangedToSubmittedIntegrationEventHandler> _logger;
public OrderStatusChangedToSubmittedIntegrationEventHandler(IHubContext<NotificationsHub> hubContext)
public OrderStatusChangedToSubmittedIntegrationEventHandler(
IHubContext<NotificationsHub> hubContext,
ILogger<OrderStatusChangedToSubmittedIntegrationEventHandler> logger)
{
_hubContext = hubContext ?? throw new ArgumentNullException(nameof(hubContext));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public async Task Handle(OrderStatusChangedToSubmittedIntegrationEvent @event)
{
await _hubContext.Clients
.Group(@event.BuyerName)
.SendAsync("UpdatedOrderState", new { OrderId = @event.OrderId, Status = @event.OrderStatus });
using (LogContext.PushProperty("IntegrationEventId_Context", @event.Id))
{
_logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppShortName} - ({@IntegrationEvent})", @event.Id, Program.AppShortName, @event);
await _hubContext.Clients
.Group(@event.BuyerName)
.SendAsync("UpdatedOrderState", new { OrderId = @event.OrderId, Status = @event.OrderStatus });
}
}
}
}

View File

@ -1,5 +1,7 @@
using Microsoft.AspNetCore.SignalR;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.Extensions.Logging;
using Serilog.Context;
using System;
using System.Collections.Generic;
using System.Linq;
@ -10,18 +12,27 @@ namespace Ordering.SignalrHub.IntegrationEvents
public class OrderStatusChangedToAwaitingValidationIntegrationEventHandler : IIntegrationEventHandler<OrderStatusChangedToAwaitingValidationIntegrationEvent>
{
private readonly IHubContext<NotificationsHub> _hubContext;
private readonly ILogger<OrderStatusChangedToAwaitingValidationIntegrationEventHandler> _logger;
public OrderStatusChangedToAwaitingValidationIntegrationEventHandler(IHubContext<NotificationsHub> hubContext)
public OrderStatusChangedToAwaitingValidationIntegrationEventHandler(
IHubContext<NotificationsHub> hubContext,
ILogger<OrderStatusChangedToAwaitingValidationIntegrationEventHandler> logger)
{
_hubContext = hubContext ?? throw new ArgumentNullException(nameof(hubContext));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public async Task Handle(OrderStatusChangedToAwaitingValidationIntegrationEvent @event)
{
await _hubContext.Clients
.Group(@event.BuyerName)
.SendAsync("UpdatedOrderState", new { OrderId = @event.OrderId, Status = @event.OrderStatus });
using (LogContext.PushProperty("IntegrationEventId_Context", @event.Id))
{
_logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppShortName} - ({@IntegrationEvent})", @event.Id, Program.AppShortName, @event);
await _hubContext.Clients
.Group(@event.BuyerName)
.SendAsync("UpdatedOrderState", new { OrderId = @event.OrderId, Status = @event.OrderStatus });
}
}
}
}

View File

@ -2,45 +2,56 @@
{
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions;
using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Payment.API.IntegrationEvents.Events;
using Serilog.Context;
using System.Threading.Tasks;
public class OrderStatusChangedToStockConfirmedIntegrationEventHandler :
public class OrderStatusChangedToStockConfirmedIntegrationEventHandler :
IIntegrationEventHandler<OrderStatusChangedToStockConfirmedIntegrationEvent>
{
private readonly IEventBus _eventBus;
private readonly PaymentSettings _settings;
private readonly ILogger<OrderStatusChangedToStockConfirmedIntegrationEventHandler> _logger;
public OrderStatusChangedToStockConfirmedIntegrationEventHandler(IEventBus eventBus,
IOptionsSnapshot<PaymentSettings> settings)
public OrderStatusChangedToStockConfirmedIntegrationEventHandler(
IEventBus eventBus,
IOptionsSnapshot<PaymentSettings> settings,
ILogger<OrderStatusChangedToStockConfirmedIntegrationEventHandler> logger)
{
_eventBus = eventBus;
_settings = settings.Value;
}
_logger = logger ?? throw new System.ArgumentNullException(nameof(logger));
}
public async Task Handle(OrderStatusChangedToStockConfirmedIntegrationEvent @event)
{
IntegrationEvent orderPaymentIntegrationEvent;
//Business feature comment:
// When OrderStatusChangedToStockConfirmed Integration Event is handled.
// Here we're simulating that we'd be performing the payment against any payment gateway
// Instead of a real payment we just take the env. var to simulate the payment
// The payment can be successful or it can fail
if (_settings.PaymentSucceded)
using (LogContext.PushProperty("IntegrationEventId_Context", @event.Id))
{
orderPaymentIntegrationEvent = new OrderPaymentSuccededIntegrationEvent(@event.OrderId);
}
else
{
orderPaymentIntegrationEvent = new OrderPaymentFailedIntegrationEvent(@event.OrderId);
}
_logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppShortName} - ({@IntegrationEvent})", @event.Id, Program.AppShortName, @event);
_eventBus.Publish(orderPaymentIntegrationEvent);
IntegrationEvent orderPaymentIntegrationEvent;
await Task.CompletedTask;
//Business feature comment:
// When OrderStatusChangedToStockConfirmed Integration Event is handled.
// Here we're simulating that we'd be performing the payment against any payment gateway
// Instead of a real payment we just take the env. var to simulate the payment
// The payment can be successful or it can fail
if (_settings.PaymentSucceded)
{
orderPaymentIntegrationEvent = new OrderPaymentSuccededIntegrationEvent(@event.OrderId);
}
else
{
orderPaymentIntegrationEvent = new OrderPaymentFailedIntegrationEvent(@event.OrderId);
}
_eventBus.Publish(orderPaymentIntegrationEvent);
await Task.CompletedTask;
}
}
}
}

View File

@ -12,7 +12,7 @@ namespace Payment.API
public class Program
{
public static readonly string AppName = typeof(Program).Namespace;
public static readonly string ShortAppName = AppName.Substring(AppName.LastIndexOf('.', AppName.LastIndexOf('.') - 1) + 1);
public static readonly string AppShortName = AppName.Substring(AppName.LastIndexOf('.', AppName.LastIndexOf('.') - 1) + 1);
public static int Main(string[] args)
{