diff --git a/src/Services/Catalog/Catalog.API/Catalog.API.csproj b/src/Services/Catalog/Catalog.API/Catalog.API.csproj index 983cc291a..05b026a36 100644 --- a/src/Services/Catalog/Catalog.API/Catalog.API.csproj +++ b/src/Services/Catalog/Catalog.API/Catalog.API.csproj @@ -40,6 +40,10 @@ + + + + @@ -58,10 +62,6 @@ - - - - diff --git a/src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs b/src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs index d9fa4002e..48ed87eef 100644 --- a/src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs +++ b/src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs @@ -1,5 +1,4 @@ -using Catalog.API.IntegrationEvents; -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure; using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events; @@ -11,6 +10,7 @@ using System.Collections.Generic; using System.Linq; using System.Net; using System.Threading.Tasks; +using DotNetCore.CAP; namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers { @@ -20,12 +20,12 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers { private readonly CatalogContext _catalogContext; private readonly CatalogSettings _settings; - private readonly ICatalogIntegrationEventService _catalogIntegrationEventService; + private readonly ICapPublisher _eventBus; - public CatalogController(CatalogContext context, IOptionsSnapshot settings, ICatalogIntegrationEventService catalogIntegrationEventService) + public CatalogController(CatalogContext context, IOptionsSnapshot settings, ICapPublisher eventBus) { _catalogContext = context ?? throw new ArgumentNullException(nameof(context)); - _catalogIntegrationEventService = catalogIntegrationEventService ?? throw new ArgumentNullException(nameof(catalogIntegrationEventService)); + _eventBus = eventBus ?? throw new ArgumentNullException(nameof(eventBus)); _settings = settings.Value; context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; @@ -233,10 +233,10 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers var priceChangedEvent = new ProductPriceChangedIntegrationEvent(catalogItem.Id, productToUpdate.Price, oldPrice); // Achieving atomicity between original Catalog database operation and the IntegrationEventLog thanks to a local transaction - await _catalogIntegrationEventService.SaveEventAndCatalogContextChangesAsync(priceChangedEvent); - - // Publish through the Event Bus and mark the saved event as published - await _catalogIntegrationEventService.PublishThroughEventBusAsync(priceChangedEvent); + using (_catalogContext.Database.BeginTransaction(_eventBus, autoCommit: true)) + { + _eventBus.Publish(nameof(ProductPriceChangedIntegrationEvent), priceChangedEvent); + } } else // Just save the updated product because the Product's Price hasn't changed. { diff --git a/src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/20170316120022_RefactoringEventBusNamespaces.Designer.cs b/src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/20170316120022_RefactoringEventBusNamespaces.Designer.cs index 52c5d7879..1daf632c0 100644 --- a/src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/20170316120022_RefactoringEventBusNamespaces.Designer.cs +++ b/src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/20170316120022_RefactoringEventBusNamespaces.Designer.cs @@ -4,7 +4,6 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure; -using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; namespace Catalog.API.Infrastructure.Migrations { diff --git a/src/Services/Catalog/Catalog.API/Infrastructure/IntegrationEventMigrations/20170322145434_IntegrationEventInitial.Designer.cs b/src/Services/Catalog/Catalog.API/Infrastructure/IntegrationEventMigrations/20170322145434_IntegrationEventInitial.Designer.cs deleted file mode 100644 index a3cdeb53f..000000000 --- a/src/Services/Catalog/Catalog.API/Infrastructure/IntegrationEventMigrations/20170322145434_IntegrationEventInitial.Designer.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF; - -namespace Catalog.API.Migrations -{ - [DbContext(typeof(IntegrationEventLogContext))] - [Migration("20170322145434_IntegrationEventInitial")] - partial class IntegrationEventInitial - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { - modelBuilder - .HasAnnotation("ProductVersion", "1.1.1") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - modelBuilder.Entity("Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.IntegrationEventLogEntry", b => - { - b.Property("EventId") - .ValueGeneratedOnAdd(); - - b.Property("Content") - .IsRequired(); - - b.Property("CreationTime"); - - b.Property("EventTypeName") - .IsRequired(); - - b.Property("State"); - - b.Property("TimesSent"); - - b.HasKey("EventId"); - - b.ToTable("IntegrationEventLog"); - }); - } - } -} diff --git a/src/Services/Catalog/Catalog.API/Infrastructure/IntegrationEventMigrations/20170322145434_IntegrationEventInitial.cs b/src/Services/Catalog/Catalog.API/Infrastructure/IntegrationEventMigrations/20170322145434_IntegrationEventInitial.cs deleted file mode 100644 index fff1ad04c..000000000 --- a/src/Services/Catalog/Catalog.API/Infrastructure/IntegrationEventMigrations/20170322145434_IntegrationEventInitial.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Collections.Generic; -using Microsoft.EntityFrameworkCore.Migrations; - -namespace Catalog.API.Migrations -{ - public partial class IntegrationEventInitial : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "IntegrationEventLog", - columns: table => new - { - EventId = table.Column(nullable: false), - Content = table.Column(nullable: false), - CreationTime = table.Column(nullable: false), - EventTypeName = table.Column(nullable: false), - State = table.Column(nullable: false), - TimesSent = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_IntegrationEventLog", x => x.EventId); - }); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "IntegrationEventLog"); - } - } -} diff --git a/src/Services/Catalog/Catalog.API/Infrastructure/IntegrationEventMigrations/IntegrationEventLogContextModelSnapshot.cs b/src/Services/Catalog/Catalog.API/Infrastructure/IntegrationEventMigrations/IntegrationEventLogContextModelSnapshot.cs deleted file mode 100644 index ab2414bb5..000000000 --- a/src/Services/Catalog/Catalog.API/Infrastructure/IntegrationEventMigrations/IntegrationEventLogContextModelSnapshot.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF; - -namespace Catalog.API.Migrations -{ - [DbContext(typeof(IntegrationEventLogContext))] - partial class IntegrationEventLogContextModelSnapshot : ModelSnapshot - { - protected override void BuildModel(ModelBuilder modelBuilder) - { - modelBuilder - .HasAnnotation("ProductVersion", "1.1.1") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - modelBuilder.Entity("Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.IntegrationEventLogEntry", b => - { - b.Property("EventId") - .ValueGeneratedOnAdd(); - - b.Property("Content") - .IsRequired(); - - b.Property("CreationTime"); - - b.Property("EventTypeName") - .IsRequired(); - - b.Property("State"); - - b.Property("TimesSent"); - - b.HasKey("EventId"); - - b.ToTable("IntegrationEventLog"); - }); - } - } -} diff --git a/src/Services/Catalog/Catalog.API/IntegrationEvents/CatalogIntegrationEventService.cs b/src/Services/Catalog/Catalog.API/IntegrationEvents/CatalogIntegrationEventService.cs deleted file mode 100644 index 3b9476b9f..000000000 --- a/src/Services/Catalog/Catalog.API/IntegrationEvents/CatalogIntegrationEventService.cs +++ /dev/null @@ -1,69 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Storage; -using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; -using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; -using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services; -using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Utilities; -using Microsoft.eShopOnContainers.Services.Catalog.API; -using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure; -using Microsoft.Extensions.Logging; -using Serilog.Context; -using System; -using System.Data.Common; -using System.Threading.Tasks; - -namespace Catalog.API.IntegrationEvents -{ - public class CatalogIntegrationEventService : ICatalogIntegrationEventService - { - private readonly Func _integrationEventLogServiceFactory; - private readonly IEventBus _eventBus; - private readonly CatalogContext _catalogContext; - private readonly IIntegrationEventLogService _eventLogService; - private readonly ILogger _logger; - - public CatalogIntegrationEventService( - ILogger logger, - IEventBus eventBus, - CatalogContext catalogContext, - Func integrationEventLogServiceFactory) - { - _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - _catalogContext = catalogContext ?? throw new ArgumentNullException(nameof(catalogContext)); - _integrationEventLogServiceFactory = integrationEventLogServiceFactory ?? throw new ArgumentNullException(nameof(integrationEventLogServiceFactory)); - _eventBus = eventBus ?? throw new ArgumentNullException(nameof(eventBus)); - _eventLogService = _integrationEventLogServiceFactory(_catalogContext.Database.GetDbConnection()); - } - - public async Task PublishThroughEventBusAsync(IntegrationEvent evt) - { - try - { - _logger.LogInformation("----- Publishing integration event: {IntegrationEventId_published} from {AppName} - ({@IntegrationEvent})", evt.Id, Program.AppName, 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} from {AppName} - ({@IntegrationEvent})", evt.Id, Program.AppName, evt); - await _eventLogService.MarkEventAsFailedAsync(evt.Id); - } - } - - public async Task SaveEventAndCatalogContextChangesAsync(IntegrationEvent evt) - { - _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()); - }); - } - } -} diff --git a/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs b/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs index 493a271cc..062347f6f 100644 --- a/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs +++ b/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToAwaitingValidationIntegrationEventHandler.cs @@ -1,39 +1,36 @@ -namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.EventHandling +using DotNetCore.CAP; + +namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.EventHandling { - using BuildingBlocks.EventBus.Abstractions; using System.Threading.Tasks; - using BuildingBlocks.EventBus.Events; using Infrastructure; using System.Collections.Generic; using System.Linq; - using global::Catalog.API.IntegrationEvents; - using IntegrationEvents.Events; + using Events; using Serilog.Context; - using Microsoft.Extensions.Logging; + using Extensions.Logging; - public class OrderStatusChangedToAwaitingValidationIntegrationEventHandler : - IIntegrationEventHandler + public class OrderStatusChangedToAwaitingValidationIntegrationEventHandler : ICapSubscribe { private readonly CatalogContext _catalogContext; - private readonly ICatalogIntegrationEventService _catalogIntegrationEventService; + private readonly ICapPublisher _eventBus; private readonly ILogger _logger; public OrderStatusChangedToAwaitingValidationIntegrationEventHandler( CatalogContext catalogContext, - ICatalogIntegrationEventService catalogIntegrationEventService, + ICapPublisher eventBus, ILogger logger) { _catalogContext = catalogContext; - _catalogIntegrationEventService = catalogIntegrationEventService; + _eventBus = eventBus; _logger = logger ?? throw new System.ArgumentNullException(nameof(logger)); } + //TODO: [CapSubscribe(nameof(OrderStatusChangedToAwaitingValidationIntegrationEvent))] public async Task Handle(OrderStatusChangedToAwaitingValidationIntegrationEvent @event) { - using (LogContext.PushProperty("IntegrationEventContext", $"{@event.Id}-{Program.AppName}")) + using (LogContext.PushProperty("IntegrationEventContext", $"{Program.AppName}")) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); - var confirmedOrderStockItems = new List(); foreach (var orderStockItem in @event.OrderStockItems) @@ -43,15 +40,18 @@ 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); + } + if (confirmedOrderStockItems.Any(c => !c.HasStock)) + { + await _eventBus.PublishAsync(nameof(OrderStockRejectedIntegrationEvent), + new OrderStockRejectedIntegrationEvent(@event.OrderId, confirmedOrderStockItems)); + } + else + { + await _eventBus.PublishAsync(nameof(OrderStockConfirmedIntegrationEvent), + new OrderStockConfirmedIntegrationEvent(@event.OrderId)); + } } } } diff --git a/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs b/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs index 7d383254f..20f84175b 100644 --- a/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs +++ b/src/Services/Catalog/Catalog.API/IntegrationEvents/EventHandling/OrderStatusChangedToPaidIntegrationEventHandler.cs @@ -1,14 +1,15 @@ -namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.EventHandling +using DotNetCore.CAP; + +namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.EventHandling { - using BuildingBlocks.EventBus.Abstractions; using System.Threading.Tasks; using Infrastructure; - using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events; - using Microsoft.Extensions.Logging; + using Events; + using Extensions.Logging; using Serilog.Context; - public class OrderStatusChangedToPaidIntegrationEventHandler : - IIntegrationEventHandler + //OrderStatusChangedToPaidIntegrationEvent + public class OrderStatusChangedToPaidIntegrationEventHandler : ICapSubscribe { private readonly CatalogContext _catalogContext; private readonly ILogger _logger; @@ -21,11 +22,12 @@ _logger = logger ?? throw new System.ArgumentNullException(nameof(logger)); } + //TODO: [CapSubscribe(nameof(OrderStatusChangedToPaidIntegrationEvent))] public async Task Handle(OrderStatusChangedToPaidIntegrationEvent @event) { - using (LogContext.PushProperty("IntegrationEventContext", $"{@event.Id}-{Program.AppName}")) + using (LogContext.PushProperty("IntegrationEventContext", $"{Program.AppName}")) { - _logger.LogInformation("----- Handling integration event: {IntegrationEventId} at {AppName} - ({@IntegrationEvent})", @event.Id, Program.AppName, @event); + _logger.LogInformation("----- Handling integration event: {AppName} - ({@IntegrationEvent})", Program.AppName, @event); //we're not blocking stock/inventory foreach (var orderStockItem in @event.OrderStockItems) @@ -36,7 +38,6 @@ } await _catalogContext.SaveChangesAsync(); - } } } diff --git a/src/Services/Catalog/Catalog.API/IntegrationEvents/Events/OrderStatusChangedToAwaitingValidationIntegrationEvent.cs b/src/Services/Catalog/Catalog.API/IntegrationEvents/Events/OrderStatusChangedToAwaitingValidationIntegrationEvent.cs index 9787aaedd..658da7e7b 100644 --- a/src/Services/Catalog/Catalog.API/IntegrationEvents/Events/OrderStatusChangedToAwaitingValidationIntegrationEvent.cs +++ b/src/Services/Catalog/Catalog.API/IntegrationEvents/Events/OrderStatusChangedToAwaitingValidationIntegrationEvent.cs @@ -1,9 +1,8 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events { - using BuildingBlocks.EventBus.Events; using System.Collections.Generic; - public class OrderStatusChangedToAwaitingValidationIntegrationEvent : IntegrationEvent + public class OrderStatusChangedToAwaitingValidationIntegrationEvent { public int OrderId { get; } public IEnumerable OrderStockItems { get; } diff --git a/src/Services/Catalog/Catalog.API/IntegrationEvents/Events/OrderStatusChangedToPaidIntegrationEvent.cs b/src/Services/Catalog/Catalog.API/IntegrationEvents/Events/OrderStatusChangedToPaidIntegrationEvent.cs index 881aa21fe..55900b171 100644 --- a/src/Services/Catalog/Catalog.API/IntegrationEvents/Events/OrderStatusChangedToPaidIntegrationEvent.cs +++ b/src/Services/Catalog/Catalog.API/IntegrationEvents/Events/OrderStatusChangedToPaidIntegrationEvent.cs @@ -1,9 +1,8 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events { using System.Collections.Generic; - using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; - public class OrderStatusChangedToPaidIntegrationEvent : IntegrationEvent + public class OrderStatusChangedToPaidIntegrationEvent { public int OrderId { get; } public IEnumerable OrderStockItems { get; } diff --git a/src/Services/Catalog/Catalog.API/IntegrationEvents/Events/OrderStockConfirmedIntegrationEvent.cs b/src/Services/Catalog/Catalog.API/IntegrationEvents/Events/OrderStockConfirmedIntegrationEvent.cs index b91eaae43..6c6d6505d 100644 --- a/src/Services/Catalog/Catalog.API/IntegrationEvents/Events/OrderStockConfirmedIntegrationEvent.cs +++ b/src/Services/Catalog/Catalog.API/IntegrationEvents/Events/OrderStockConfirmedIntegrationEvent.cs @@ -1,8 +1,6 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events { - using BuildingBlocks.EventBus.Events; - - public class OrderStockConfirmedIntegrationEvent : IntegrationEvent + public class OrderStockConfirmedIntegrationEvent { public int OrderId { get; } diff --git a/src/Services/Catalog/Catalog.API/IntegrationEvents/Events/OrderStockRejectedIntegrationEvent.cs b/src/Services/Catalog/Catalog.API/IntegrationEvents/Events/OrderStockRejectedIntegrationEvent.cs index eb74af8dd..3f92c5e95 100644 --- a/src/Services/Catalog/Catalog.API/IntegrationEvents/Events/OrderStockRejectedIntegrationEvent.cs +++ b/src/Services/Catalog/Catalog.API/IntegrationEvents/Events/OrderStockRejectedIntegrationEvent.cs @@ -1,9 +1,8 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events { - using BuildingBlocks.EventBus.Events; using System.Collections.Generic; - public class OrderStockRejectedIntegrationEvent : IntegrationEvent + public class OrderStockRejectedIntegrationEvent { public int OrderId { get; } diff --git a/src/Services/Catalog/Catalog.API/IntegrationEvents/Events/ProductPriceChangedIntegrationEvent.cs b/src/Services/Catalog/Catalog.API/IntegrationEvents/Events/ProductPriceChangedIntegrationEvent.cs index 7c14a07d1..994edd505 100644 --- a/src/Services/Catalog/Catalog.API/IntegrationEvents/Events/ProductPriceChangedIntegrationEvent.cs +++ b/src/Services/Catalog/Catalog.API/IntegrationEvents/Events/ProductPriceChangedIntegrationEvent.cs @@ -1,11 +1,9 @@ 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. - public class ProductPriceChangedIntegrationEvent : IntegrationEvent + public class ProductPriceChangedIntegrationEvent { public int ProductId { get; private set; } diff --git a/src/Services/Catalog/Catalog.API/IntegrationEvents/ICatalogIntegrationEventService.cs b/src/Services/Catalog/Catalog.API/IntegrationEvents/ICatalogIntegrationEventService.cs deleted file mode 100644 index 4d87e8e94..000000000 --- a/src/Services/Catalog/Catalog.API/IntegrationEvents/ICatalogIntegrationEventService.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; -using System.Threading.Tasks; - -namespace Catalog.API.IntegrationEvents -{ - public interface ICatalogIntegrationEventService - { - Task SaveEventAndCatalogContextChangesAsync(IntegrationEvent evt); - Task PublishThroughEventBusAsync(IntegrationEvent evt); - } -} diff --git a/src/Services/Catalog/Catalog.API/Program.cs b/src/Services/Catalog/Catalog.API/Program.cs index c75b56c39..303da6d12 100644 --- a/src/Services/Catalog/Catalog.API/Program.cs +++ b/src/Services/Catalog/Catalog.API/Program.cs @@ -1,6 +1,5 @@ using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; -using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF; using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -38,8 +37,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API new CatalogContextSeed() .SeedAsync(context, env, settings, logger) .Wait(); - }) - .MigrateDbContext((_, __) => { }); + }); Log.Information("Starting web host ({ApplicationContext})...", AppName); host.Run(); diff --git a/src/Services/Catalog/Catalog.API/Startup.cs b/src/Services/Catalog/Catalog.API/Startup.cs index 0258a0a98..00f398904 100644 --- a/src/Services/Catalog/Catalog.API/Startup.cs +++ b/src/Services/Catalog/Catalog.API/Startup.cs @@ -1,32 +1,20 @@ using Autofac; using Autofac.Extensions.DependencyInjection; using global::Catalog.API.Infrastructure.Filters; -using global::Catalog.API.IntegrationEvents; using Microsoft.ApplicationInsights.Extensibility; using Microsoft.ApplicationInsights.ServiceFabric; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; -using Microsoft.Azure.ServiceBus; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Diagnostics; -using Microsoft.eShopOnContainers.BuildingBlocks.EventBus; -using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; -using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ; -using Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus; -using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF; -using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF.Services; using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure; using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.EventHandling; -using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using RabbitMQ.Client; using System; -using System.Data.Common; using System.Reflection; using HealthChecks.UI.Client; using Microsoft.AspNetCore.Diagnostics.HealthChecks; @@ -49,7 +37,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API .AddCustomMVC(Configuration) .AddCustomDbContext(Configuration) .AddCustomOptions(Configuration) - .AddIntegrationServices(Configuration) + .AddIntegrationServices() .AddEventBus(Configuration) .AddSwagger() .AddCustomHealthCheck(Configuration); @@ -95,15 +83,6 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API { c.SwaggerEndpoint($"{ (!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty) }/swagger/v1/swagger.json", "Catalog.API V1"); }); - - ConfigureEventBus(app); - } - - protected virtual void ConfigureEventBus(IApplicationBuilder app) - { - var eventBus = app.ApplicationServices.GetRequiredService(); - eventBus.Subscribe(); - eventBus.Subscribe(); } } @@ -130,7 +109,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API } public static IServiceCollection AddCustomMVC(this IServiceCollection services, IConfiguration configuration) - { + { services.AddMvc(options => { options.Filters.Add(typeof(HttpGlobalExceptionFilter)); @@ -166,7 +145,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API tags: new string[] { "catalogdb" }); if (!string.IsNullOrEmpty(accountName) && !string.IsNullOrEmpty(accountKey)) - { + { hcBuilder .AddAzureBlobStorage( $"DefaultEndpointsProtocol=https;AccountName={accountName};AccountKey={accountKey};EndpointSuffix=core.windows.net", @@ -213,17 +192,6 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API //Check Client vs. Server evaluation: https://docs.microsoft.com/en-us/ef/core/querying/client-eval }); - services.AddDbContext(options => - { - options.UseSqlServer(configuration["ConnectionString"], - sqlServerOptionsAction: sqlOptions => - { - sqlOptions.MigrationsAssembly(typeof(Startup).GetTypeInfo().Assembly.GetName().Name); - //Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency - sqlOptions.EnableRetryOnFailure(maxRetryCount: 10, maxRetryDelay: TimeSpan.FromSeconds(30), errorNumbersToAdd: null); - }); - }); - return services; } @@ -269,100 +237,51 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API } - public static IServiceCollection AddIntegrationServices(this IServiceCollection services, IConfiguration configuration) + public static IServiceCollection AddIntegrationServices(this IServiceCollection services) { - services.AddTransient>( - sp => (DbConnection c) => new IntegrationEventLogService(c)); - - services.AddTransient(); - - if (configuration.GetValue("AzureServiceBusEnabled")) - { - services.AddSingleton(sp => - { - var settings = sp.GetRequiredService>().Value; - var logger = sp.GetRequiredService>(); - - var serviceBusConnection = new ServiceBusConnectionStringBuilder(settings.EventBusConnection); - - return new DefaultServiceBusPersisterConnection(serviceBusConnection, logger); - }); - } - else - { - services.AddSingleton(sp => - { - var settings = sp.GetRequiredService>().Value; - var logger = sp.GetRequiredService>(); - - var factory = new ConnectionFactory() - { - HostName = configuration["EventBusConnection"] - }; - - if (!string.IsNullOrEmpty(configuration["EventBusUserName"])) - { - factory.UserName = configuration["EventBusUserName"]; - } - - if (!string.IsNullOrEmpty(configuration["EventBusPassword"])) - { - factory.Password = configuration["EventBusPassword"]; - } - - var retryCount = 5; - if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) - { - retryCount = int.Parse(configuration["EventBusRetryCount"]); - } - - return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); - }); - } + //Handlers + services.AddTransient(); // OrderStatusChangedToAwaitingValidationIntegrationEvent + services.AddTransient(); // OrderStatusChangedToPaidIntegrationEvent return services; } public static IServiceCollection AddEventBus(this IServiceCollection services, IConfiguration configuration) { - var subscriptionClientName = configuration["SubscriptionClientName"]; - - if (configuration.GetValue("AzureServiceBusEnabled")) + services.AddCap(options => { - services.AddSingleton(sp => - { - var serviceBusPersisterConnection = sp.GetRequiredService(); - var iLifetimeScope = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubcriptionsManager = sp.GetRequiredService(); - - return new EventBusServiceBus(serviceBusPersisterConnection, logger, - eventBusSubcriptionsManager, subscriptionClientName, iLifetimeScope); - }); + options.UseSqlServer(configuration["ConnectionString"]); - } - else - { - services.AddSingleton(sp => + if (configuration.GetValue("AzureServiceBusEnabled")) { - var rabbitMQPersistentConnection = sp.GetRequiredService(); - var iLifetimeScope = sp.GetRequiredService(); - var logger = sp.GetRequiredService>(); - var eventBusSubcriptionsManager = sp.GetRequiredService(); - - var retryCount = 5; - if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) + options.UseAzureServiceBus(configuration["EventBusConnection"]); + } + else + { + options.UseRabbitMQ(conf => { - retryCount = int.Parse(configuration["EventBusRetryCount"]); - } - - return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, subscriptionClientName, retryCount); - }); - } + conf.HostName = configuration["EventBusConnection"]; + if (!string.IsNullOrEmpty(configuration["EventBusUserName"])) + { + conf.UserName = configuration["EventBusUserName"]; + } + if (!string.IsNullOrEmpty(configuration["EventBusPassword"])) + { + conf.Password = configuration["EventBusPassword"]; + } + }); + } + + if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"])) + { + options.FailedRetryCount = int.Parse(configuration["EventBusRetryCount"]); + } - services.AddSingleton(); - services.AddTransient(); - services.AddTransient(); + if (!string.IsNullOrEmpty(configuration["SubscriptionClientName"])) + { + options.DefaultGroup = configuration["SubscriptionClientName"]; + } + }); return services; }