diff --git a/Eventuous.sln b/Eventuous.sln index 0c3a43c4..429e4673 100644 --- a/Eventuous.sln +++ b/Eventuous.sln @@ -171,6 +171,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Eventuous.Tests.Diagnostics EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Eventuous.Tests.Application", "src\Core\test\Eventuous.Tests.Application\Eventuous.Tests.Application.csproj", "{2C44A145-81E5-4F43-9C9A-AB3CF822AF82}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Eventuous.Process", "src\Experimental\src\Eventuous.Process\Eventuous.Process.csproj", "{C5FA2821-4565-4C63-9FC8-4A667329A66F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -361,6 +363,10 @@ Global {2C44A145-81E5-4F43-9C9A-AB3CF822AF82}.Debug|Any CPU.Build.0 = Debug|Any CPU {2C44A145-81E5-4F43-9C9A-AB3CF822AF82}.Release|Any CPU.ActiveCfg = Release|Any CPU {2C44A145-81E5-4F43-9C9A-AB3CF822AF82}.Release|Any CPU.Build.0 = Release|Any CPU + {C5FA2821-4565-4C63-9FC8-4A667329A66F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C5FA2821-4565-4C63-9FC8-4A667329A66F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C5FA2821-4565-4C63-9FC8-4A667329A66F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C5FA2821-4565-4C63-9FC8-4A667329A66F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -436,6 +442,7 @@ Global {3743969A-4635-40DE-B45C-46F80CBB5733} = {7BBD9F8E-EB6A-4E2D-84A9-AF15C1784401} {EAB7C8CC-FD8D-437B-ADB5-FA02FC62AAF9} = {0ED6785B-60EF-46B4-B938-EF04189FC8BC} {2C44A145-81E5-4F43-9C9A-AB3CF822AF82} = {0ED6785B-60EF-46B4-B938-EF04189FC8BC} + {C5FA2821-4565-4C63-9FC8-4A667329A66F} = {0E2520E7-B4A6-47E7-AED8-662C88441A84} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {0691467B-C257-46DB-BC4F-88EB7CD615B8} diff --git a/src/Core/src/Eventuous.Application/ApplicationService.cs b/src/Core/src/Eventuous.Application/ApplicationService.cs index 8966c5f9..296f7dec 100644 --- a/src/Core/src/Eventuous.Application/ApplicationService.cs +++ b/src/Core/src/Eventuous.Application/ApplicationService.cs @@ -17,7 +17,7 @@ namespace Eventuous; // [PublicAPI] public abstract class ApplicationService : IApplicationService, IApplicationService - where TAggregate : Aggregate, new() + where TAggregate : Aggregate where TState : State, new() where TId : AggregateId { protected IAggregateStore Store { get; } diff --git a/src/Core/src/Eventuous.Application/Eventuous.Application.csproj b/src/Core/src/Eventuous.Application/Eventuous.Application.csproj index 3a736624..9e3275d4 100644 --- a/src/Core/src/Eventuous.Application/Eventuous.Application.csproj +++ b/src/Core/src/Eventuous.Application/Eventuous.Application.csproj @@ -1,22 +1,13 @@ Eventuous + true + true - - - Diagnostics\DiagnosticName.cs - - - Tools\Ensure.cs - - - Tools\TaskExtensions.cs - - Eventuous.ExceptionMessages.resources diff --git a/src/Core/src/Eventuous.Persistence/Eventuous.Persistence.csproj b/src/Core/src/Eventuous.Persistence/Eventuous.Persistence.csproj index 1541933d..2f880901 100644 --- a/src/Core/src/Eventuous.Persistence/Eventuous.Persistence.csproj +++ b/src/Core/src/Eventuous.Persistence/Eventuous.Persistence.csproj @@ -1,18 +1,9 @@ Eventuous + true + true - - - Diagnostics\DiagnosticName.cs - - - Tools\TaskExtensions.cs - - - Tools\Ensure.cs - - diff --git a/src/Core/src/Eventuous.Producers/Eventuous.Producers.csproj b/src/Core/src/Eventuous.Producers/Eventuous.Producers.csproj index 5d2966e1..b2b8c326 100644 --- a/src/Core/src/Eventuous.Producers/Eventuous.Producers.csproj +++ b/src/Core/src/Eventuous.Producers/Eventuous.Producers.csproj @@ -1,19 +1,12 @@ + + true + true + - - - Diagnostics\DiagnosticName.cs - - - Tools\TaskExtensions.cs - - - Tools\Ensure.cs - - diff --git a/src/Core/src/Eventuous.Subscriptions/Eventuous.Subscriptions.csproj b/src/Core/src/Eventuous.Subscriptions/Eventuous.Subscriptions.csproj index 4a070d30..73c6c90f 100644 --- a/src/Core/src/Eventuous.Subscriptions/Eventuous.Subscriptions.csproj +++ b/src/Core/src/Eventuous.Subscriptions/Eventuous.Subscriptions.csproj @@ -1,6 +1,8 @@ true + true + true @@ -15,15 +17,6 @@ - - Diagnostics\DiagnosticName.cs - - - Tools\Ensure.cs - - - Tools\TaskExtensions.cs - Tools\TypeExtensions.cs diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 4d09c60a..18d7db51 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -77,6 +77,19 @@ + + + Tools\TaskExtensions.cs + + + Tools\Ensure.cs + + + + + Diagnostics\DiagnosticName.cs + + diff --git a/src/EventStore/src/Eventuous.EventStore/Eventuous.EventStore.csproj b/src/EventStore/src/Eventuous.EventStore/Eventuous.EventStore.csproj index a7154073..d5350337 100644 --- a/src/EventStore/src/Eventuous.EventStore/Eventuous.EventStore.csproj +++ b/src/EventStore/src/Eventuous.EventStore/Eventuous.EventStore.csproj @@ -1,28 +1,23 @@ + + true + - - + + - - - - + + + + - - - + + + - - - - - Tools\TaskExtensions.cs - - - Tools\Ensure.cs - + diff --git a/src/Experimental/src/Eventuous.ElasticSearch/Eventuous.ElasticSearch.csproj b/src/Experimental/src/Eventuous.ElasticSearch/Eventuous.ElasticSearch.csproj index 92b01269..ae4c87c8 100644 --- a/src/Experimental/src/Eventuous.ElasticSearch/Eventuous.ElasticSearch.csproj +++ b/src/Experimental/src/Eventuous.ElasticSearch/Eventuous.ElasticSearch.csproj @@ -1,4 +1,7 @@ + + true + @@ -8,12 +11,4 @@ - - - Tools\TaskExtensions.cs - - - Tools\Ensure.cs - - diff --git a/src/Experimental/src/Eventuous.Process/Eventuous.Process.csproj b/src/Experimental/src/Eventuous.Process/Eventuous.Process.csproj new file mode 100644 index 00000000..b4f23f34 --- /dev/null +++ b/src/Experimental/src/Eventuous.Process/Eventuous.Process.csproj @@ -0,0 +1,11 @@ + + + true + + + + + + + + diff --git a/src/Experimental/src/Eventuous.Process/Process.cs b/src/Experimental/src/Eventuous.Process/Process.cs new file mode 100644 index 00000000..992105fb --- /dev/null +++ b/src/Experimental/src/Eventuous.Process/Process.cs @@ -0,0 +1,12 @@ +// Copyright (C) Ubiquitous AS. All rights reserved +// Licensed under the Apache License, Version 2.0. + +namespace Eventuous.Process; + +public abstract record ProcessId : AggregateId { + protected ProcessId(string value) : base(value) { } +} + +public abstract record ProcessState : State where T : ProcessState { } + +public abstract class Process : Aggregate where TState : ProcessState, new() { } \ No newline at end of file diff --git a/src/Experimental/src/Eventuous.Process/ProcessManager.cs b/src/Experimental/src/Eventuous.Process/ProcessManager.cs new file mode 100644 index 00000000..1182d5cd --- /dev/null +++ b/src/Experimental/src/Eventuous.Process/ProcessManager.cs @@ -0,0 +1,14 @@ +// Copyright (C) Ubiquitous AS. All rights reserved +// Licensed under the Apache License, Version 2.0. + +namespace Eventuous.Process; + +public abstract class ProcessManager : ApplicationService + where T : Process where TState : ProcessState, new() where TId : ProcessId { + protected ProcessManager( + IAggregateStore store, + AggregateFactoryRegistry? factoryRegistry = null, + StreamNameMap? streamNameMap = null, + TypeMapper? typeMap = null + ) : base(store, factoryRegistry, streamNameMap, typeMap) { } +} \ No newline at end of file diff --git a/src/Gateway/src/Eventuous.Gateway/Eventuous.Gateway.csproj b/src/Gateway/src/Eventuous.Gateway/Eventuous.Gateway.csproj index 00dd6dfa..712a528f 100644 --- a/src/Gateway/src/Eventuous.Gateway/Eventuous.Gateway.csproj +++ b/src/Gateway/src/Eventuous.Gateway/Eventuous.Gateway.csproj @@ -1,18 +1,16 @@ + + true + - - + + - - + + - - - - - Tools\TaskExtensions.cs - + diff --git a/src/GooglePubSub/src/Eventuous.GooglePubSub/Eventuous.GooglePubSub.csproj b/src/GooglePubSub/src/Eventuous.GooglePubSub/Eventuous.GooglePubSub.csproj index e6ec729d..ab659466 100644 --- a/src/GooglePubSub/src/Eventuous.GooglePubSub/Eventuous.GooglePubSub.csproj +++ b/src/GooglePubSub/src/Eventuous.GooglePubSub/Eventuous.GooglePubSub.csproj @@ -1,28 +1,21 @@ README.md + true - + - - + + - + - - - - - - - Tools\TaskExtensions.cs - - - Tools\Ensure.cs - + + + diff --git a/src/Kafka/src/Eventuous.Kafka/Eventuous.Kafka.csproj b/src/Kafka/src/Eventuous.Kafka/Eventuous.Kafka.csproj index 293c888a..564ec229 100644 --- a/src/Kafka/src/Eventuous.Kafka/Eventuous.Kafka.csproj +++ b/src/Kafka/src/Eventuous.Kafka/Eventuous.Kafka.csproj @@ -1,26 +1,19 @@ README.md + true - - + + - + - + - - - - - Tools\TaskExtensions.cs - - - Tools\Ensure.cs - + diff --git a/src/Mongo/src/Eventuous.Projections.MongoDB/Eventuous.Projections.MongoDB.csproj b/src/Mongo/src/Eventuous.Projections.MongoDB/Eventuous.Projections.MongoDB.csproj index b8b4edbe..3ae72485 100644 --- a/src/Mongo/src/Eventuous.Projections.MongoDB/Eventuous.Projections.MongoDB.csproj +++ b/src/Mongo/src/Eventuous.Projections.MongoDB/Eventuous.Projections.MongoDB.csproj @@ -1,28 +1,21 @@ README.md + true - - + + - + - - + + - - - - - - Tools\TaskExtensions.cs - - - Tools\Ensure.cs - + + diff --git a/src/Postgres/src/Eventuous.Postgresql/Eventuous.Postgresql.csproj b/src/Postgres/src/Eventuous.Postgresql/Eventuous.Postgresql.csproj index c9a67e82..d10b0fe8 100644 --- a/src/Postgres/src/Eventuous.Postgresql/Eventuous.Postgresql.csproj +++ b/src/Postgres/src/Eventuous.Postgresql/Eventuous.Postgresql.csproj @@ -1,4 +1,7 @@ + + true + @@ -15,12 +18,4 @@ - - - Tools\TaskExtensions.cs - - - Tools\Ensure.cs - - - + \ No newline at end of file diff --git a/src/RabbitMq/src/Eventuous.RabbitMq/Eventuous.RabbitMq.csproj b/src/RabbitMq/src/Eventuous.RabbitMq/Eventuous.RabbitMq.csproj index c968ebc2..c6c05e1b 100644 --- a/src/RabbitMq/src/Eventuous.RabbitMq/Eventuous.RabbitMq.csproj +++ b/src/RabbitMq/src/Eventuous.RabbitMq/Eventuous.RabbitMq.csproj @@ -1,27 +1,20 @@ README.md + true - + - - + + - + - - - - - - Tools\TaskExtensions.cs - - - Tools\Ensure.cs - + + diff --git a/src/RabbitMq/src/Eventuous.RabbitMq/Subscriptions/RabbitMqSubscription.cs b/src/RabbitMq/src/Eventuous.RabbitMq/Subscriptions/RabbitMqSubscription.cs index 7400ac25..fb0af104 100644 --- a/src/RabbitMq/src/Eventuous.RabbitMq/Subscriptions/RabbitMqSubscription.cs +++ b/src/RabbitMq/src/Eventuous.RabbitMq/Subscriptions/RabbitMqSubscription.cs @@ -12,7 +12,7 @@ namespace Eventuous.RabbitMq.Subscriptions; /// -/// RabbitMQ subscription service +/// RabbitMQ subscription. /// [PublicAPI] public class RabbitMqSubscription : EventSubscription { @@ -94,33 +94,34 @@ public RabbitMqSubscription( ) { } protected override ValueTask Subscribe(CancellationToken cancellationToken) { - var exchange = Ensure.NotEmptyString(Options.Exchange); + var exchangeName = Ensure.NotEmptyString(Options.Exchange); + var queueName = Options.Queue ?? Options.SubscriptionId; - Log.InfoLog?.Log("Ensuring exchange", exchange); + Log.InfoLog?.Log("Ensuring exchange", exchangeName); _channel.ExchangeDeclare( - exchange, + exchangeName, Options.ExchangeOptions?.Type ?? ExchangeType.Fanout, Options.ExchangeOptions?.Durable ?? true, Options.ExchangeOptions?.AutoDelete ?? true, Options.ExchangeOptions?.Arguments ); - Log.InfoLog?.Log("Ensuring queue", Options.SubscriptionId); + Log.InfoLog?.Log("Ensuring queue", queueName); _channel.QueueDeclare( - Options.SubscriptionId, + queueName, Options.QueueOptions?.Durable ?? true, Options.QueueOptions?.Exclusive ?? false, Options.QueueOptions?.AutoDelete ?? false, Options.QueueOptions?.Arguments ); - Log.InfoLog?.Log("Binding exchange to queue:", exchange, Options.SubscriptionId); + Log.InfoLog?.Log("Binding exchange to queue:", exchangeName, queueName); _channel.QueueBind( - Options.SubscriptionId, - exchange, + queueName, + exchangeName, Options.BindingOptions?.RoutingKey ?? "", Options.BindingOptions?.Arguments ); diff --git a/src/RabbitMq/src/Eventuous.RabbitMq/Subscriptions/RabbitMqSubscriptionOptions.cs b/src/RabbitMq/src/Eventuous.RabbitMq/Subscriptions/RabbitMqSubscriptionOptions.cs index 2a6b63f5..05fe0d58 100644 --- a/src/RabbitMq/src/Eventuous.RabbitMq/Subscriptions/RabbitMqSubscriptionOptions.cs +++ b/src/RabbitMq/src/Eventuous.RabbitMq/Subscriptions/RabbitMqSubscriptionOptions.cs @@ -6,39 +6,116 @@ namespace Eventuous.RabbitMq.Subscriptions; +/// +/// Options for a RabbitMQ subscription +/// [PublicAPI] public record RabbitMqSubscriptionOptions : SubscriptionOptions { - public string Exchange { get; set; } = null!; - public HandleEventProcessingFailure? FailureHandler { get; set; } - public RabbitMqExchangeOptions? ExchangeOptions { get; set; } = new(); - public RabbitMqQueueOptions? QueueOptions { get; set; } = new(); - public RabbitMqBindingOptions? BindingOptions { get; set; } = new(); + /// + /// Exchange for where the subscription binds to. + /// + public string Exchange { get; set; } = null!; - public uint ConcurrencyLimit { get; set; } = 1; - public ushort PrefetchCount { get; set; } + /// + /// Queue name for the subscription. If it's null, the subscription id will be used as the queue name. + /// + public string? Queue { get; set; } + /// + /// Alternative way to deal with failed messages. The default strategy is to requeue. + /// + public HandleEventProcessingFailure? FailureHandler { get; set; } + + /// + /// RabbitMQ exchange options (optional). + /// + public RabbitMqExchangeOptions? ExchangeOptions { get; set; } = new(); + + /// + /// RabbitMQ queue options (optional). + /// + public RabbitMqQueueOptions? QueueOptions { get; set; } = new(); + + /// + /// RabbitMQ queue to exchange binding options (optional). + /// + public RabbitMqBindingOptions? BindingOptions { get; set; } = new(); + + /// + /// The number of consumers running in parallel. Default is 1. + /// + public uint ConcurrencyLimit { get; set; } = 1; + + /// + /// Prefetch count. Will be adjusted automatically if not set. + /// + public ushort PrefetchCount { get; set; } + + /// + /// RabbitMQ exchange options. + /// [PublicAPI] public record RabbitMqExchangeOptions { - public string Type { get; set; } = ExchangeType.Fanout; - public bool AutoDelete { get; set; } - public bool Durable { get; set; } = true; + /// + /// Exchange type, default is fan out. + /// + public string Type { get; set; } = ExchangeType.Fanout; + /// + /// Should the exchange be deleted when the service shuts down. Default is false. + /// + public bool AutoDelete { get; set; } + + /// + /// Should the exchange be durable or not. Default is true. + /// + public bool Durable { get; set; } = true; + + /// + /// Exchange arguments, passed directly to RMQ client. + /// public IDictionary? Arguments { get; set; } } + /// + /// RabbitMQ queue options + /// [PublicAPI] public record RabbitMqQueueOptions { - public bool Durable { get; set; } = true; - public bool Exclusive { get; set; } + /// + /// Should the queue be durable. Default is true. + /// + public bool Durable { get; set; } = true; + + /// + /// Should the queue be exclusive. Default is false. + /// + public bool Exclusive { get; set; } + + /// + /// Should the queue be deleted when the service shuts down. Default is false. + /// public bool AutoDelete { get; set; } + /// + /// Queue arguments, passed directly to RMQ client + /// public IDictionary? Arguments { get; set; } } + /// + /// RabbitMQ queue to exchange binding options + /// [PublicAPI] public record RabbitMqBindingOptions { + /// + /// Routing key for the binding. Learn more in RMQ documentation. + /// public string? RoutingKey { get; set; } + /// + /// Binding arguments. Passed directly to RMQ client. + /// public IDictionary? Arguments { get; set; } } } \ No newline at end of file diff --git a/src/SqlServer/src/Eventuous.SqlServer/Eventuous.SqlServer.csproj b/src/SqlServer/src/Eventuous.SqlServer/Eventuous.SqlServer.csproj index f5b98f89..8b97309f 100644 --- a/src/SqlServer/src/Eventuous.SqlServer/Eventuous.SqlServer.csproj +++ b/src/SqlServer/src/Eventuous.SqlServer/Eventuous.SqlServer.csproj @@ -1,26 +1,21 @@ + + true + - - + + - - + + - - - - - - - - - - Tools\TaskExtensions.cs - - - Tools\Ensure.cs - + + + + + +