diff --git a/src/Services/Catalog/Catalog.API/Catalog.API.csproj b/src/Services/Catalog/Catalog.API/Catalog.API.csproj
index 1c0fddf92..387908b90 100644
--- a/src/Services/Catalog/Catalog.API/Catalog.API.csproj
+++ b/src/Services/Catalog/Catalog.API/Catalog.API.csproj
@@ -45,6 +45,7 @@
+
diff --git a/src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs b/src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs
index 9d8cc0b11..71dcd5d1e 100644
--- a/src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs
+++ b/src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs
@@ -5,7 +5,9 @@ using Microsoft.eShopOnContainers.Services.Catalog.API.Model;
using Microsoft.eShopOnContainers.Services.Catalog.API.ViewModel;
using Microsoft.eShopOnContainers.Services.Common.Infrastructure;
using Microsoft.eShopOnContainers.Services.Common.Infrastructure.Catalog;
+using Microsoft.eShopOnContainers.Services.Common.Infrastructure.Data;
using Microsoft.Extensions.Options;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
@@ -104,12 +106,6 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
var model = new PaginatedItemsViewModel(
pageIndex, pageSize, totalItems, itemsOnPage);
- //hook to run integration tests until POST methods are created
- if (catalogTypeId.HasValue && catalogTypeId == 1)
- {
- _eventBus.Publish(new CatalogPriceChanged(2, 10.4M, 8.4M));
- }
-
return Ok(model);
}
@@ -153,11 +149,12 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
_context.CatalogItems.Update(item);
await _context.SaveChangesAsync();
- _eventBus.Publish(new CatalogPriceChanged(item.Id, item.Price, oldPrice));
+ var @event = new CatalogPriceChanged(item.Id, item.Price, oldPrice);
+ await ProcessEventAsync(@event);
}
return Ok();
- }
+ }
private List ComposePicUri(List items) {
var baseUri = _settings.Value.ExternalCatalogBaseUrl;
@@ -168,5 +165,22 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
return items;
}
+
+ private async Task ProcessEventAsync(IntegrationEventBase @event)
+ {
+ _eventBus.Publish(@event);
+ var eventData = new IntegrationEvent(@event);
+ eventData.TimesSent++;
+ eventData.State = EventStateEnum.Sent;
+ try
+ {
+ _context.IntegrationEvents.Add(eventData);
+ await _context.SaveChangesAsync();
+ }
+ catch (Exception ex)
+ {
+ var t = ex.Message;
+ }
+ }
}
}
diff --git a/src/Services/Catalog/Catalog.API/Infrastructure/CatalogContext.cs b/src/Services/Catalog/Catalog.API/Infrastructure/CatalogContext.cs
index 5c5498099..aac778940 100644
--- a/src/Services/Catalog/Catalog.API/Infrastructure/CatalogContext.cs
+++ b/src/Services/Catalog/Catalog.API/Infrastructure/CatalogContext.cs
@@ -3,6 +3,7 @@
using EntityFrameworkCore.Metadata.Builders;
using Microsoft.EntityFrameworkCore;
using Model;
+ using Microsoft.eShopOnContainers.Services.Common.Infrastructure.Data;
public class CatalogContext : DbContext
{
@@ -12,12 +13,15 @@
public DbSet CatalogItems { get; set; }
public DbSet CatalogBrands { get; set; }
public DbSet CatalogTypes { get; set; }
+ public DbSet IntegrationEvents { get; set; }
+
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity(ConfigureCatalogBrand);
builder.Entity(ConfigureCatalogType);
builder.Entity(ConfigureCatalogItem);
- }
+ builder.Entity(ConfigureIntegrationEvent);
+ }
void ConfigureCatalogItem(EntityTypeBuilder builder)
{
@@ -75,5 +79,31 @@
.IsRequired()
.HasMaxLength(100);
}
+
+ void ConfigureIntegrationEvent(EntityTypeBuilder builder)
+ {
+ builder.ToTable("IntegrationEvent");
+
+ 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/Services/Catalog/Catalog.API/Infrastructure/Migrations/20170314083211_AddEventTable.Designer.cs b/src/Services/Catalog/Catalog.API/Infrastructure/Migrations/20170314083211_AddEventTable.Designer.cs
new file mode 100644
index 000000000..126047b85
--- /dev/null
+++ b/src/Services/Catalog/Catalog.API/Infrastructure/Migrations/20170314083211_AddEventTable.Designer.cs
@@ -0,0 +1,123 @@
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure;
+using Microsoft.eShopOnContainers.Services.Common.Infrastructure;
+
+namespace Catalog.API.Infrastructure.Migrations
+{
+ [DbContext(typeof(CatalogContext))]
+ [Migration("20170314083211_AddEventTable")]
+ partial class AddEventTable
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+ modelBuilder
+ .HasAnnotation("ProductVersion", "1.1.0-rtm-22752")
+ .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.Common.Infrastructure.Data.IntegrationEvent", b =>
+ {
+ b.Property("EventId")
+ .ValueGeneratedOnAdd();
+
+ b.Property("Content")
+ .IsRequired();
+
+ b.Property("CreationTime");
+
+ b.Property("EventTypeName")
+ .IsRequired()
+ .HasMaxLength(200);
+
+ b.Property("State");
+
+ b.Property("TimesSent");
+
+ b.HasKey("EventId");
+
+ b.ToTable("IntegrationEvent");
+ });
+
+ 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/Migrations/20170314083211_AddEventTable.cs b/src/Services/Catalog/Catalog.API/Infrastructure/Migrations/20170314083211_AddEventTable.cs
new file mode 100644
index 000000000..e6494d2a3
--- /dev/null
+++ b/src/Services/Catalog/Catalog.API/Infrastructure/Migrations/20170314083211_AddEventTable.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace Catalog.API.Infrastructure.Migrations
+{
+ public partial class AddEventTable : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.CreateTable(
+ name: "IntegrationEvent",
+ columns: table => new
+ {
+ EventId = table.Column(nullable: false),
+ Content = table.Column(nullable: false),
+ CreationTime = table.Column(nullable: false),
+ EventTypeName = table.Column(maxLength: 200, nullable: false),
+ State = table.Column(nullable: false),
+ TimesSent = table.Column(nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_IntegrationEvent", x => x.EventId);
+ });
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable(
+ name: "IntegrationEvent");
+ }
+ }
+}
diff --git a/src/Services/Catalog/Catalog.API/Infrastructure/Migrations/CatalogContextModelSnapshot.cs b/src/Services/Catalog/Catalog.API/Infrastructure/Migrations/CatalogContextModelSnapshot.cs
index c0eb1db72..4ea056e0d 100644
--- a/src/Services/Catalog/Catalog.API/Infrastructure/Migrations/CatalogContextModelSnapshot.cs
+++ b/src/Services/Catalog/Catalog.API/Infrastructure/Migrations/CatalogContextModelSnapshot.cs
@@ -4,6 +4,7 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure;
+using Microsoft.eShopOnContainers.Services.Common.Infrastructure;
namespace Catalog.API.Infrastructure.Migrations
{
@@ -13,13 +14,13 @@ namespace Catalog.API.Infrastructure.Migrations
protected override void BuildModel(ModelBuilder modelBuilder)
{
modelBuilder
- .HasAnnotation("ProductVersion", "1.0.1")
+ .HasAnnotation("ProductVersion", "1.1.0-rtm-22752")
.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.Infrastructure.CatalogBrand", b =>
+ modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Catalog.API.Model.CatalogBrand", b =>
{
b.Property("Id")
.ValueGeneratedOnAdd()
@@ -28,14 +29,14 @@ namespace Catalog.API.Infrastructure.Migrations
b.Property("Brand")
.IsRequired()
- .HasAnnotation("MaxLength", 100);
+ .HasMaxLength(100);
b.HasKey("Id");
b.ToTable("CatalogBrand");
});
- modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure.CatalogItem", b =>
+ modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Catalog.API.Model.CatalogItem", b =>
{
b.Property("Id")
.ValueGeneratedOnAdd()
@@ -50,7 +51,7 @@ namespace Catalog.API.Infrastructure.Migrations
b.Property("Name")
.IsRequired()
- .HasAnnotation("MaxLength", 50);
+ .HasMaxLength(50);
b.Property("PictureUri");
@@ -65,7 +66,7 @@ namespace Catalog.API.Infrastructure.Migrations
b.ToTable("Catalog");
});
- modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure.CatalogType", b =>
+ modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Catalog.API.Model.CatalogType", b =>
{
b.Property("Id")
.ValueGeneratedOnAdd()
@@ -74,21 +75,44 @@ namespace Catalog.API.Infrastructure.Migrations
b.Property("Type")
.IsRequired()
- .HasAnnotation("MaxLength", 100);
+ .HasMaxLength(100);
b.HasKey("Id");
b.ToTable("CatalogType");
});
- modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure.CatalogItem", b =>
+ modelBuilder.Entity("Microsoft.eShopOnContainers.Services.Common.Infrastructure.Data.IntegrationEvent", b =>
{
- b.HasOne("Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure.CatalogBrand", "CatalogBrand")
+ b.Property("EventId")
+ .ValueGeneratedOnAdd();
+
+ b.Property("Content")
+ .IsRequired();
+
+ b.Property("CreationTime");
+
+ b.Property("EventTypeName")
+ .IsRequired()
+ .HasMaxLength(200);
+
+ b.Property("State");
+
+ b.Property("TimesSent");
+
+ b.HasKey("EventId");
+
+ b.ToTable("IntegrationEvent");
+ });
+
+ 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.Infrastructure.CatalogType", "CatalogType")
+ b.HasOne("Microsoft.eShopOnContainers.Services.Catalog.API.Model.CatalogType", "CatalogType")
.WithMany()
.HasForeignKey("CatalogTypeId")
.OnDelete(DeleteBehavior.Cascade);
diff --git a/src/Services/Common/Infrastructure/Catalog/CatalogPriceChanged.cs b/src/Services/Common/Infrastructure/Catalog/CatalogPriceChanged.cs
index 427aa69c2..2c31a85b6 100644
--- a/src/Services/Common/Infrastructure/Catalog/CatalogPriceChanged.cs
+++ b/src/Services/Common/Infrastructure/Catalog/CatalogPriceChanged.cs
@@ -4,7 +4,7 @@ using System.Text;
namespace Microsoft.eShopOnContainers.Services.Common.Infrastructure.Catalog
{
- public class CatalogPriceChanged : IIntegrationEvent
+ public class CatalogPriceChanged : IntegrationEventBase
{
public int ItemId { get; private set; }
diff --git a/src/Services/Common/Infrastructure/IIntegrationEvent.cs b/src/Services/Common/Infrastructure/Data/EventStateEnum.cs
similarity index 59%
rename from src/Services/Common/Infrastructure/IIntegrationEvent.cs
rename to src/Services/Common/Infrastructure/Data/EventStateEnum.cs
index 48d991283..e952b7742 100644
--- a/src/Services/Common/Infrastructure/IIntegrationEvent.cs
+++ b/src/Services/Common/Infrastructure/Data/EventStateEnum.cs
@@ -4,7 +4,10 @@ using System.Text;
namespace Microsoft.eShopOnContainers.Services.Common.Infrastructure
{
- public interface IIntegrationEvent
- {
+ public enum EventStateEnum
+ {
+ NotSend = 0,
+ Sent = 1,
+ SendingFailed = 2
}
}
diff --git a/src/Services/Common/Infrastructure/Data/IntegrationEvent.cs b/src/Services/Common/Infrastructure/Data/IntegrationEvent.cs
new file mode 100644
index 000000000..97b313021
--- /dev/null
+++ b/src/Services/Common/Infrastructure/Data/IntegrationEvent.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Newtonsoft.Json;
+
+namespace Microsoft.eShopOnContainers.Services.Common.Infrastructure.Data
+{
+ public class IntegrationEvent
+ {
+ public IntegrationEvent(IntegrationEventBase @event)
+ {
+ EventId = @event.Id;
+ CreationTime = DateTime.UtcNow;
+ EventTypeName = @event.GetType().FullName;
+ Content = JsonConvert.SerializeObject(@event);
+ State = EventStateEnum.NotSend;
+ TimesSent = 0;
+ }
+ public Guid EventId { get; private set; }
+ public string EventTypeName { get; private set; }
+ public EventStateEnum State { get; set; }
+ public int TimesSent { get; set; }
+ public DateTime CreationTime { get; private set; }
+ public string Content { get; private set; }
+ }
+}
diff --git a/src/Services/Common/Infrastructure/EventBus.cs b/src/Services/Common/Infrastructure/EventBus.cs
index 47e51d28d..4ff33e79b 100644
--- a/src/Services/Common/Infrastructure/EventBus.cs
+++ b/src/Services/Common/Infrastructure/EventBus.cs
@@ -30,7 +30,7 @@ namespace Microsoft.eShopOnContainers.Services.Common.Infrastructure
_handlers = new Dictionary>();
_eventTypes = new List();
}
- public void Publish(IIntegrationEvent @event)
+ public void Publish(IntegrationEventBase @event)
{
var eventName = @event.GetType().Name;
var factory = new ConnectionFactory() { HostName = _connectionString };
@@ -51,7 +51,7 @@ namespace Microsoft.eShopOnContainers.Services.Common.Infrastructure
}
- public void Subscribe(IIntegrationEventHandler handler) where T : IIntegrationEvent
+ public void Subscribe(IIntegrationEventHandler handler) where T : IntegrationEventBase
{
var eventName = typeof(T).Name;
if (_handlers.ContainsKey(eventName))
@@ -72,7 +72,7 @@ namespace Microsoft.eShopOnContainers.Services.Common.Infrastructure
}
- public void Unsubscribe(IIntegrationEventHandler handler) where T : IIntegrationEvent
+ public void Unsubscribe(IIntegrationEventHandler handler) where T : IntegrationEventBase
{
var eventName = typeof(T).Name;
if (_handlers.ContainsKey(eventName) && _handlers[eventName].Contains(handler))
diff --git a/src/Services/Common/Infrastructure/IEventBus.cs b/src/Services/Common/Infrastructure/IEventBus.cs
index 5751f1b81..483e550ec 100644
--- a/src/Services/Common/Infrastructure/IEventBus.cs
+++ b/src/Services/Common/Infrastructure/IEventBus.cs
@@ -6,8 +6,8 @@ namespace Microsoft.eShopOnContainers.Services.Common.Infrastructure
{
public interface IEventBus
{
- void Subscribe(IIntegrationEventHandler handler) where T: IIntegrationEvent;
- void Unsubscribe(IIntegrationEventHandler handler) where T : IIntegrationEvent;
- void Publish(IIntegrationEvent @event);
+ void Subscribe(IIntegrationEventHandler handler) where T: IntegrationEventBase;
+ void Unsubscribe(IIntegrationEventHandler handler) where T : IntegrationEventBase;
+ void Publish(IntegrationEventBase @event);
}
}
diff --git a/src/Services/Common/Infrastructure/IIntegrationEventHandler.cs b/src/Services/Common/Infrastructure/IIntegrationEventHandler.cs
index 6824a1665..f4c00fa6b 100644
--- a/src/Services/Common/Infrastructure/IIntegrationEventHandler.cs
+++ b/src/Services/Common/Infrastructure/IIntegrationEventHandler.cs
@@ -6,7 +6,7 @@ using System.Threading.Tasks;
namespace Microsoft.eShopOnContainers.Services.Common.Infrastructure
{
public interface IIntegrationEventHandler : IIntegrationEventHandler
- where TIntegrationEvent: IIntegrationEvent
+ where TIntegrationEvent: IntegrationEventBase
{
Task Handle(TIntegrationEvent @event);
}
diff --git a/src/Services/Common/Infrastructure/IntegrationEventBase.cs b/src/Services/Common/Infrastructure/IntegrationEventBase.cs
new file mode 100644
index 000000000..b11c17815
--- /dev/null
+++ b/src/Services/Common/Infrastructure/IntegrationEventBase.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Microsoft.eShopOnContainers.Services.Common.Infrastructure
+{
+ public class IntegrationEventBase
+ {
+ public IntegrationEventBase()
+ {
+ Id = Guid.NewGuid();
+ }
+
+ public Guid Id { get; private set; }
+ }
+}