From 2e674ad5321fef5bea8ab2a5bef6f31b39d5e44e Mon Sep 17 00:00:00 2001 From: Eduard Tomas Date: Wed, 22 Mar 2017 14:23:25 +0100 Subject: [PATCH 1/4] Replaced Tuple by C#7 multiple return statement Replaced private set only used in ctor by readonly prop --- .../EventBus/Events/IntegrationEvent.cs | 2 +- .../EventBusRabbitMQ/EventBusRabbitMQ.cs | 72 ++++++++++--------- .../EventBusRabbitMQ/EventBusRabbitMQ.csproj | 1 + 3 files changed, 40 insertions(+), 35 deletions(-) diff --git a/src/BuildingBlocks/EventBus/EventBus/Events/IntegrationEvent.cs b/src/BuildingBlocks/EventBus/EventBus/Events/IntegrationEvent.cs index 11185764e..e1802704e 100644 --- a/src/BuildingBlocks/EventBus/EventBus/Events/IntegrationEvent.cs +++ b/src/BuildingBlocks/EventBus/EventBus/Events/IntegrationEvent.cs @@ -11,6 +11,6 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events Id = Guid.NewGuid(); } - public Guid Id { get; private set; } + public Guid Id { get; } } } diff --git a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs index e31c43396..b850c4eef 100644 --- a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs +++ b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs @@ -21,7 +21,8 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ private readonly Dictionary> _handlers; private readonly List _eventTypes; - private Tuple _connection; + private IModel _model; + private IConnection _connection; private string _queueName; @@ -86,15 +87,15 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ _handlers.Remove(eventName); var eventType = _eventTypes.Single(e => e.Name == eventName); _eventTypes.Remove(eventType); - _connection.Item1.QueueUnbind(queue: _queueName, + _model.QueueUnbind(queue: _queueName, exchange: _brokerName, routingKey: eventName); if (_handlers.Keys.Count == 0) { _queueName = string.Empty; - _connection.Item1.Dispose(); - _connection.Item2.Dispose(); + _model.Dispose(); + _connection.Dispose(); } } @@ -103,48 +104,51 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ public void Dispose() { - if (_connection != null) - { - _handlers.Clear(); - _connection.Item1.Dispose(); - _connection.Item2.Dispose(); - } + _handlers.Clear(); + _model?.Dispose(); + _connection?.Dispose(); } private IModel GetChannel() { - if (_connection != null) + if (_model != null) { - return _connection.Item1; + return _model; } else { - var factory = new ConnectionFactory() { HostName = _connectionString }; - var connection = factory.CreateConnection(); - var channel = connection.CreateModel(); + ((_model, _connection) = CreateConnection(); + return _model; + } + } - channel.ExchangeDeclare(exchange: _brokerName, - type: "direct"); - if (string.IsNullOrEmpty(_queueName)) - { - _queueName = channel.QueueDeclare().QueueName; - } - var consumer = new EventingBasicConsumer(channel); - consumer.Received += async (model, ea) => - { - var eventName = ea.RoutingKey; - var message = Encoding.UTF8.GetString(ea.Body); - - await ProcessEvent(eventName, message); - }; - channel.BasicConsume(queue: _queueName, - noAck: true, - consumer: consumer); - _connection = new Tuple(channel, connection); + private (IModel model, IConnection connection) CreateConnection() + { + var factory = new ConnectionFactory() { HostName = _connectionString }; + var con = factory.CreateConnection(); + var channel = con.CreateModel(); - return _connection.Item1; + channel.ExchangeDeclare(exchange: _brokerName, + type: "direct"); + if (string.IsNullOrEmpty(_queueName)) + { + _queueName = channel.QueueDeclare().QueueName; } + + var consumer = new EventingBasicConsumer(channel); + consumer.Received += async (model, ea) => + { + var eventName = ea.RoutingKey; + var message = Encoding.UTF8.GetString(ea.Body); + + await ProcessEvent(eventName, message); + }; + channel.BasicConsume(queue: _queueName, + noAck: true, + consumer: consumer); + + return (channel, con); } private async Task ProcessEvent(string eventName, string message) diff --git a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.csproj b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.csproj index 6e399a627..cf36a2222 100644 --- a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.csproj +++ b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.csproj @@ -9,6 +9,7 @@ + From 20d2e32719dfada74b8dd54de5710edb027ccc11 Mon Sep 17 00:00:00 2001 From: Eduard Tomas Date: Wed, 22 Mar 2017 14:40:00 +0100 Subject: [PATCH 2/4] Ups... too many parens xD --- .../EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs index b850c4eef..3388875ab 100644 --- a/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs +++ b/src/BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.cs @@ -117,7 +117,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ } else { - ((_model, _connection) = CreateConnection(); + (_model, _connection) = CreateConnection(); return _model; } } From 7a63490558e9a7f40229d746db309839c3d5e21d Mon Sep 17 00:00:00 2001 From: dsanz Date: Wed, 22 Mar 2017 16:10:46 +0100 Subject: [PATCH 3/4] Add the sql implementation for the storage of Integration events. --- eShopOnContainers-ServicesAndWebApps.sln | 53 +++++++++- .../EventStateEnum.cs | 2 +- .../IntegrationEventLogContext.cs | 48 +++++++++ .../IntegrationEventLogEF.csproj | 27 +++++ .../IntegrationEventLogEntry.cs | 3 +- .../Catalog/Catalog.API/Catalog.API.csproj | 1 + .../Controllers/CatalogController.cs | 50 +++++----- .../Infrastructure/CatalogContext.cs | 42 ++++---- .../20161103152832_Initial.Designer.cs | 0 .../20161103152832_Initial.cs | 0 ...0161103153420_UpdateTableNames.Designer.cs | 0 .../20161103153420_UpdateTableNames.cs | 0 .../20170314083211_AddEventTable.Designer.cs | 0 .../20170314083211_AddEventTable.cs | 0 ...factoringToIntegrationEventLog.Designer.cs | 0 ...012921_RefactoringToIntegrationEventLog.cs | 0 ..._RefactoringEventBusNamespaces.Designer.cs | 0 ...316120022_RefactoringEventBusNamespaces.cs | 0 ...244_RemoveIntegrationEventLogs.Designer.cs | 99 +++++++++++++++++++ ...170322124244_RemoveIntegrationEventLogs.cs | 34 +++++++ .../CatalogContextModelSnapshot.cs | 23 ----- ...145434_IntegrationEventInitial.Designer.cs | 43 ++++++++ .../20170322145434_IntegrationEventInitial.cs | 34 +++++++ ...IntegrationEventLogContextModelSnapshot.cs | 42 ++++++++ src/Services/Catalog/Catalog.API/Startup.cs | 15 ++- 25 files changed, 443 insertions(+), 73 deletions(-) rename src/BuildingBlocks/EventBus/{EventBus/Events/IntegrationEventLog => IntegrationEventLogEF}/EventStateEnum.cs (68%) create mode 100644 src/BuildingBlocks/EventBus/IntegrationEventLogEF/IntegrationEventLogContext.cs create mode 100644 src/BuildingBlocks/EventBus/IntegrationEventLogEF/IntegrationEventLogEF.csproj rename src/BuildingBlocks/EventBus/{EventBus/Events/IntegrationEventLog => IntegrationEventLogEF}/IntegrationEventLogEntry.cs (85%) rename src/Services/Catalog/Catalog.API/Infrastructure/{Migrations => CatalogMigrations}/20161103152832_Initial.Designer.cs (100%) rename src/Services/Catalog/Catalog.API/Infrastructure/{Migrations => CatalogMigrations}/20161103152832_Initial.cs (100%) rename src/Services/Catalog/Catalog.API/Infrastructure/{Migrations => CatalogMigrations}/20161103153420_UpdateTableNames.Designer.cs (100%) rename src/Services/Catalog/Catalog.API/Infrastructure/{Migrations => CatalogMigrations}/20161103153420_UpdateTableNames.cs (100%) rename src/Services/Catalog/Catalog.API/Infrastructure/{Migrations => CatalogMigrations}/20170314083211_AddEventTable.Designer.cs (100%) rename src/Services/Catalog/Catalog.API/Infrastructure/{Migrations => CatalogMigrations}/20170314083211_AddEventTable.cs (100%) rename src/Services/Catalog/Catalog.API/Infrastructure/{Migrations => CatalogMigrations}/20170316012921_RefactoringToIntegrationEventLog.Designer.cs (100%) rename src/Services/Catalog/Catalog.API/Infrastructure/{Migrations => CatalogMigrations}/20170316012921_RefactoringToIntegrationEventLog.cs (100%) rename src/Services/Catalog/Catalog.API/Infrastructure/{Migrations => CatalogMigrations}/20170316120022_RefactoringEventBusNamespaces.Designer.cs (100%) rename src/Services/Catalog/Catalog.API/Infrastructure/{Migrations => CatalogMigrations}/20170316120022_RefactoringEventBusNamespaces.cs (100%) create mode 100644 src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/20170322124244_RemoveIntegrationEventLogs.Designer.cs create mode 100644 src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/20170322124244_RemoveIntegrationEventLogs.cs rename src/Services/Catalog/Catalog.API/Infrastructure/{Migrations => CatalogMigrations}/CatalogContextModelSnapshot.cs (84%) create mode 100644 src/Services/Catalog/Catalog.API/Infrastructure/IntegrationEventMigrations/20170322145434_IntegrationEventInitial.Designer.cs create mode 100644 src/Services/Catalog/Catalog.API/Infrastructure/IntegrationEventMigrations/20170322145434_IntegrationEventInitial.cs create mode 100644 src/Services/Catalog/Catalog.API/Infrastructure/IntegrationEventMigrations/IntegrationEventLogContextModelSnapshot.cs diff --git a/eShopOnContainers-ServicesAndWebApps.sln b/eShopOnContainers-ServicesAndWebApps.sln index 619dcf4c3..e497a67e5 100644 --- a/eShopOnContainers-ServicesAndWebApps.sln +++ b/eShopOnContainers-ServicesAndWebApps.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26228.4 +VisualStudioVersion = 15.0.26228.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{932D8224-11F6-4D07-B109-DA28AD288A63}" EndProject @@ -72,6 +72,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EventBus", "src\BuildingBlo EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EventBusRabbitMQ", "src\BuildingBlocks\EventBus\EventBusRabbitMQ\EventBusRabbitMQ.csproj", "{8088F3FC-6787-45FA-A924-816EC81CBFAC}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IntegrationEventLogEF", "src\BuildingBlocks\EventBus\IntegrationEventLogEF\IntegrationEventLogEF.csproj", "{9EE28E45-1533-472B-8267-56C48855BA0E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Ad-Hoc|Any CPU = Ad-Hoc|Any CPU @@ -662,6 +664,54 @@ Global {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Release|x64.Build.0 = Release|Any CPU {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Release|x86.ActiveCfg = Release|Any CPU {8088F3FC-6787-45FA-A924-816EC81CBFAC}.Release|x86.Build.0 = Release|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|ARM.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|iPhone.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|x64.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|x64.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|x86.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.AppStore|x86.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|ARM.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|ARM.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|iPhone.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|x64.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|x64.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|x86.ActiveCfg = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Debug|x86.Build.0 = Debug|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Release|Any CPU.Build.0 = Release|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Release|ARM.ActiveCfg = Release|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Release|ARM.Build.0 = Release|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Release|iPhone.ActiveCfg = Release|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Release|iPhone.Build.0 = Release|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Release|x64.ActiveCfg = Release|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Release|x64.Build.0 = Release|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Release|x86.ActiveCfg = Release|Any CPU + {9EE28E45-1533-472B-8267-56C48855BA0E}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -689,5 +739,6 @@ Global {807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F} = {DB0EFB20-B024-4E5E-A75C-52143C131D25} {0044B293-1DCC-4224-B948-00CF6DC7F510} = {807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F} {8088F3FC-6787-45FA-A924-816EC81CBFAC} = {807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F} + {9EE28E45-1533-472B-8267-56C48855BA0E} = {807BB76E-B2BB-47A2-A57B-3D1B20FF5E7F} EndGlobalSection EndGlobal diff --git a/src/BuildingBlocks/EventBus/EventBus/Events/IntegrationEventLog/EventStateEnum.cs b/src/BuildingBlocks/EventBus/IntegrationEventLogEF/EventStateEnum.cs similarity index 68% rename from src/BuildingBlocks/EventBus/EventBus/Events/IntegrationEventLog/EventStateEnum.cs rename to src/BuildingBlocks/EventBus/IntegrationEventLogEF/EventStateEnum.cs index 41ddc119c..3efb78e74 100644 --- a/src/BuildingBlocks/EventBus/EventBus/Events/IntegrationEventLog/EventStateEnum.cs +++ b/src/BuildingBlocks/EventBus/IntegrationEventLogEF/EventStateEnum.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events.IntegrationEventLog +namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF { public enum EventStateEnum { diff --git a/src/BuildingBlocks/EventBus/IntegrationEventLogEF/IntegrationEventLogContext.cs b/src/BuildingBlocks/EventBus/IntegrationEventLogEF/IntegrationEventLogContext.cs new file mode 100644 index 000000000..de8754e03 --- /dev/null +++ b/src/BuildingBlocks/EventBus/IntegrationEventLogEF/IntegrationEventLogContext.cs @@ -0,0 +1,48 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF +{ + public class IntegrationEventLogContext : DbContext + { + public IntegrationEventLogContext(DbContextOptions options) : base(options) + { + } + + public DbSet IntegrationEventLogs { get; set; } + + protected override void OnModelCreating(ModelBuilder builder) + { + builder.Entity(ConfigureIntegrationEventLogEntry); + } + + void ConfigureIntegrationEventLogEntry(EntityTypeBuilder builder) + { + builder.ToTable("IntegrationEventLog"); + + builder.HasKey(e => e.EventId); + + builder.Property(e => e.EventId) + .IsRequired(); + + builder.Property(e => e.Content) + .IsRequired(); + + builder.Property(e => e.CreationTime) + .IsRequired(); + + builder.Property(e => e.State) + .IsRequired(); + + builder.Property(e => e.TimesSent) + .IsRequired(); + + builder.Property(e => e.EventTypeName) + .IsRequired(); + + } + } +} diff --git a/src/BuildingBlocks/EventBus/IntegrationEventLogEF/IntegrationEventLogEF.csproj b/src/BuildingBlocks/EventBus/IntegrationEventLogEF/IntegrationEventLogEF.csproj new file mode 100644 index 000000000..039b26ae2 --- /dev/null +++ b/src/BuildingBlocks/EventBus/IntegrationEventLogEF/IntegrationEventLogEF.csproj @@ -0,0 +1,27 @@ + + + + netcoreapp1.1 + 1.1.0 + Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/BuildingBlocks/EventBus/EventBus/Events/IntegrationEventLog/IntegrationEventLogEntry.cs b/src/BuildingBlocks/EventBus/IntegrationEventLogEF/IntegrationEventLogEntry.cs similarity index 85% rename from src/BuildingBlocks/EventBus/EventBus/Events/IntegrationEventLog/IntegrationEventLogEntry.cs rename to src/BuildingBlocks/EventBus/IntegrationEventLogEF/IntegrationEventLogEntry.cs index a74c600e4..2b31e6681 100644 --- a/src/BuildingBlocks/EventBus/EventBus/Events/IntegrationEventLog/IntegrationEventLogEntry.cs +++ b/src/BuildingBlocks/EventBus/IntegrationEventLogEF/IntegrationEventLogEntry.cs @@ -2,8 +2,9 @@ using System.Collections.Generic; using System.Text; using Newtonsoft.Json; +using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; -namespace Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events.IntegrationEventLog +namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF { public class IntegrationEventLogEntry { diff --git a/src/Services/Catalog/Catalog.API/Catalog.API.csproj b/src/Services/Catalog/Catalog.API/Catalog.API.csproj index 5cef06749..f4567b88a 100644 --- a/src/Services/Catalog/Catalog.API/Catalog.API.csproj +++ b/src/Services/Catalog/Catalog.API/Catalog.API.csproj @@ -58,6 +58,7 @@ + diff --git a/src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs b/src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs index b60ddc27c..2feaa423d 100644 --- a/src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs +++ b/src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs @@ -1,7 +1,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; -using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events.IntegrationEventLog; +using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF; using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure; using Microsoft.eShopOnContainers.Services.Catalog.API.IntegrationEvents.Events; using Microsoft.eShopOnContainers.Services.Catalog.API.Model; @@ -16,28 +16,31 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers [Route("api/v1/[controller]")] public class CatalogController : ControllerBase { - private readonly CatalogContext _context; + private readonly CatalogContext _catalogContext; + private readonly IntegrationEventLogContext _integrationEventLogContext; private readonly IOptionsSnapshot _settings; private readonly IEventBus _eventBus; - public CatalogController(CatalogContext context, IOptionsSnapshot settings, IEventBus eventBus) + public CatalogController(CatalogContext catalogContext, IntegrationEventLogContext integrationEventLogContext, IOptionsSnapshot settings, IEventBus eventBus) { - _context = context; + _catalogContext = catalogContext; + _integrationEventLogContext = integrationEventLogContext; _settings = settings; _eventBus = eventBus; - ((DbContext)context).ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; + ((DbContext)catalogContext).ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; } // GET api/v1/[controller]/items[?pageSize=3&pageIndex=10] [HttpGet] [Route("[action]")] public async Task Items([FromQuery]int pageSize = 10, [FromQuery]int pageIndex = 0) + { - var totalItems = await _context.CatalogItems + var totalItems = await _catalogContext.CatalogItems .LongCountAsync(); - var itemsOnPage = await _context.CatalogItems + var itemsOnPage = await _catalogContext.CatalogItems .OrderBy(c=>c.Name) .Skip(pageSize * pageIndex) .Take(pageSize) @@ -57,11 +60,11 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers public async Task Items(string name, [FromQuery]int pageSize = 10, [FromQuery]int pageIndex = 0) { - var totalItems = await _context.CatalogItems + var totalItems = await _catalogContext.CatalogItems .Where(c => c.Name.StartsWith(name)) .LongCountAsync(); - var itemsOnPage = await _context.CatalogItems + var itemsOnPage = await _catalogContext.CatalogItems .Where(c => c.Name.StartsWith(name)) .Skip(pageSize * pageIndex) .Take(pageSize) @@ -80,7 +83,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers [Route("[action]/type/{catalogTypeId}/brand/{catalogBrandId}")] public async Task Items(int? catalogTypeId, int? catalogBrandId, [FromQuery]int pageSize = 10, [FromQuery]int pageIndex = 0) { - var root = (IQueryable)_context.CatalogItems; + var root = (IQueryable)_catalogContext.CatalogItems; if (catalogTypeId.HasValue) { @@ -113,7 +116,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers [Route("[action]")] public async Task CatalogTypes() { - var items = await _context.CatalogTypes + var items = await _catalogContext.CatalogTypes .ToListAsync(); return Ok(items); @@ -124,7 +127,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers [Route("[action]")] public async Task CatalogBrands() { - var items = await _context.CatalogBrands + var items = await _catalogContext.CatalogBrands .ToListAsync(); return Ok(items); @@ -135,7 +138,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers [HttpPost] public async Task EditProduct([FromBody]CatalogItem product) { - var item = await _context.CatalogItems.SingleOrDefaultAsync(i => i.Id == product.Id); + var item = await _catalogContext.CatalogItems.SingleOrDefaultAsync(i => i.Id == product.Id); if (item == null) { @@ -146,20 +149,21 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers { var oldPrice = item.Price; item.Price = product.Price; - _context.CatalogItems.Update(item); + _catalogContext.CatalogItems.Update(item); var @event = new ProductPriceChangedIntegrationEvent(item.Id, item.Price, oldPrice); var eventLogEntry = new IntegrationEventLogEntry(@event); - _context.IntegrationEventLog.Add(eventLogEntry); + _integrationEventLogContext.IntegrationEventLogs.Add(eventLogEntry); - await _context.SaveChangesAsync(); + await _integrationEventLogContext.SaveChangesAsync(); + await _catalogContext.SaveChangesAsync(); _eventBus.Publish(@event); eventLogEntry.TimesSent++; eventLogEntry.State = EventStateEnum.Published; - _context.IntegrationEventLog.Update(eventLogEntry); - await _context.SaveChangesAsync(); + _integrationEventLogContext.IntegrationEventLogs.Update(eventLogEntry); + await _integrationEventLogContext.SaveChangesAsync(); } return Ok(); @@ -170,7 +174,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers [HttpPost] public async Task CreateProduct([FromBody]CatalogItem product) { - _context.CatalogItems.Add( + _catalogContext.CatalogItems.Add( new CatalogItem { CatalogBrandId = product.CatalogBrandId, @@ -181,7 +185,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers Price = product.Price }); - await _context.SaveChangesAsync(); + await _catalogContext.SaveChangesAsync(); return Ok(); } @@ -191,15 +195,15 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers [HttpDelete] public async Task DeleteProduct(int id) { - var product = _context.CatalogItems.SingleOrDefault(x => x.Id == id); + var product = _catalogContext.CatalogItems.SingleOrDefault(x => x.Id == id); if (product == null) { return NotFound(); } - _context.CatalogItems.Remove(product); - await _context.SaveChangesAsync(); + _catalogContext.CatalogItems.Remove(product); + await _catalogContext.SaveChangesAsync(); return Ok(); } diff --git a/src/Services/Catalog/Catalog.API/Infrastructure/CatalogContext.cs b/src/Services/Catalog/Catalog.API/Infrastructure/CatalogContext.cs index 846b1dbb5..b8ae183c8 100644 --- a/src/Services/Catalog/Catalog.API/Infrastructure/CatalogContext.cs +++ b/src/Services/Catalog/Catalog.API/Infrastructure/CatalogContext.cs @@ -3,24 +3,24 @@ using EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore; using Model; - using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events.IntegrationEventLog; + using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF; public class CatalogContext : DbContext { - public CatalogContext(DbContextOptions options) : base(options) + public CatalogContext(DbContextOptions options) : base(options) { } public DbSet CatalogItems { get; set; } public DbSet CatalogBrands { get; set; } public DbSet CatalogTypes { get; set; } - public DbSet IntegrationEventLog { get; set; } + //public DbSet IntegrationEventLog { get; set; } protected override void OnModelCreating(ModelBuilder builder) { builder.Entity(ConfigureCatalogBrand); builder.Entity(ConfigureCatalogType); builder.Entity(ConfigureCatalogItem); - builder.Entity(ConfigureIntegrationEventLogEntry); + //builder.Entity(ConfigureIntegrationEventLogEntry); } void ConfigureCatalogItem(EntityTypeBuilder builder) @@ -80,30 +80,30 @@ .HasMaxLength(100); } - void ConfigureIntegrationEventLogEntry(EntityTypeBuilder builder) - { - builder.ToTable("IntegrationEventLog"); + //void ConfigureIntegrationEventLogEntry(EntityTypeBuilder builder) + //{ + // builder.ToTable("IntegrationEventLog"); - builder.HasKey(e => e.EventId); + // builder.HasKey(e => e.EventId); - builder.Property(e => e.EventId) - .IsRequired(); + // builder.Property(e => e.EventId) + // .IsRequired(); - builder.Property(e => e.Content) - .IsRequired(); + // builder.Property(e => e.Content) + // .IsRequired(); - builder.Property(e => e.CreationTime) - .IsRequired(); + // builder.Property(e => e.CreationTime) + // .IsRequired(); - builder.Property(e => e.State) - .IsRequired(); + // builder.Property(e => e.State) + // .IsRequired(); - builder.Property(e => e.TimesSent) - .IsRequired(); + // builder.Property(e => e.TimesSent) + // .IsRequired(); - builder.Property(e => e.EventTypeName) - .IsRequired(); + // builder.Property(e => e.EventTypeName) + // .IsRequired(); - } + //} } } diff --git a/src/Services/Catalog/Catalog.API/Infrastructure/Migrations/20161103152832_Initial.Designer.cs b/src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/20161103152832_Initial.Designer.cs similarity index 100% rename from src/Services/Catalog/Catalog.API/Infrastructure/Migrations/20161103152832_Initial.Designer.cs rename to src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/20161103152832_Initial.Designer.cs diff --git a/src/Services/Catalog/Catalog.API/Infrastructure/Migrations/20161103152832_Initial.cs b/src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/20161103152832_Initial.cs similarity index 100% rename from src/Services/Catalog/Catalog.API/Infrastructure/Migrations/20161103152832_Initial.cs rename to src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/20161103152832_Initial.cs diff --git a/src/Services/Catalog/Catalog.API/Infrastructure/Migrations/20161103153420_UpdateTableNames.Designer.cs b/src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/20161103153420_UpdateTableNames.Designer.cs similarity index 100% rename from src/Services/Catalog/Catalog.API/Infrastructure/Migrations/20161103153420_UpdateTableNames.Designer.cs rename to src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/20161103153420_UpdateTableNames.Designer.cs diff --git a/src/Services/Catalog/Catalog.API/Infrastructure/Migrations/20161103153420_UpdateTableNames.cs b/src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/20161103153420_UpdateTableNames.cs similarity index 100% rename from src/Services/Catalog/Catalog.API/Infrastructure/Migrations/20161103153420_UpdateTableNames.cs rename to src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/20161103153420_UpdateTableNames.cs diff --git a/src/Services/Catalog/Catalog.API/Infrastructure/Migrations/20170314083211_AddEventTable.Designer.cs b/src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/20170314083211_AddEventTable.Designer.cs similarity index 100% rename from src/Services/Catalog/Catalog.API/Infrastructure/Migrations/20170314083211_AddEventTable.Designer.cs rename to src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/20170314083211_AddEventTable.Designer.cs diff --git a/src/Services/Catalog/Catalog.API/Infrastructure/Migrations/20170314083211_AddEventTable.cs b/src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/20170314083211_AddEventTable.cs similarity index 100% rename from src/Services/Catalog/Catalog.API/Infrastructure/Migrations/20170314083211_AddEventTable.cs rename to src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/20170314083211_AddEventTable.cs diff --git a/src/Services/Catalog/Catalog.API/Infrastructure/Migrations/20170316012921_RefactoringToIntegrationEventLog.Designer.cs b/src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/20170316012921_RefactoringToIntegrationEventLog.Designer.cs similarity index 100% rename from src/Services/Catalog/Catalog.API/Infrastructure/Migrations/20170316012921_RefactoringToIntegrationEventLog.Designer.cs rename to src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/20170316012921_RefactoringToIntegrationEventLog.Designer.cs diff --git a/src/Services/Catalog/Catalog.API/Infrastructure/Migrations/20170316012921_RefactoringToIntegrationEventLog.cs b/src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/20170316012921_RefactoringToIntegrationEventLog.cs similarity index 100% rename from src/Services/Catalog/Catalog.API/Infrastructure/Migrations/20170316012921_RefactoringToIntegrationEventLog.cs rename to src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/20170316012921_RefactoringToIntegrationEventLog.cs diff --git a/src/Services/Catalog/Catalog.API/Infrastructure/Migrations/20170316120022_RefactoringEventBusNamespaces.Designer.cs b/src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/20170316120022_RefactoringEventBusNamespaces.Designer.cs similarity index 100% rename from src/Services/Catalog/Catalog.API/Infrastructure/Migrations/20170316120022_RefactoringEventBusNamespaces.Designer.cs rename to src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/20170316120022_RefactoringEventBusNamespaces.Designer.cs diff --git a/src/Services/Catalog/Catalog.API/Infrastructure/Migrations/20170316120022_RefactoringEventBusNamespaces.cs b/src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/20170316120022_RefactoringEventBusNamespaces.cs similarity index 100% rename from src/Services/Catalog/Catalog.API/Infrastructure/Migrations/20170316120022_RefactoringEventBusNamespaces.cs rename to src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/20170316120022_RefactoringEventBusNamespaces.cs diff --git a/src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/20170322124244_RemoveIntegrationEventLogs.Designer.cs b/src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/20170322124244_RemoveIntegrationEventLogs.Designer.cs new file mode 100644 index 000000000..aea1086f6 --- /dev/null +++ b/src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/20170322124244_RemoveIntegrationEventLogs.Designer.cs @@ -0,0 +1,99 @@ +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure; + +namespace Catalog.API.Infrastructure.Migrations +{ + [DbContext(typeof(CatalogContext))] + [Migration("20170322124244_RemoveIntegrationEventLogs")] + partial class RemoveIntegrationEventLogs + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { + modelBuilder + .HasAnnotation("ProductVersion", "1.1.1") + .HasAnnotation("SqlServer:Sequence:.catalog_brand_hilo", "'catalog_brand_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("SqlServer:Sequence:.catalog_hilo", "'catalog_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("SqlServer:Sequence:.catalog_type_hilo", "'catalog_type_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Catalog.API.Model.CatalogBrand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasAnnotation("SqlServer:HiLoSequenceName", "catalog_brand_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("Brand") + .IsRequired() + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogBrand"); + }); + + modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Catalog.API.Model.CatalogItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasAnnotation("SqlServer:HiLoSequenceName", "catalog_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("CatalogBrandId"); + + b.Property("CatalogTypeId"); + + b.Property("Description"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50); + + b.Property("PictureUri"); + + b.Property("Price"); + + b.HasKey("Id"); + + b.HasIndex("CatalogBrandId"); + + b.HasIndex("CatalogTypeId"); + + b.ToTable("Catalog"); + }); + + modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Catalog.API.Model.CatalogType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasAnnotation("SqlServer:HiLoSequenceName", "catalog_type_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("Type") + .IsRequired() + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogType"); + }); + + modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Catalog.API.Model.CatalogItem", b => + { + b.HasOne("Microsoft.eShopOnContainers.Services.Catalog.API.Model.CatalogBrand", "CatalogBrand") + .WithMany() + .HasForeignKey("CatalogBrandId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("Microsoft.eShopOnContainers.Services.Catalog.API.Model.CatalogType", "CatalogType") + .WithMany() + .HasForeignKey("CatalogTypeId") + .OnDelete(DeleteBehavior.Cascade); + }); + } + } +} diff --git a/src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/20170322124244_RemoveIntegrationEventLogs.cs b/src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/20170322124244_RemoveIntegrationEventLogs.cs new file mode 100644 index 000000000..88e0c76db --- /dev/null +++ b/src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/20170322124244_RemoveIntegrationEventLogs.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Catalog.API.Infrastructure.Migrations +{ + public partial class RemoveIntegrationEventLogs : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "IntegrationEventLog"); + } + + protected override void Down(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); + }); + } + } +} diff --git a/src/Services/Catalog/Catalog.API/Infrastructure/Migrations/CatalogContextModelSnapshot.cs b/src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/CatalogContextModelSnapshot.cs similarity index 84% rename from src/Services/Catalog/Catalog.API/Infrastructure/Migrations/CatalogContextModelSnapshot.cs rename to src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/CatalogContextModelSnapshot.cs index 77c820212..ba1151672 100644 --- a/src/Services/Catalog/Catalog.API/Infrastructure/Migrations/CatalogContextModelSnapshot.cs +++ b/src/Services/Catalog/Catalog.API/Infrastructure/CatalogMigrations/CatalogContextModelSnapshot.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 { @@ -20,28 +19,6 @@ namespace Catalog.API.Infrastructure.Migrations .HasAnnotation("SqlServer:Sequence:.catalog_type_hilo", "'catalog_type_hilo', '', '1', '10', '', '', 'Int64', 'False'") .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - modelBuilder.Entity("Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events.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"); - }); - modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Catalog.API.Model.CatalogBrand", b => { b.Property("Id") 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 new file mode 100644 index 000000000..a3cdeb53f --- /dev/null +++ b/src/Services/Catalog/Catalog.API/Infrastructure/IntegrationEventMigrations/20170322145434_IntegrationEventInitial.Designer.cs @@ -0,0 +1,43 @@ +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 new file mode 100644 index 000000000..fff1ad04c --- /dev/null +++ b/src/Services/Catalog/Catalog.API/Infrastructure/IntegrationEventMigrations/20170322145434_IntegrationEventInitial.cs @@ -0,0 +1,34 @@ +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 new file mode 100644 index 000000000..ab2414bb5 --- /dev/null +++ b/src/Services/Catalog/Catalog.API/Infrastructure/IntegrationEventMigrations/IntegrationEventLogContextModelSnapshot.cs @@ -0,0 +1,42 @@ +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/Startup.cs b/src/Services/Catalog/Catalog.API/Startup.cs index 818855d69..05c6409fe 100644 --- a/src/Services/Catalog/Catalog.API/Startup.cs +++ b/src/Services/Catalog/Catalog.API/Startup.cs @@ -6,6 +6,7 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; using Microsoft.eShopOnContainers.BuildingBlocks.EventBusRabbitMQ; + using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF; using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -45,6 +46,12 @@ //Check Client vs. Server evaluation: https://docs.microsoft.com/en-us/ef/core/querying/client-eval }); + services.AddDbContext(c => + { + c.UseSqlServer(Configuration["ConnectionString"], b => b.MigrationsAssembly("Catalog.API")); + c.ConfigureWarnings(warnings => warnings.Throw(RelationalEventId.QueryClientEvaluationWarning)); + }); + services.Configure(Configuration); // Add framework services. @@ -77,7 +84,7 @@ services.AddMvc(); } - public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) + public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IntegrationEventLogContext integrationEventLogContext) { //Configure logs @@ -98,9 +105,11 @@ //Seed Data CatalogContextSeed.SeedAsync(app, loggerFactory) - .Wait(); + .Wait(); + + // TODO: move this creation to a db initializer + integrationEventLogContext.Database.Migrate(); - } } } From 6e4d9461de69adfee709f210218d053033a5a203 Mon Sep 17 00:00:00 2001 From: dsanz Date: Thu, 23 Mar 2017 13:24:17 +0100 Subject: [PATCH 4/4] Add shared scope transaction between updating catalog product priceand store ProductPriceChangedIntegrationEvent. Added service to encapsulate logic for storage of integration event logs. --- .../IntegrationEventLogEntry.cs | 1 + .../Controllers/CatalogController.cs | 38 +++++++------- .../IIntegrationEventLogService.cs | 14 +++++ .../IntegrationEventLogService.cs | 51 +++++++++++++++++++ src/Services/Catalog/Catalog.API/Startup.cs | 15 ++++-- 5 files changed, 96 insertions(+), 23 deletions(-) create mode 100644 src/Services/Catalog/Catalog.API/IntegrationEvents/IIntegrationEventLogService.cs create mode 100644 src/Services/Catalog/Catalog.API/IntegrationEvents/IntegrationEventLogService.cs diff --git a/src/BuildingBlocks/EventBus/IntegrationEventLogEF/IntegrationEventLogEntry.cs b/src/BuildingBlocks/EventBus/IntegrationEventLogEF/IntegrationEventLogEntry.cs index 2b31e6681..0b68e56a0 100644 --- a/src/BuildingBlocks/EventBus/IntegrationEventLogEF/IntegrationEventLogEntry.cs +++ b/src/BuildingBlocks/EventBus/IntegrationEventLogEF/IntegrationEventLogEntry.cs @@ -8,6 +8,7 @@ namespace Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF { public class IntegrationEventLogEntry { + private IntegrationEventLogEntry() { } public IntegrationEventLogEntry(IntegrationEvent @event) { EventId = @event.Id; diff --git a/src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs b/src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs index 2feaa423d..bbc30a772 100644 --- a/src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs +++ b/src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs @@ -1,5 +1,7 @@ -using Microsoft.AspNetCore.Mvc; +using Catalog.API.IntegrationEvents; +using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Storage; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF; using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure; @@ -17,18 +19,18 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers public class CatalogController : ControllerBase { private readonly CatalogContext _catalogContext; - private readonly IntegrationEventLogContext _integrationEventLogContext; private readonly IOptionsSnapshot _settings; private readonly IEventBus _eventBus; + private readonly IIntegrationEventLogService _integrationEventLogService; - public CatalogController(CatalogContext catalogContext, IntegrationEventLogContext integrationEventLogContext, IOptionsSnapshot settings, IEventBus eventBus) + public CatalogController(CatalogContext Context, IOptionsSnapshot settings, IEventBus eventBus, IIntegrationEventLogService integrationEventLogService) { - _catalogContext = catalogContext; - _integrationEventLogContext = integrationEventLogContext; + _catalogContext = Context; _settings = settings; _eventBus = eventBus; + _integrationEventLogService = integrationEventLogService; - ((DbContext)catalogContext).ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; + ((DbContext)Context).ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; } // GET api/v1/[controller]/items[?pageSize=3&pageIndex=10] @@ -149,21 +151,21 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers { var oldPrice = item.Price; item.Price = product.Price; - _catalogContext.CatalogItems.Update(item); - var @event = new ProductPriceChangedIntegrationEvent(item.Id, item.Price, oldPrice); - var eventLogEntry = new IntegrationEventLogEntry(@event); - _integrationEventLogContext.IntegrationEventLogs.Add(eventLogEntry); - await _integrationEventLogContext.SaveChangesAsync(); - await _catalogContext.SaveChangesAsync(); - + using (var transaction = _catalogContext.Database.BeginTransaction()) + { + _catalogContext.CatalogItems.Update(item); + await _catalogContext.SaveChangesAsync(); + + await _integrationEventLogService.SaveEventAsync(@event); + + transaction.Commit(); + } + _eventBus.Publish(@event); - - eventLogEntry.TimesSent++; - eventLogEntry.State = EventStateEnum.Published; - _integrationEventLogContext.IntegrationEventLogs.Update(eventLogEntry); - await _integrationEventLogContext.SaveChangesAsync(); + + await _integrationEventLogService.MarkEventAsPublishedAsync(@event); } return Ok(); diff --git a/src/Services/Catalog/Catalog.API/IntegrationEvents/IIntegrationEventLogService.cs b/src/Services/Catalog/Catalog.API/IntegrationEvents/IIntegrationEventLogService.cs new file mode 100644 index 000000000..423a0eb98 --- /dev/null +++ b/src/Services/Catalog/Catalog.API/IntegrationEvents/IIntegrationEventLogService.cs @@ -0,0 +1,14 @@ +using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Catalog.API.IntegrationEvents +{ + public interface IIntegrationEventLogService + { + Task SaveEventAsync(IntegrationEvent @event); + Task MarkEventAsPublishedAsync(IntegrationEvent @event); + } +} diff --git a/src/Services/Catalog/Catalog.API/IntegrationEvents/IntegrationEventLogService.cs b/src/Services/Catalog/Catalog.API/IntegrationEvents/IntegrationEventLogService.cs new file mode 100644 index 000000000..e9859c5ae --- /dev/null +++ b/src/Services/Catalog/Catalog.API/IntegrationEvents/IntegrationEventLogService.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Events; +using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Storage; +using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF; +using Microsoft.EntityFrameworkCore.Infrastructure; + +namespace Catalog.API.IntegrationEvents +{ + public class IntegrationEventLogService : IIntegrationEventLogService + { + private readonly IntegrationEventLogContext _integrationEventLogContext; + private readonly CatalogContext _catalogContext; + + public IntegrationEventLogService(CatalogContext catalogContext) + { + _catalogContext = catalogContext; + _integrationEventLogContext = new IntegrationEventLogContext( + new DbContextOptionsBuilder() + .UseSqlServer(catalogContext.Database.GetDbConnection()) + .ConfigureWarnings(warnings => warnings.Throw(RelationalEventId.QueryClientEvaluationWarning)) + .Options); + } + + public Task SaveEventAsync(IntegrationEvent @event) + { + var eventLogEntry = new IntegrationEventLogEntry(@event); + + // as a constraint this transaction has to be done together with a catalogContext transaction + _integrationEventLogContext.Database.UseTransaction(_catalogContext.Database.CurrentTransaction.GetDbTransaction()); + _integrationEventLogContext.IntegrationEventLogs.Add(eventLogEntry); + + return _integrationEventLogContext.SaveChangesAsync(); + } + + public Task MarkEventAsPublishedAsync(IntegrationEvent @event) + { + var eventLogEntry = _integrationEventLogContext.IntegrationEventLogs.Single(ie => ie.EventId == @event.Id); + eventLogEntry.TimesSent++; + eventLogEntry.State = EventStateEnum.Published; + + _integrationEventLogContext.IntegrationEventLogs.Update(eventLogEntry); + + return _integrationEventLogContext.SaveChangesAsync(); + } + } +} diff --git a/src/Services/Catalog/Catalog.API/Startup.cs b/src/Services/Catalog/Catalog.API/Startup.cs index 05c6409fe..1598eb5a0 100644 --- a/src/Services/Catalog/Catalog.API/Startup.cs +++ b/src/Services/Catalog/Catalog.API/Startup.cs @@ -1,5 +1,6 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API { + using global::Catalog.API.IntegrationEvents; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore; @@ -12,6 +13,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; + using System.Data.SqlClient; using System.Reflection; public class Startup @@ -37,9 +39,11 @@ public void ConfigureServices(IServiceCollection services) { + var sqlConnection = new SqlConnection(Configuration["ConnectionString"]); + services.AddDbContext(c => { - c.UseSqlServer(Configuration["ConnectionString"]); + c.UseSqlServer(sqlConnection); // Changing default behavior when client evaluation occurs to throw. // Default in EF Core would be to log a warning when client evaluation is performed. c.ConfigureWarnings(warnings => warnings.Throw(RelationalEventId.QueryClientEvaluationWarning)); @@ -48,7 +52,7 @@ services.AddDbContext(c => { - c.UseSqlServer(Configuration["ConnectionString"], b => b.MigrationsAssembly("Catalog.API")); + c.UseSqlServer(sqlConnection, b => b.MigrationsAssembly("Catalog.API")); c.ConfigureWarnings(warnings => warnings.Throw(RelationalEventId.QueryClientEvaluationWarning)); }); @@ -77,6 +81,8 @@ .AllowCredentials()); }); + services.AddTransient(); + var serviceProvider = services.BuildServiceProvider(); var configuration = serviceProvider.GetRequiredService>().Value; services.AddSingleton(new EventBusRabbitMQ(configuration.EventBusConnection)); @@ -106,9 +112,8 @@ //Seed Data CatalogContextSeed.SeedAsync(app, loggerFactory) .Wait(); - - // TODO: move this creation to a db initializer - integrationEventLogContext.Database.Migrate(); + + integrationEventLogContext.Database.Migrate(); } }