-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add domain & integration events (#11)
Co-authored-by: Artem Leshchev <artem.leshchev@dxc.com>
- Loading branch information
Showing
18 changed files
with
298 additions
and
3 deletions.
There are no files selected for viewing
8 changes: 8 additions & 0 deletions
8
src/Bss.Platform.Events.Abstractions/Bss.Platform.Events.Abstractions.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<PackageId>Luxoft.Bss.Platform.Events.Abstractions</PackageId> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<PackageReference Include="MediatR"/> | ||
</ItemGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
using MediatR; | ||
|
||
namespace Bss.Platform.Events.Abstractions; | ||
|
||
public interface IDomainEvent : INotification; |
6 changes: 6 additions & 0 deletions
6
src/Bss.Platform.Events.Abstractions/IDomainEventPublisher.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
namespace Bss.Platform.Events.Abstractions; | ||
|
||
public interface IDomainEventPublisher | ||
{ | ||
Task PublishAsync(IDomainEvent @event, CancellationToken cancellationToken); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
using MediatR; | ||
|
||
namespace Bss.Platform.Events.Abstractions; | ||
|
||
public interface IIntegrationEvent : INotification; |
6 changes: 6 additions & 0 deletions
6
src/Bss.Platform.Events.Abstractions/IIntegrationEventPublisher.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
namespace Bss.Platform.Events.Abstractions; | ||
|
||
public interface IIntegrationEventPublisher | ||
{ | ||
Task PublishAsync(IIntegrationEvent @event, CancellationToken cancellationToken); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<PackageId>Luxoft.Bss.Platform.Events</PackageId> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<ProjectReference Include="..\Bss.Platform.Events.Abstractions\Bss.Platform.Events.Abstractions.csproj" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<PackageReference Include="DotNetCore.CAP.Dashboard" /> | ||
<PackageReference Include="DotNetCore.CAP.RabbitMQ" /> | ||
<PackageReference Include="DotNetCore.CAP.SqlServer" /> | ||
<PackageReference Include="Savorboard.CAP.InMemoryMessageQueue" /> | ||
</ItemGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
using Bss.Platform.Events.Abstractions; | ||
using Bss.Platform.Events.Interfaces; | ||
|
||
namespace Bss.Platform.Events; | ||
|
||
internal class CapConsumerExecutor<TEvent>(IIntegrationEventProcessor eventProcessor) | ||
where TEvent : IIntegrationEvent | ||
{ | ||
public Task HandleAsync(TEvent @event, CancellationToken cancellationToken) => eventProcessor.ProcessAsync(@event, cancellationToken); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
using System.Reflection; | ||
|
||
using Bss.Platform.Events.Abstractions; | ||
|
||
using DotNetCore.CAP; | ||
using DotNetCore.CAP.Internal; | ||
|
||
using Microsoft.Extensions.DependencyInjection; | ||
using Microsoft.Extensions.Options; | ||
|
||
namespace Bss.Platform.Events; | ||
|
||
public class CapConsumerServiceSelector(IServiceProvider serviceProvider, Assembly assembly) | ||
: ConsumerServiceSelector(serviceProvider) | ||
{ | ||
protected override IEnumerable<ConsumerExecutorDescriptor> FindConsumersFromControllerTypes() => []; | ||
|
||
protected override IEnumerable<ConsumerExecutorDescriptor> FindConsumersFromInterfaceTypes(IServiceProvider provider) | ||
{ | ||
var namePrefix = provider.GetRequiredService<IOptions<CapOptions>>().Value.TopicNamePrefix; | ||
|
||
return assembly | ||
.ExportedTypes | ||
.Where(x => typeof(IIntegrationEvent).IsAssignableFrom(x) && x is { IsInterface: false, IsAbstract: false }) | ||
.Select(x => this.CreateExecutorDescriptor(typeof(CapConsumerExecutor<>).MakeGenericType(x), x, namePrefix)); | ||
} | ||
|
||
private ConsumerExecutorDescriptor CreateExecutorDescriptor(Type executor, Type @event, string? namePrefix) | ||
{ | ||
var subscribeAttribute = new CapSubscribeAttribute(@event.Name); | ||
this.SetSubscribeAttribute(subscribeAttribute); | ||
|
||
var methodInfo = executor | ||
.GetRuntimeMethods() | ||
.Single(x => x.Name.Contains(nameof(CapConsumerExecutor<IIntegrationEvent>.HandleAsync))); | ||
|
||
var methodParameters = methodInfo.GetParameters(); | ||
return new ConsumerExecutorDescriptor | ||
{ | ||
Attribute = subscribeAttribute, | ||
ClassAttribute = null, | ||
MethodInfo = methodInfo, | ||
ImplTypeInfo = executor.GetTypeInfo(), | ||
ServiceTypeInfo = null, | ||
TopicNamePrefix = namePrefix, | ||
Parameters = new List<ParameterDescriptor> | ||
{ | ||
new() { ParameterType = methodParameters[0].ParameterType, IsFromCap = false }, | ||
new() { ParameterType = methodParameters[1].ParameterType, IsFromCap = true } | ||
} | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
using System.Data; | ||
using System.Reflection; | ||
|
||
using Bss.Platform.Events.Abstractions; | ||
using Bss.Platform.Events.Interfaces; | ||
using Bss.Platform.Events.Models; | ||
using Bss.Platform.Events.Publishers; | ||
|
||
using DotNetCore.CAP; | ||
using DotNetCore.CAP.Internal; | ||
|
||
using Microsoft.Extensions.DependencyInjection; | ||
|
||
using Savorboard.CAP.InMemoryMessageQueue; | ||
|
||
namespace Bss.Platform.Events; | ||
|
||
public static class DependencyInjection | ||
{ | ||
public static IServiceCollection AddPlatformDomainEvents(this IServiceCollection services) => | ||
services.AddScoped<IDomainEventPublisher, DomainEventPublisher>(); | ||
|
||
public static IServiceCollection AddPlatformIntegrationEvents<TEventProcessor>( | ||
this IServiceCollection services, | ||
Assembly eventsAssembly, | ||
Action<IntegrationEventsOptions>? setup = null) | ||
where TEventProcessor : class, IIntegrationEventProcessor | ||
{ | ||
services | ||
.AddSingleton<IIntegrationEventProcessor, TEventProcessor>() | ||
.AddSingleton<IConsumerServiceSelector, CapConsumerServiceSelector>(x => new CapConsumerServiceSelector(x, eventsAssembly)) | ||
.AddScoped<IIntegrationEventPublisher, IntegrationEventPublisher>() | ||
.AddScoped<ICapTransaction>( | ||
serviceProvider => | ||
{ | ||
var capTransaction = ActivatorUtilities.CreateInstance<SqlServerCapTransaction>(serviceProvider); | ||
capTransaction.DbTransaction = serviceProvider.GetRequiredService<IDbTransaction>(); | ||
return capTransaction; | ||
}) | ||
.AddCap( | ||
x => | ||
{ | ||
var eventsOptions = IntegrationEventsOptions.Default; | ||
setup?.Invoke(eventsOptions); | ||
|
||
x.FailedRetryCount = eventsOptions.FailedRetryCount; | ||
x.SucceedMessageExpiredAfter = (int)TimeSpan.FromDays(eventsOptions.RetentionDays).TotalSeconds; | ||
|
||
x.UseSqlServer( | ||
o => | ||
{ | ||
o.ConnectionString = eventsOptions.SqlServer.ConnectionString; | ||
o.Schema = eventsOptions.SqlServer.Schema; | ||
}); | ||
|
||
x.UseDashboard(o => o.PathMatch = eventsOptions.DashboardPath); | ||
|
||
if (!eventsOptions.MessageQueue.Enable) | ||
{ | ||
x.UseInMemoryMessageQueue(); | ||
return; | ||
} | ||
|
||
x.DefaultGroupName = eventsOptions.MessageQueue.ExchangeName; | ||
x.UseRabbitMQ( | ||
o => | ||
{ | ||
o.HostName = eventsOptions.MessageQueue.Host; | ||
o.Port = eventsOptions.MessageQueue.Port; | ||
o.VirtualHost = eventsOptions.MessageQueue.VirtualHost; | ||
o.Password = eventsOptions.MessageQueue.Secret; | ||
o.UserName = eventsOptions.MessageQueue.UserName; | ||
o.ExchangeName = eventsOptions.MessageQueue.ExchangeName; | ||
o.BasicQosOptions = new RabbitMQOptions.BasicQos(1, true); | ||
}); | ||
}); | ||
|
||
return services; | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
src/Bss.Platform.Events/Interfaces/IIntegrationEventProcessor.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
using Bss.Platform.Events.Abstractions; | ||
|
||
namespace Bss.Platform.Events.Interfaces; | ||
|
||
public interface IIntegrationEventProcessor | ||
{ | ||
Task ProcessAsync(IIntegrationEvent @event, CancellationToken token); | ||
} |
18 changes: 18 additions & 0 deletions
18
src/Bss.Platform.Events/Models/IntegrationEventsMessageQueueOptions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
namespace Bss.Platform.Events.Models; | ||
|
||
public class IntegrationEventsMessageQueueOptions | ||
{ | ||
public bool Enable { get; set; } | ||
|
||
public string Host { get; set; } = default!; | ||
|
||
public int Port { get; set; } | ||
|
||
public string UserName { get; set; } = default!; | ||
|
||
public string Secret { get; set; } = default!; | ||
|
||
public string VirtualHost { get; set; } = default!; | ||
|
||
public string ExchangeName { get; set; } = default!; | ||
} |
24 changes: 24 additions & 0 deletions
24
src/Bss.Platform.Events/Models/IntegrationEventsOptions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
namespace Bss.Platform.Events.Models; | ||
|
||
public class IntegrationEventsOptions | ||
{ | ||
public string DashboardPath { get; set; } = default!; | ||
|
||
public int FailedRetryCount { get; set; } | ||
|
||
public int RetentionDays { get; set; } | ||
|
||
public IntegrationEventsSqlServerOptions SqlServer { get; set; } = default!; | ||
|
||
public IntegrationEventsMessageQueueOptions MessageQueue { get; set; } = default!; | ||
|
||
public static IntegrationEventsOptions Default => | ||
new() | ||
{ | ||
DashboardPath = "/admin/events", | ||
FailedRetryCount = 5, | ||
RetentionDays = 15, | ||
SqlServer = new IntegrationEventsSqlServerOptions { Schema = "events" }, | ||
MessageQueue = new IntegrationEventsMessageQueueOptions { Enable = true } | ||
}; | ||
} |
8 changes: 8 additions & 0 deletions
8
src/Bss.Platform.Events/Models/IntegrationEventsSqlServerOptions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
namespace Bss.Platform.Events.Models; | ||
|
||
public class IntegrationEventsSqlServerOptions | ||
{ | ||
public string ConnectionString { get; set; } = default!; | ||
|
||
public string Schema { get; set; } = default!; | ||
} |
10 changes: 10 additions & 0 deletions
10
src/Bss.Platform.Events/Publishers/DomainEventPublisher.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
using Bss.Platform.Events.Abstractions; | ||
|
||
using MediatR; | ||
|
||
namespace Bss.Platform.Events.Publishers; | ||
|
||
public class DomainEventPublisher(IMediator mediator) : IDomainEventPublisher | ||
{ | ||
public Task PublishAsync(IDomainEvent @event, CancellationToken cancellationToken) => mediator.Publish(@event, cancellationToken); | ||
} |
19 changes: 19 additions & 0 deletions
19
src/Bss.Platform.Events/Publishers/IntegrationEventPublisher.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
using Bss.Platform.Events.Abstractions; | ||
|
||
using DotNetCore.CAP; | ||
|
||
namespace Bss.Platform.Events.Publishers; | ||
|
||
public class IntegrationEventPublisher(ICapPublisher capPublisher, ICapTransaction capTransaction) : IIntegrationEventPublisher | ||
{ | ||
public Task PublishAsync(IIntegrationEvent @event, CancellationToken cancellationToken) | ||
{ | ||
if (capPublisher.Transaction is not null && capPublisher.Transaction != capTransaction) | ||
{ | ||
throw new Exception("There cannot be different CAP transactions within the same scope"); | ||
} | ||
|
||
capPublisher.Transaction = capTransaction; | ||
return capPublisher.PublishAsync(@event.GetType().Name, @event, cancellationToken: cancellationToken); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters