diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs index 1fd8273e67..b86f9b83b1 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs @@ -201,7 +201,7 @@ namespace Volo.Abp.EntityFrameworkCore foreach (var distributedEvent in changeReport.DistributedEvents) { UnitOfWorkManager.Current?.AddOrReplaceDistributedEvent( - new UnitOfWorkEventRecord(distributedEvent.EventData.GetType(), distributedEvent.EventData, distributedEvent.EventOrder, useOutbox: true) + new UnitOfWorkEventRecord(distributedEvent.EventData.GetType(), distributedEvent.EventData, distributedEvent.EventOrder) ); } } diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreModule.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreModule.cs index b5d9eb8436..1378f955e4 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreModule.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpEntityFrameworkCoreModule.cs @@ -3,6 +3,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Volo.Abp.Domain; using Volo.Abp.EntityFrameworkCore.DependencyInjection; +using Volo.Abp.EntityFrameworkCore.DistributedEvents; using Volo.Abp.Modularity; using Volo.Abp.Uow.EntityFrameworkCore; @@ -26,6 +27,7 @@ namespace Volo.Abp.EntityFrameworkCore }); context.Services.TryAddTransient(typeof(IDbContextProvider<>), typeof(UnitOfWorkDbContextProvider<>)); + context.Services.AddTransient(typeof(DbContextEventOutbox<>)); } } } diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DistributedEvents/DbContextEventOutbox.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DistributedEvents/DbContextEventOutbox.cs new file mode 100644 index 0000000000..1831b67ccb --- /dev/null +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DistributedEvents/DbContextEventOutbox.cs @@ -0,0 +1,29 @@ +using System.Threading.Tasks; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.Guids; + +namespace Volo.Abp.EntityFrameworkCore.DistributedEvents +{ + public class DbContextEventOutbox : IEventOutbox + where TDbContext : IHasEventOutbox + { + protected IDbContextProvider DbContextProvider { get; } + protected IGuidGenerator GuidGenerator { get; } + + public DbContextEventOutbox( + IDbContextProvider dbContextProvider, + IGuidGenerator guidGenerator) + { + DbContextProvider = dbContextProvider; + GuidGenerator = guidGenerator; + } + + public async Task EnqueueAsync(string eventName, byte[] eventData) + { + var dbContext = (IHasEventOutbox) await DbContextProvider.GetDbContextAsync(); + dbContext.OutgoingEventRecords.Add( + new OutgoingEventRecord(GuidGenerator.Create(), eventName, eventData) + ); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DistributedEvents/IHasEventOutbox.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DistributedEvents/IHasEventOutbox.cs index 34c712c1a1..e7e60e3800 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DistributedEvents/IHasEventOutbox.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DistributedEvents/IHasEventOutbox.cs @@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore; namespace Volo.Abp.EntityFrameworkCore.DistributedEvents { - public interface IHasEventOutbox + public interface IHasEventOutbox : IEfCoreDbContext { DbSet OutgoingEventRecords { get; set; } } diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DistributedEvents/OutgoingEventRecord.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DistributedEvents/OutgoingEventRecord.cs index 9ebee6894a..395970c4a9 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DistributedEvents/OutgoingEventRecord.cs +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DistributedEvents/OutgoingEventRecord.cs @@ -19,9 +19,12 @@ namespace Volo.Abp.EntityFrameworkCore.DistributedEvents this.SetDefaultsForExtraProperties(); } - public OutgoingEventRecord(Guid id) + public OutgoingEventRecord(Guid id, string eventName, byte[] eventData) : base(id) { + EventName = eventName; + EventData = eventData; + ExtraProperties = new ExtraPropertyDictionary(); this.SetDefaultsForExtraProperties(); } diff --git a/framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/KafkaDistributedEventBus.cs b/framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/KafkaDistributedEventBus.cs index b2d099286a..18f68923e1 100644 --- a/framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/KafkaDistributedEventBus.cs +++ b/framework/src/Volo.Abp.EventBus.Kafka/Volo/Abp/EventBus/Kafka/KafkaDistributedEventBus.cs @@ -182,6 +182,11 @@ namespace Volo.Abp.EventBus.Kafka { unitOfWork.AddOrReplaceDistributedEvent(eventRecord); } + + protected override byte[] Serialize(object eventData) + { + return Serializer.Serialize(eventData); + } public virtual async Task PublishAsync(Type eventType, object eventData, Headers headers, Dictionary headersArguments) { diff --git a/framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/RabbitMq/RabbitMqDistributedEventBus.cs b/framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/RabbitMq/RabbitMqDistributedEventBus.cs index 471bcacad6..d2766eb247 100644 --- a/framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/RabbitMq/RabbitMqDistributedEventBus.cs +++ b/framework/src/Volo.Abp.EventBus.RabbitMQ/Volo/Abp/EventBus/RabbitMq/RabbitMqDistributedEventBus.cs @@ -198,6 +198,11 @@ namespace Volo.Abp.EventBus.RabbitMq { unitOfWork.AddOrReplaceDistributedEvent(eventRecord); } + + protected override byte[] Serialize(object eventData) + { + return Serializer.Serialize(eventData); + } public Task PublishAsync(Type eventType, object eventData, IBasicProperties properties, Dictionary headersArguments = null) { diff --git a/framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/IRabbitMqSerializer.cs b/framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/IRabbitMqSerializer.cs new file mode 100644 index 0000000000..68700b4da5 --- /dev/null +++ b/framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/IRabbitMqSerializer.cs @@ -0,0 +1,13 @@ +using System; + +namespace Volo.Abp.EventBus.Rebus +{ + public interface IRebusSerializer + { + byte[] Serialize(object obj); + + object Deserialize(byte[] value, Type type); + + T Deserialize(byte[] value); + } +} diff --git a/framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/RebusDistributedEventBus.cs b/framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/RebusDistributedEventBus.cs index 760af619f5..43017d9c4a 100644 --- a/framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/RebusDistributedEventBus.cs +++ b/framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/RebusDistributedEventBus.cs @@ -19,6 +19,7 @@ namespace Volo.Abp.EventBus.Rebus public class RebusDistributedEventBus : DistributedEventBusBase, ISingletonDependency { protected IBus Rebus { get; } + protected IRebusSerializer Serializer { get; } //TODO: Accessing to the List may not be thread-safe! protected ConcurrentDictionary> HandlerFactories { get; } @@ -32,7 +33,8 @@ namespace Volo.Abp.EventBus.Rebus IBus rebus, IOptions abpDistributedEventBusOptions, IOptions abpEventBusRebusOptions, - IEventErrorHandler errorHandler) : + IEventErrorHandler errorHandler, + IRebusSerializer serializer) : base( serviceScopeFactory, currentTenant, @@ -41,6 +43,7 @@ namespace Volo.Abp.EventBus.Rebus abpDistributedEventBusOptions) { Rebus = rebus; + Serializer = serializer; AbpRebusEventBusOptions = abpEventBusRebusOptions.Value; HandlerFactories = new ConcurrentDictionary>(); @@ -178,5 +181,10 @@ namespace Volo.Abp.EventBus.Rebus return false; } + + protected override byte[] Serialize(object eventData) + { + return Serializer.Serialize(eventData); + } } } diff --git a/framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/Utf8JsonRabbitMqSerializer.cs b/framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/Utf8JsonRabbitMqSerializer.cs new file mode 100644 index 0000000000..515e616aab --- /dev/null +++ b/framework/src/Volo.Abp.EventBus.Rebus/Volo/Abp/EventBus/Rebus/Utf8JsonRabbitMqSerializer.cs @@ -0,0 +1,32 @@ +using System; +using System.Text; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Json; + +namespace Volo.Abp.EventBus.Rebus +{ + public class Utf8JsonRebusSerializer : IRebusSerializer, ITransientDependency + { + private readonly IJsonSerializer _jsonSerializer; + + public Utf8JsonRebusSerializer(IJsonSerializer jsonSerializer) + { + _jsonSerializer = jsonSerializer; + } + + public byte[] Serialize(object obj) + { + return Encoding.UTF8.GetBytes(_jsonSerializer.Serialize(obj)); + } + + public object Deserialize(byte[] value, Type type) + { + return _jsonSerializer.Deserialize(type, Encoding.UTF8.GetString(value)); + } + + public T Deserialize(byte[] value) + { + return _jsonSerializer.Deserialize(Encoding.UTF8.GetString(value)); + } + } +} diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/AbpDistributedEventBusOptions.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/AbpDistributedEventBusOptions.cs index 2d3861da73..052e421511 100644 --- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/AbpDistributedEventBusOptions.cs +++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/AbpDistributedEventBusOptions.cs @@ -1,4 +1,3 @@ -using System.Collections.Generic; using Volo.Abp.Collections; namespace Volo.Abp.EventBus.Distributed @@ -7,16 +6,12 @@ namespace Volo.Abp.EventBus.Distributed { public ITypeList Handlers { get; } - public List Outboxes { get; } + public OutboxConfigList Outboxes { get; } public AbpDistributedEventBusOptions() { Handlers = new TypeList(); + Outboxes = new OutboxConfigList(); } } - - public class OutboxConfig - { - - } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/DistributedEventBusBase.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/DistributedEventBusBase.cs index 541373cd13..bea6b93a36 100644 --- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/DistributedEventBusBase.cs +++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/DistributedEventBusBase.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; @@ -31,6 +32,11 @@ namespace Volo.Abp.EventBus.Distributed return Subscribe(typeof(TEvent), handler); } + public override Task PublishAsync(Type eventType, object eventData, bool onUnitOfWorkComplete = true) + { + return PublishAsync(eventType, eventData, onUnitOfWorkComplete, useOutbox: true); + } + public Task PublishAsync( TEvent eventData, bool onUnitOfWorkComplete = true, @@ -68,7 +74,29 @@ namespace Volo.Abp.EventBus.Distributed private async Task AddToOutboxAsync(Type eventType, object eventData) { + var unitOfWork = UnitOfWorkManager.Current; + if (unitOfWork == null) + { + return false; + } + + foreach (var outboxConfig in AbpDistributedEventBusOptions.Outboxes) + { + if (outboxConfig.Selector == null || outboxConfig.Selector(eventType)) + { + var eventOutbox = (IEventOutbox)unitOfWork.ServiceProvider.GetRequiredService(outboxConfig.ImplementationType); + var eventName = EventNameAttribute.GetNameOrDefault(eventType); + await eventOutbox.EnqueueAsync( + eventName, + Serialize(eventData) + ); + return true; + } + } + return false; } + + protected abstract byte[] Serialize(object eventData); } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/IEventOutbox.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/IEventOutbox.cs new file mode 100644 index 0000000000..ec6d010307 --- /dev/null +++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/IEventOutbox.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.EventBus.Distributed +{ + public interface IEventOutbox + { + Task EnqueueAsync(string eventName, byte[] eventData); + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/OutboxConfig.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/OutboxConfig.cs new file mode 100644 index 0000000000..97712ec85e --- /dev/null +++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/OutboxConfig.cs @@ -0,0 +1,18 @@ +using System; + +namespace Volo.Abp.EventBus.Distributed +{ + public class OutboxConfig + { + public string Name { get; } + + public Type ImplementationType { get; set; } + public Func Selector { get; set; } + + public OutboxConfig(string name, Type implementationType, Func selector = null) + { + Name = name; + ImplementationType = implementationType; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/OutboxConfigList.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/OutboxConfigList.cs new file mode 100644 index 0000000000..47c91377da --- /dev/null +++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/Distributed/OutboxConfigList.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; + +namespace Volo.Abp.EventBus.Distributed +{ + public class OutboxConfigList : List + { + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventBusBase.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventBusBase.cs index a739bf814d..c8b7eb6790 100644 --- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventBusBase.cs +++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/EventBusBase.cs @@ -99,7 +99,7 @@ namespace Volo.Abp.EventBus } /// - public async Task PublishAsync( + public virtual async Task PublishAsync( Type eventType, object eventData, bool onUnitOfWorkComplete = true) diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs index db8448db23..a40117e0ff 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs @@ -674,8 +674,7 @@ namespace Volo.Abp.Domain.Repositories.MongoDB new UnitOfWorkEventRecord( distributedEvent.EventData.GetType(), distributedEvent.EventData, - distributedEvent.EventOrder, - useOutbox: true + distributedEvent.EventOrder ) ); } diff --git a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkEventRecord.cs b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkEventRecord.cs index dd917d6fe2..cba5646f7a 100644 --- a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkEventRecord.cs +++ b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkEventRecord.cs @@ -22,7 +22,7 @@ namespace Volo.Abp.Uow Type eventType, object eventData, long eventOrder, - bool useOutbox = false) + bool useOutbox = true) { EventType = eventType; EventData = eventData; diff --git a/test/DistEvents/DistDemoApp/DistDemoApp.csproj b/test/DistEvents/DistDemoApp/DistDemoApp.csproj index 9695a92f04..0513a520d1 100644 --- a/test/DistEvents/DistDemoApp/DistDemoApp.csproj +++ b/test/DistEvents/DistDemoApp/DistDemoApp.csproj @@ -16,6 +16,7 @@ + diff --git a/test/DistEvents/DistDemoApp/DistDemoAppModule.cs b/test/DistEvents/DistDemoApp/DistDemoAppModule.cs index f69f9c2380..3cb92b2307 100644 --- a/test/DistEvents/DistDemoApp/DistDemoAppModule.cs +++ b/test/DistEvents/DistDemoApp/DistDemoAppModule.cs @@ -2,14 +2,18 @@ using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Autofac; using Volo.Abp.Domain.Entities.Events.Distributed; using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore.DistributedEvents; using Volo.Abp.EntityFrameworkCore.SqlServer; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.EventBus.RabbitMq; using Volo.Abp.Modularity; namespace DistDemoApp { [DependsOn( typeof(AbpEntityFrameworkCoreSqlServerModule), - typeof(AbpAutofacModule) + typeof(AbpAutofacModule), + typeof(AbpEventBusRabbitMqModule) )] public class DistDemoAppModule : AbpModule { @@ -32,6 +36,13 @@ namespace DistDemoApp options.EtoMappings.Add(); options.AutoEventSelectors.Add(); }); + + Configure(options => + { + options.Outboxes.Add( + new OutboxConfig("Default", typeof(DbContextEventOutbox)) + ); + }); } } } \ No newline at end of file diff --git a/test/DistEvents/DistDemoApp/Migrations/20210908063422_Added_Outbox.Designer.cs b/test/DistEvents/DistDemoApp/Migrations/20210908063422_Added_Outbox.Designer.cs new file mode 100644 index 0000000000..9c350598bf --- /dev/null +++ b/test/DistEvents/DistDemoApp/Migrations/20210908063422_Added_Outbox.Designer.cs @@ -0,0 +1,118 @@ +// +using System; +using DistDemoApp; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Volo.Abp.EntityFrameworkCore; + +namespace DistDemoApp.Migrations +{ + [DbContext(typeof(TodoDbContext))] + [Migration("20210908063422_Added_Outbox")] + partial class Added_Outbox + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer) + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("ProductVersion", "5.0.9") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("DistDemoApp.TodoItem", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Text") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.HasKey("Id"); + + b.ToTable("TodoItems"); + }); + + modelBuilder.Entity("DistDemoApp.TodoSummary", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("Day") + .HasColumnType("tinyint"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Month") + .HasColumnType("tinyint"); + + b.Property("TotalCount") + .HasColumnType("int"); + + b.Property("Year") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("TodoSummaries"); + }); + + modelBuilder.Entity("Volo.Abp.EntityFrameworkCore.DistributedEvents.OutgoingEventRecord", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("EventData") + .IsRequired() + .HasColumnType("varbinary(max)"); + + b.Property("EventName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.HasKey("Id"); + + b.ToTable("AbpEventOutbox"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/test/DistEvents/DistDemoApp/Migrations/20210908063422_Added_Outbox.cs b/test/DistEvents/DistDemoApp/Migrations/20210908063422_Added_Outbox.cs new file mode 100644 index 0000000000..2954acdac7 --- /dev/null +++ b/test/DistEvents/DistDemoApp/Migrations/20210908063422_Added_Outbox.cs @@ -0,0 +1,31 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace DistDemoApp.Migrations +{ + public partial class Added_Outbox : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "AbpEventOutbox", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true), + EventName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + EventData = table.Column(type: "varbinary(max)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AbpEventOutbox", x => x.Id); + }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "AbpEventOutbox"); + } + } +} diff --git a/test/DistEvents/DistDemoApp/Migrations/TodoDbContextModelSnapshot.cs b/test/DistEvents/DistDemoApp/Migrations/TodoDbContextModelSnapshot.cs index 99f0f92ab7..91d7bc0cc7 100644 --- a/test/DistEvents/DistDemoApp/Migrations/TodoDbContextModelSnapshot.cs +++ b/test/DistEvents/DistDemoApp/Migrations/TodoDbContextModelSnapshot.cs @@ -87,6 +87,29 @@ namespace DistDemoApp.Migrations b.ToTable("TodoSummaries"); }); + + modelBuilder.Entity("Volo.Abp.EntityFrameworkCore.DistributedEvents.OutgoingEventRecord", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("EventData") + .IsRequired() + .HasColumnType("varbinary(max)"); + + b.Property("EventName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.HasKey("Id"); + + b.ToTable("AbpEventOutbox"); + }); #pragma warning restore 612, 618 } } diff --git a/test/DistEvents/DistDemoApp/TodoDbContext.cs b/test/DistEvents/DistDemoApp/TodoDbContext.cs index 000f18c802..3db006535a 100644 --- a/test/DistEvents/DistDemoApp/TodoDbContext.cs +++ b/test/DistEvents/DistDemoApp/TodoDbContext.cs @@ -1,13 +1,15 @@ using Microsoft.EntityFrameworkCore; using Volo.Abp.Domain.Entities; using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore.DistributedEvents; namespace DistDemoApp { - public class TodoDbContext : AbpDbContext + public class TodoDbContext : AbpDbContext, IHasEventOutbox { public DbSet TodoItems { get; set; } public DbSet TodoSummaries { get; set; } + public DbSet OutgoingEventRecords { get; set; } public TodoDbContext(DbContextOptions options) : base(options) @@ -18,6 +20,8 @@ namespace DistDemoApp protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); + + modelBuilder.ConfigureEventOutbox(); modelBuilder.Entity(b => { diff --git a/test/DistEvents/DistDemoApp/TodoEventHandler.cs b/test/DistEvents/DistDemoApp/TodoEventHandler.cs index 73c7040732..c7fd43aea3 100644 --- a/test/DistEvents/DistDemoApp/TodoEventHandler.cs +++ b/test/DistEvents/DistDemoApp/TodoEventHandler.cs @@ -42,7 +42,7 @@ namespace DistDemoApp Console.WriteLine("Increased total count: " + todoSummary); - throw new ApplicationException("Thrown to rollback the UOW!"); + //throw new ApplicationException("Thrown to rollback the UOW!"); } public async Task HandleEventAsync(EntityDeletedEto eventData) diff --git a/test/DistEvents/DistDemoApp/appsettings.json b/test/DistEvents/DistDemoApp/appsettings.json index 6bb7ba54ca..8f4773ae6a 100644 --- a/test/DistEvents/DistDemoApp/appsettings.json +++ b/test/DistEvents/DistDemoApp/appsettings.json @@ -1,5 +1,16 @@ { "ConnectionStrings": { "Default": "Server=(LocalDb)\\MSSQLLocalDB;Database=DistEventsDemo;Trusted_Connection=True" + }, + "RabbitMQ": { + "Connections": { + "Default": { + "HostName": "localhost" + } + }, + "EventBus": { + "ClientName": "DistDemoApp", + "ExchangeName": "DistDemo" + } } } \ No newline at end of file