From 07127a4b27f163135243bd2bb6c2bedcdbfe1c6a Mon Sep 17 00:00:00 2001 From: Chris Patterson Date: Tue, 19 Apr 2022 17:44:44 -0500 Subject: [PATCH] Updated to MT v8 --- src/SampleBatch.Api/SampleBatch.Api.csproj | 8 +-- src/SampleBatch.Common/JsonHelper.cs | 17 ----- src/SampleBatch.Common/JsonValueComparer.cs | 64 ------------------- src/SampleBatch.Common/JsonValueConverter.cs | 16 ----- .../SampleBatch.Common.csproj | 4 +- .../CancelOrder/CancelOrderActivity.cs | 5 +- .../SuspendOrder/SuspendOrderActivity.cs | 3 +- .../Consumers/SubmitBatchConsumer.cs | 9 --- .../SampleBatch.Components.csproj | 4 +- .../SampleBatchDbContext.cs | 2 +- .../{JobState.cs => BatchJobState.cs} | 4 +- ...tateMachine.cs => BatchJobStateMachine.cs} | 43 +++++-------- .../StateMachines/BatchState.cs | 7 +- .../BatchStateEntityConfiguration.cs | 2 +- .../StateMachines/BatchStateMachine.cs | 5 +- .../JobStateEntityConfiguration.cs | 4 +- .../SampleBatch.Contracts.csproj | 2 +- src/SampleBatch.Service/Program.cs | 6 +- .../SampleBatch.Service.csproj | 29 ++++----- .../Integration/BatchStateMachineTests.cs | 5 +- .../SampleBatch.Tests.csproj | 7 +- .../Unit/BatchStateMachineTests.cs | 4 +- 22 files changed, 64 insertions(+), 186 deletions(-) delete mode 100644 src/SampleBatch.Common/JsonHelper.cs delete mode 100644 src/SampleBatch.Common/JsonValueComparer.cs delete mode 100644 src/SampleBatch.Common/JsonValueConverter.cs rename src/SampleBatch.Components/StateMachines/{JobState.cs => BatchJobState.cs} (92%) rename src/SampleBatch.Components/StateMachines/{JobStateMachine.cs => BatchJobStateMachine.cs} (73%) diff --git a/src/SampleBatch.Api/SampleBatch.Api.csproj b/src/SampleBatch.Api/SampleBatch.Api.csproj index da673e9..70f8bba 100644 --- a/src/SampleBatch.Api/SampleBatch.Api.csproj +++ b/src/SampleBatch.Api/SampleBatch.Api.csproj @@ -13,11 +13,9 @@ - - - - - + + + diff --git a/src/SampleBatch.Common/JsonHelper.cs b/src/SampleBatch.Common/JsonHelper.cs deleted file mode 100644 index 48d27cd..0000000 --- a/src/SampleBatch.Common/JsonHelper.cs +++ /dev/null @@ -1,17 +0,0 @@ -using Newtonsoft.Json; - -namespace SampleBatch.Common -{ - internal static class JsonHelper - { - public static T Deserialize(string json) where T : class - { - return string.IsNullOrWhiteSpace(json) ? null : JsonConvert.DeserializeObject(json); - } - - public static string Serialize(T obj) where T : class - { - return obj == null ? null : JsonConvert.SerializeObject(obj); - } - } -} diff --git a/src/SampleBatch.Common/JsonValueComparer.cs b/src/SampleBatch.Common/JsonValueComparer.cs deleted file mode 100644 index e29b03b..0000000 --- a/src/SampleBatch.Common/JsonValueComparer.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.ChangeTracking; -using Newtonsoft.Json; - -namespace SampleBatch.Common -{ - /// - /// Compares two objects. - /// Required to make EF Core change tracking work for complex value converted objects. - /// - /// - /// For objects that implement and , - /// those implementations will be used for cloning and equality. - /// For plain objects, fall back to deep equality comparison using JSON serialization - /// (safe, but inefficient). - /// - public class JsonValueComparer : ValueComparer - { - private static string Json(T instance) - { - return JsonConvert.SerializeObject(instance); - } - - private static T DoGetSnapshot(T instance) - { - - if (instance is ICloneable cloneable) - return (T)cloneable.Clone(); - - var result = (T)JsonConvert.DeserializeObject(Json(instance), typeof(T)); - return result; - - } - - private static int DoGetHashCode(T instance) - { - - if (instance is IEquatable) - return instance.GetHashCode(); - - return Json(instance).GetHashCode(); - - } - - private static bool DoEquals(T left, T right) - { - - if (left is IEquatable equatable) - return equatable.Equals(right); - - var result = Json(left).Equals(Json(right)); - return result; - - } - - public JsonValueComparer() : base( - (t1, t2) => DoEquals(t1, t2), - t => DoGetHashCode(t), - t => DoGetSnapshot(t)) - { - } - - } -} diff --git a/src/SampleBatch.Common/JsonValueConverter.cs b/src/SampleBatch.Common/JsonValueConverter.cs deleted file mode 100644 index fe8f85b..0000000 --- a/src/SampleBatch.Common/JsonValueConverter.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; - -namespace SampleBatch.Common -{ - /// - /// Converts complex field to/from JSON string. - /// - /// Model field type. - /// See more: https://docs.microsoft.com/en-us/ef/core/modeling/value-conversions - public class JsonValueConverter : ValueConverter where T : class - { - public JsonValueConverter(ConverterMappingHints hints = default) : - base(v => JsonHelper.Serialize(v), v => JsonHelper.Deserialize(v), hints) - { } - } -} diff --git a/src/SampleBatch.Common/SampleBatch.Common.csproj b/src/SampleBatch.Common/SampleBatch.Common.csproj index ba907f7..0b71923 100644 --- a/src/SampleBatch.Common/SampleBatch.Common.csproj +++ b/src/SampleBatch.Common/SampleBatch.Common.csproj @@ -6,8 +6,8 @@ - - + + diff --git a/src/SampleBatch.Components/Activities/CancelOrder/CancelOrderActivity.cs b/src/SampleBatch.Components/Activities/CancelOrder/CancelOrderActivity.cs index 7c042bd..a7530c0 100644 --- a/src/SampleBatch.Components/Activities/CancelOrder/CancelOrderActivity.cs +++ b/src/SampleBatch.Components/Activities/CancelOrder/CancelOrderActivity.cs @@ -2,15 +2,14 @@ { using System; using System.Threading.Tasks; - using MassTransit.Courier; - using MassTransit.Courier.Exceptions; + using MassTransit; using Microsoft.Extensions.Logging; public class CancelOrderActivity : IExecuteActivity { - private readonly SampleBatchDbContext _dbContext; + readonly SampleBatchDbContext _dbContext; readonly ILogger _logger; public CancelOrderActivity(SampleBatchDbContext dbContext, ILoggerFactory loggerFactory) diff --git a/src/SampleBatch.Components/Activities/SuspendOrder/SuspendOrderActivity.cs b/src/SampleBatch.Components/Activities/SuspendOrder/SuspendOrderActivity.cs index 8cc1938..49980cc 100644 --- a/src/SampleBatch.Components/Activities/SuspendOrder/SuspendOrderActivity.cs +++ b/src/SampleBatch.Components/Activities/SuspendOrder/SuspendOrderActivity.cs @@ -2,8 +2,7 @@ { using System; using System.Threading.Tasks; - using MassTransit.Courier; - using MassTransit.Courier.Exceptions; + using MassTransit; using Microsoft.Extensions.Logging; diff --git a/src/SampleBatch.Components/Consumers/SubmitBatchConsumer.cs b/src/SampleBatch.Components/Consumers/SubmitBatchConsumer.cs index c3b1c20..7e89277 100644 --- a/src/SampleBatch.Components/Consumers/SubmitBatchConsumer.cs +++ b/src/SampleBatch.Components/Consumers/SubmitBatchConsumer.cs @@ -3,7 +3,6 @@ using System.Threading.Tasks; using Contracts; using MassTransit; - using MassTransit.Definition; using Microsoft.Extensions.Logging; @@ -66,14 +65,6 @@ public class SubmitBatchConsumerDefinition : public SubmitBatchConsumerDefinition() { ConcurrentMessageLimit = 10; - - Request(x => - { - x.Responds(); - x.Responds(); - - x.Publishes(); - }); } } } \ No newline at end of file diff --git a/src/SampleBatch.Components/SampleBatch.Components.csproj b/src/SampleBatch.Components/SampleBatch.Components.csproj index af4eb72..4228c7e 100644 --- a/src/SampleBatch.Components/SampleBatch.Components.csproj +++ b/src/SampleBatch.Components/SampleBatch.Components.csproj @@ -6,8 +6,8 @@ - - + + diff --git a/src/SampleBatch.Components/SampleBatchDbContext.cs b/src/SampleBatch.Components/SampleBatchDbContext.cs index c83dabe..072a77a 100644 --- a/src/SampleBatch.Components/SampleBatchDbContext.cs +++ b/src/SampleBatch.Components/SampleBatchDbContext.cs @@ -20,6 +20,6 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) } public DbSet BatchStates { get; set; } - public DbSet JobStates { get; set; } + public DbSet JobStates { get; set; } } } diff --git a/src/SampleBatch.Components/StateMachines/JobState.cs b/src/SampleBatch.Components/StateMachines/BatchJobState.cs similarity index 92% rename from src/SampleBatch.Components/StateMachines/JobState.cs rename to src/SampleBatch.Components/StateMachines/BatchJobState.cs index 9b45659..0bc346b 100644 --- a/src/SampleBatch.Components/StateMachines/JobState.cs +++ b/src/SampleBatch.Components/StateMachines/BatchJobState.cs @@ -1,11 +1,11 @@ namespace SampleBatch.Components.StateMachines { using System; - using Automatonymous; using Contracts.Enums; + using MassTransit; - public class JobState : + public class BatchJobState : SagaStateMachineInstance { public Guid BatchId { get; set; } diff --git a/src/SampleBatch.Components/StateMachines/JobStateMachine.cs b/src/SampleBatch.Components/StateMachines/BatchJobStateMachine.cs similarity index 73% rename from src/SampleBatch.Components/StateMachines/JobStateMachine.cs rename to src/SampleBatch.Components/StateMachines/BatchJobStateMachine.cs index d4af485..168a4c3 100644 --- a/src/SampleBatch.Components/StateMachines/JobStateMachine.cs +++ b/src/SampleBatch.Components/StateMachines/BatchJobStateMachine.cs @@ -1,18 +1,14 @@ namespace SampleBatch.Components.StateMachines { using System; - using System.Threading.Tasks; - using Automatonymous; using Contracts; - using GreenPipes; using MassTransit; - using MassTransit.Definition; - public class JobStateMachine : - MassTransitStateMachine + public class BatchJobStateMachine : + MassTransitStateMachine { - public JobStateMachine() + public BatchJobStateMachine() { InstanceState(x => x.CurrentState); @@ -25,7 +21,14 @@ public JobStateMachine() .Then(context => Touch(context.Instance, context.Data.Timestamp)) .Then(context => SetReceiveTimestamp(context.Instance, context.Data.Timestamp)) .Then(Initialize) - .ThenAsync(InitiateProcessing) + .Send(context => context.Init(new + { + BatchJobId = context.Instance.CorrelationId, + Timestamp = DateTime.UtcNow, + context.Instance.BatchId, + context.Instance.OrderId, + context.Instance.Action + })) .TransitionTo(Received)); During(Received, @@ -58,7 +61,7 @@ public JobStateMachine() public Event BatchJobFailed { get; private set; } public Event BatchJobCompleted { get; private set; } - static void Touch(JobState state, DateTime timestamp) + static void Touch(BatchJobState state, DateTime timestamp) { state.CreateTimestamp ??= timestamp; @@ -66,47 +69,35 @@ static void Touch(JobState state, DateTime timestamp) state.UpdateTimestamp = timestamp; } - static void SetReceiveTimestamp(JobState state, DateTime timestamp) + static void SetReceiveTimestamp(BatchJobState state, DateTime timestamp) { if (!state.ReceiveTimestamp.HasValue || state.ReceiveTimestamp.Value > timestamp) state.ReceiveTimestamp = timestamp; } - static void Initialize(BehaviorContext context) + static void Initialize(BehaviorContext context) { InitializeInstance(context.Instance, context.Data); } - static void InitializeInstance(JobState instance, BatchJobReceived data) + static void InitializeInstance(BatchJobState instance, BatchJobReceived data) { instance.Action = data.Action; instance.OrderId = data.OrderId; instance.BatchId = data.BatchId; } - - static async Task InitiateProcessing(BehaviorContext context) - { - await context.Send(new - { - BatchJobId = context.Instance.CorrelationId, - Timestamp = DateTime.UtcNow, - context.Instance.BatchId, - context.Instance.OrderId, - context.Instance.Action - }); - } } public class JobStateMachineDefinition : - SagaDefinition + SagaDefinition { public JobStateMachineDefinition() { ConcurrentMessageLimit = 8; } - protected override void ConfigureSaga(IReceiveEndpointConfigurator endpointConfigurator, ISagaConfigurator sagaConfigurator) + protected override void ConfigureSaga(IReceiveEndpointConfigurator endpointConfigurator, ISagaConfigurator sagaConfigurator) { sagaConfigurator.UseMessageRetry(r => r.Immediate(5)); sagaConfigurator.UseInMemoryOutbox(); diff --git a/src/SampleBatch.Components/StateMachines/BatchState.cs b/src/SampleBatch.Components/StateMachines/BatchState.cs index 36e3023..ba8deef 100644 --- a/src/SampleBatch.Components/StateMachines/BatchState.cs +++ b/src/SampleBatch.Components/StateMachines/BatchState.cs @@ -2,15 +2,13 @@ { using System; using System.Collections.Generic; - using Automatonymous; using Contracts.Enums; + using MassTransit; public class BatchState : SagaStateMachineInstance { - public Guid CorrelationId { get; set; } - public string CurrentState { get; set; } public DateTime? ReceiveTimestamp { get; set; } @@ -35,6 +33,7 @@ public class BatchState : public Dictionary ProcessingOrderIds { get; set; } = new Dictionary(); // CorrelationId, OrderId // Navigation Properties - public List Jobs { get; set; } = new List(); + public List Jobs { get; set; } = new List(); + public Guid CorrelationId { get; set; } } } \ No newline at end of file diff --git a/src/SampleBatch.Components/StateMachines/BatchStateEntityConfiguration.cs b/src/SampleBatch.Components/StateMachines/BatchStateEntityConfiguration.cs index 935827a..da14cea 100644 --- a/src/SampleBatch.Components/StateMachines/BatchStateEntityConfiguration.cs +++ b/src/SampleBatch.Components/StateMachines/BatchStateEntityConfiguration.cs @@ -2,8 +2,8 @@ { using System; using System.Collections.Generic; - using Common; using Contracts.Enums; + using MassTransit.EntityFrameworkCoreIntegration; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; diff --git a/src/SampleBatch.Components/StateMachines/BatchStateMachine.cs b/src/SampleBatch.Components/StateMachines/BatchStateMachine.cs index 34b3307..680b6ff 100644 --- a/src/SampleBatch.Components/StateMachines/BatchStateMachine.cs +++ b/src/SampleBatch.Components/StateMachines/BatchStateMachine.cs @@ -4,11 +4,8 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; - using Automatonymous; using Contracts; - using GreenPipes; using MassTransit; - using MassTransit.Definition; public class BatchStateMachine : @@ -93,7 +90,7 @@ public BatchStateMachine() InVar.Timestamp, ProcessingJobCount = x.Instance.ProcessingOrderIds.Count, UnprocessedJobCount = x.Instance.UnprocessedOrderIds.Count, - State = (await this.GetState(x.Instance)).Name + State = (await this.GetState(x)).Name })), When(BatchReceived) .Then(context => Touch(context.Instance, context.Data.Timestamp)) diff --git a/src/SampleBatch.Components/StateMachines/JobStateEntityConfiguration.cs b/src/SampleBatch.Components/StateMachines/JobStateEntityConfiguration.cs index d6f6635..2f3ee07 100644 --- a/src/SampleBatch.Components/StateMachines/JobStateEntityConfiguration.cs +++ b/src/SampleBatch.Components/StateMachines/JobStateEntityConfiguration.cs @@ -7,9 +7,9 @@ class JobStateEntityConfiguration : - IEntityTypeConfiguration + IEntityTypeConfiguration { - public void Configure(EntityTypeBuilder builder) + public void Configure(EntityTypeBuilder builder) { builder.HasKey(c => c.CorrelationId); diff --git a/src/SampleBatch.Contracts/SampleBatch.Contracts.csproj b/src/SampleBatch.Contracts/SampleBatch.Contracts.csproj index aa4404b..beaaaaa 100644 --- a/src/SampleBatch.Contracts/SampleBatch.Contracts.csproj +++ b/src/SampleBatch.Contracts/SampleBatch.Contracts.csproj @@ -6,7 +6,7 @@ - + diff --git a/src/SampleBatch.Service/Program.cs b/src/SampleBatch.Service/Program.cs index 6483b1a..0a64f91 100644 --- a/src/SampleBatch.Service/Program.cs +++ b/src/SampleBatch.Service/Program.cs @@ -10,13 +10,13 @@ using Components.StateMachines; using Contracts; using MassTransit; - using MassTransit.EntityFrameworkCoreIntegration; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; + class Program { public static AppConfig AppConfig { get; set; } @@ -58,7 +58,7 @@ static async Task Main(string[] args) new CustomSqlLockStatementProvider("select * from {0}.{1} WITH (UPDLOCK, ROWLOCK) WHERE BatchId = @p0"); }); - cfg.AddSagaStateMachine(typeof(JobStateMachineDefinition)) + cfg.AddSagaStateMachine() .EntityFrameworkRepository(r => { r.ConcurrencyMode = ConcurrencyMode.Pessimistic; @@ -110,9 +110,7 @@ static async Task Main(string[] args) }); } else - { throw new ApplicationException("Invalid Bus configuration. Couldn't find Azure or RabbitMq config"); - } }); services.AddDbContext(x => x.UseSqlServer(hostContext.Configuration.GetConnectionString("sample-batch"))); diff --git a/src/SampleBatch.Service/SampleBatch.Service.csproj b/src/SampleBatch.Service/SampleBatch.Service.csproj index 07fcba3..4b4469f 100644 --- a/src/SampleBatch.Service/SampleBatch.Service.csproj +++ b/src/SampleBatch.Service/SampleBatch.Service.csproj @@ -17,21 +17,20 @@ - - - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/src/SampleBatch.Tests/Integration/BatchStateMachineTests.cs b/src/SampleBatch.Tests/Integration/BatchStateMachineTests.cs index f23db78..6349716 100644 --- a/src/SampleBatch.Tests/Integration/BatchStateMachineTests.cs +++ b/src/SampleBatch.Tests/Integration/BatchStateMachineTests.cs @@ -16,6 +16,9 @@ namespace SampleBatch.Tests.Integration { + using MassTransit.EntityFrameworkCoreIntegration; + + /// /// Integration Tests I like to test more end to end scenarios. This still uses in-memory for all the message broker bits, but instead it uses MsSql for the persistence /// @@ -76,7 +79,7 @@ private void ConfigureInMemoryBus(IInMemoryBusFactoryConfigurator configurator) [Fact] public async Task should_complete_successfully() { - var message = await MessageInitializerCache.InitializeMessage( + var (message, _) = await MessageInitializerCache.InitializeMessage( new { BatchId = NewId.NextGuid(), diff --git a/src/SampleBatch.Tests/SampleBatch.Tests.csproj b/src/SampleBatch.Tests/SampleBatch.Tests.csproj index 88e9983..acba6d7 100644 --- a/src/SampleBatch.Tests/SampleBatch.Tests.csproj +++ b/src/SampleBatch.Tests/SampleBatch.Tests.csproj @@ -7,9 +7,10 @@ - - - + + + + all diff --git a/src/SampleBatch.Tests/Unit/BatchStateMachineTests.cs b/src/SampleBatch.Tests/Unit/BatchStateMachineTests.cs index b525dc7..86acdb7 100644 --- a/src/SampleBatch.Tests/Unit/BatchStateMachineTests.cs +++ b/src/SampleBatch.Tests/Unit/BatchStateMachineTests.cs @@ -54,7 +54,7 @@ private void ConfigureInMemoryBus(IInMemoryBusFactoryConfigurator configurator) [Fact] public async Task should_start() { - var message = await MessageInitializerCache.InitializeMessage( + var (message, _) = await MessageInitializerCache.InitializeMessage( new { BatchId = NewId.NextGuid(), @@ -82,7 +82,7 @@ public async Task should_start() [Fact] public async Task should_receive_and_wait() { - var message = await MessageInitializerCache.InitializeMessage( + var (message, _) = await MessageInitializerCache.InitializeMessage( new { BatchId = NewId.NextGuid(),