diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index c5cb15c..b9d760f 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -19,7 +19,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v3 with: - dotnet-version: 6.0.x + dotnet-version: 8.0.x - name: Restore dependencies working-directory: ./src run: dotnet restore diff --git a/README.md b/README.md index bef6cc7..0cf5f81 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,13 @@ -# GreenFeetWorkFlow .Net +# MicroWorkflow .net [![Stats](https://img.shields.io/badge/Code_lines-1,7_K-ff69b4.svg)]() [![Stats](https://img.shields.io/badge/Test_lines-1,1_K-69ffb4.svg)]() -[![Stats](https://img.shields.io/badge/Doc_lines-450-ffb469.svg)]() +[![Stats](https://img.shields.io/badge/Doc_lines-453-ffb469.svg)]() +# 0. + # 1. Design goals **Simplicity** @@ -30,9 +32,8 @@ * You can add more servers each running a workflow engine (horizontal scaling) **No external dependencies** -* The core library has *no external dependencies*, you can use whatever database, logger, json/xml/binary serializer you want -* ... in any version you want - +* The core library has *no external dependencies*, you can use whatever database, logger, json/xml/binary serializer you want ... in any version you want +* Convenience supplement nuget packages for Newtonsoft json, Ado .net, and Autofac are provided # 2. Overview @@ -84,29 +85,29 @@ Below are some more elaborate exaples. ### Simple console demo -A fully working C# example in one file: https://github.com/kbilsted/GreenFeetWorkFlow/blob/master/src/Demos/GreenFeetWorkFlow.ConsoleDemo/Program.cs +A fully working C# example in one file: https://github.com/kbilsted/MicroWorkflow.net/blob/master/src/Demos/ConsoleDemo/Program.cs ### Webapi demo -Now that you have understood the basics, lets make an example using a real IOC container and a database see https://github.com/kbilsted/GreenFeetWorkFlow/tree/master/src/Demos/GreenFeetWorkFlow.WebApiDemo +Now that you have understood the basics, lets make an example using a real IOC container and a database see https://github.com/kbilsted/MicroWorkflow.net/tree/master/src/Demos/WebApiDemo ### IOC container -You can use any IOC container that supports named instances. We use Autofac. For more information see https://github.com/kbilsted/GreenFeetWorkFlow/tree/master/src/Product/GreenFeetWorkFlow.Ioc.Autofac +You can use any IOC container that supports named instances. We use Autofac. For more information see https://github.com/kbilsted/MicroWorkflow.net/tree/master/src/Product/MicroWorkflow.Ioc.Autofac ### Database -You likely want to persist workflows in a database. We currently use Microsoft SQL Server in production environments, but and SQL database should be easy to get working. For more information see https://github.com/kbilsted/GreenFeetWorkFlow/tree/master/src/Product/GreenFeetWorkFlow.AdoPersistence +You likely want to persist workflows in a database. We currently use Microsoft SQL Server in production environments, but and SQL database should be easy to get working. For more information see https://github.com/kbilsted/MicroWorkflow.net/tree/master/src/Product/MicroWorkflow.AdoPersistence -# 4. Core concepts in Greenfeet Workflow +# 4. Core concepts in Micro Workflow The model revolves around the notion of a *step*. A step is in traditional workfow litterature referred to as an activity. Where activities live in a workflow. The workflow has identity and state and so forth. -In GreenFeet Workflow, however, there is only a `FlowId` property. No modelling of transitions nor workflow state. It is often desireable to store state around your business entities, in fact it is highly encouraged that you keep doing this. +In Micro Workflow, however, there is only a `FlowId` property. No modelling of transitions nor workflow state. It is often desireable to store state around your business entities, in fact it is highly encouraged that you keep doing this. A *step* has the following properties @@ -121,7 +122,7 @@ A *step* has the following properties * *done* (succesful execution). * During a step execution a step can spawn one or many new steps. Hence forming a chain or a graph of things to do. These steps execute after the current step. * Each step has a number of *tracking fields* such as create date, execution time, correlation id, flow id, created by id. -* There are a few more fields, they are all documented here https://github.com/kbilsted/GreenFeetWorkFlow/blob/master/src/Product/GreenFeetWorkFlow/Step.cs +* There are a few more fields, they are all documented here https://github.com/kbilsted/MicroWorkflow.net/blob/master/src/Product/MicroWorkflow/Step.cs Orthogonal to the step data we have *step implementations*. @@ -148,7 +149,7 @@ Simplicify is the focus of the code base. Performance is simply a side-effect of On a 2020 mid-tier computer we execute 10.000/sec steps using a single Workflow engine with 8 workers and an un-optimized SQL Server instance. Your milage may wary, so I highly recommend you do your own measurements before jumping to any conclusions. -You can take outset in some simple test scenarios at https://github.com/kbilsted/GreenFeetWorkFlow/blob/master/src/Demos/GreenFeetWorkFlow.Tests/PerformanceTests.cs +You can take outset in some simple test scenarios at https://github.com/kbilsted/MicroWorkflow.net/blob/master/src/Demos/MicroWorkFlow.Tests/PerformanceTests.cs @@ -172,26 +173,26 @@ Step execution is only orderes by an earliest execution time. If you need to con -# 8. GreenFeet Workflow and related concepts -Another way to gain conceptual insights into the framework, we explain why GreenFeet workflow is a good implementation fit to many concepts. +# 8. Micro Workflow and related concepts +Another way to gain conceptual insights into the framework, we explain why Micro Workflow is a good implementation fit to many concepts. -### GreenFeet as a Queue -You may not think of GreenFeet as a queue since the step execution is unordered. Queue's are asociated with FIFO - First In First Out. +### Micro Workflow as a Queue +You may not think of Micro Workflow as a queue since the step execution is unordered. Queue's are asociated with FIFO - First In First Out. A consequence of FIFO is that when queue elements can fail and retry, the FIFO property will stop the entire queue. For most real life scenarios this is unacceptable, hence most queues are in fact not FIFO. Thus we can implement a queue as a a workflow with only one step. -### GreenFeet as a Job scheduler +### Micro Workflow as a Job scheduler The system can act as a job scheduler. A step can be scheduled for a certain time and re-executed again at a certain time. To ensure only one instance exist, use the `Singleton` attribute. -### GreenFeet as the 'outbox pattern' +### Micro Workflow as the 'outbox pattern' The *outbox pattern* is an implementation strategy you often read about when dealing with events or distributed systems. It is a way to ensure that notifying other systems of a change happens in the same transaction as the change itself. The implementation is simply to insert a row into a queue that notifies the other system. -This is exactly a one-to-one match with a step in GreenFeet Workflow. +This is exactly a one-to-one match with a step in Micro Workflow. diff --git a/src/Demos/GreenFeetWorkFlow.ConsoleDemo/LICENSE b/src/Demos/ConsoleDemo/LICENSE similarity index 100% rename from src/Demos/GreenFeetWorkFlow.ConsoleDemo/LICENSE rename to src/Demos/ConsoleDemo/LICENSE diff --git a/src/Demos/GreenFeetWorkFlow.ConsoleDemo/GreenFeetWorkFlow.ConsoleDemo.csproj b/src/Demos/ConsoleDemo/MicroWorkflow.ConsoleDemo.csproj similarity index 64% rename from src/Demos/GreenFeetWorkFlow.ConsoleDemo/GreenFeetWorkFlow.ConsoleDemo.csproj rename to src/Demos/ConsoleDemo/MicroWorkflow.ConsoleDemo.csproj index 1ce6006..4da8658 100644 --- a/src/Demos/GreenFeetWorkFlow.ConsoleDemo/GreenFeetWorkFlow.ConsoleDemo.csproj +++ b/src/Demos/ConsoleDemo/MicroWorkflow.ConsoleDemo.csproj @@ -10,11 +10,8 @@ - - + diff --git a/src/Demos/GreenFeetWorkFlow.ConsoleDemo/Program.cs b/src/Demos/ConsoleDemo/Program.cs similarity index 78% rename from src/Demos/GreenFeetWorkFlow.ConsoleDemo/Program.cs rename to src/Demos/ConsoleDemo/Program.cs index c04850d..02349f3 100644 --- a/src/Demos/GreenFeetWorkFlow.ConsoleDemo/Program.cs +++ b/src/Demos/ConsoleDemo/Program.cs @@ -1,4 +1,6 @@ -using GreenFeetWorkflow; +using MicroWorkflow; +using MicroWorkflow.DemoImplementation; +using System.Reflection; using System.Text.Json; @@ -73,29 +75,13 @@ public async Task ExecuteAsync(Step step) class Program { - public static void Main(string[] args) + public static void Main() { - // To start and run the engine + // register the steps by scanning the assembly + var iocContainer = new DemoIocContainer().RegisterNamedSteps(Assembly.GetExecutingAssembly()); + // we persist in-memory + iocContainer.RegisterInstance(typeof(IStepPersister), new DemoInMemoryPersister()); - // register the steps to be used by the engine. For the demo we don't use a real IOC container, but you can use any IOC container supporting named dependencies - var iocContainer = new DemoIocContainer().RegisterNamedSteps(typeof(FetchData).Assembly); - - // register the persistence mechanism. For the demo we use a crude in-memory storage - iocContainer.Entries.Add(typeof(IStepPersister).FullName!, new DemoInMemoryPersister()); - - // register the logger and the loglevel. For the demo we simply log to the console. - // Notice loglevels can be re-defined at run-time so you can turn on fine-grained logs for a limited time - IWorkflowLogger logger = new ConsoleStepLogger(); - - // Define the format of workflow steps' state. Here we use .Net's JSON serializer - var formatter = new DotNetStepStateFormatterJson(logger); - var engine = new WorkflowEngine(logger, iocContainer, formatter); - - // Add a step to be executed - when executing succesfully, it will spawn new steps during processing - // you can add new steps at any time during run-time - engine.Data.AddStep(new Step(FetchData.Name, 0)); - - // Configure the engine. // For the demo we tell the engine to stop when there is no immediate pending work, so the program terminates quickly. For production you want the engine to run forever // The number of workers is dynamically adjusted during execution to fit the pending work. // This ensures we do not constantly bombard the persistence storage with requests while at the same time quickly respond to new work @@ -107,10 +93,17 @@ public static void Main(string[] args) MaxWorkerCount = 8, }); + // register the logger. Loglevels can change at run-time so you can turn on e.g. fine-grained logs for a limited time + var logger = new ConsoleStepLogger(cfg.LoggerConfiguration); + + var engine = new WorkflowEngine(logger, iocContainer, new DotNetStepStateFormatterJson(logger)); + + // Add a step to be executed - you can add new steps at any time during run-time + engine.Data.AddStep(new Step(FetchData.Name, 0)); + // Start the engine and wait for it to terminate engine.Start(cfg); - // don't close the window immediately Console.WriteLine(PrintTable("Ready", DemoInMemoryPersister.ReadySteps)); Console.WriteLine(PrintTable("Failed", DemoInMemoryPersister.FailedSteps)); Console.WriteLine(PrintTable("Done", DemoInMemoryPersister.DoneSteps)); diff --git a/src/Demos/GreenFeetWorkFlow.ConsoleDemo/readme.md b/src/Demos/ConsoleDemo/readme.md similarity index 100% rename from src/Demos/GreenFeetWorkFlow.ConsoleDemo/readme.md rename to src/Demos/ConsoleDemo/readme.md diff --git a/src/Demos/GreenFeetWorkFlow.Tests/AdoSingletonStepTests.cs b/src/Demos/MicroWorkflow.Tests/AdoSingletonStepTests.cs similarity index 60% rename from src/Demos/GreenFeetWorkFlow.Tests/AdoSingletonStepTests.cs rename to src/Demos/MicroWorkflow.Tests/AdoSingletonStepTests.cs index 955d8fb..19fa362 100644 --- a/src/Demos/GreenFeetWorkFlow.Tests/AdoSingletonStepTests.cs +++ b/src/Demos/MicroWorkflow.Tests/AdoSingletonStepTests.cs @@ -1,11 +1,11 @@ using Microsoft.Data.SqlClient; -using static GreenFeetWorkflow.Tests.TestHelper; +using static MicroWorkflow.TestHelper; -namespace GreenFeetWorkflow.Tests; +namespace MicroWorkflow; public class AdoSingletonStepTests { - TestHelper helper = new TestHelper(); + TestHelper helper = new(); [SetUp] public void Setup() @@ -17,15 +17,22 @@ public void Setup() public void When_creating_a_singleton_Then_it_is_created() { string? stepResult = null; - helper.Steps = [new Step(helper.RndName) + bool? stepResultIsSingleton = null; + var name = helper.RndName; + helper.Steps = [new Step(name) { Singleton = true, FlowId = helper.FlowId }]; - helper.StepHandlers = [Handle(helper.RndName, step => { stepResult = $"hello"; return ExecutionResult.Done(); })]; + helper.StepHandlers = [Handle(name, step => { + stepResult = $"hello"; + stepResultIsSingleton = step.Singleton; + return ExecutionResult.Done(); + })]; helper.StopWhenNoWork().BuildAndStart(); stepResult.Should().Be("hello"); + stepResultIsSingleton.Should().BeTrue(); helper.AssertTableCounts(helper.FlowId, ready: 0, done: 1, failed: 0); } @@ -33,9 +40,9 @@ public void When_creating_a_singleton_Then_it_is_created() public void When_adding_two_identical_singleton_steps_simultaniously_Then_fail() { var engine = helper.Build(); - - var step = new Step(helper.RndName) { Singleton = true, }; - var step2 = new Step(helper.RndName) { Singleton = true, }; + var name = helper.RndName; + var step = new Step(name) { Singleton = true, }; + var step2 = new Step(name) { Singleton = true, }; Func act = () => engine.Data.AddSteps([step, step2]); @@ -48,10 +55,11 @@ public void When_adding_two_identical_singleton_steps_simultaniously_Then_fail() public void When_adding_two_identical_singleton_steps_Then_fail_on_last_insert() { var engine = helper.Build(); - var step = new Step(helper.RndName) { Singleton = true, }; + var name = helper.RndName; + var step = new Step(name) { Singleton = true, }; engine.Data.AddStep(step); - var step2 = new Step(helper.RndName) { Singleton = true, }; + var step2 = new Step(name) { Singleton = true, }; Func act = () => engine.Data.AddStep(step2); act.Should() @@ -63,14 +71,14 @@ public void When_adding_two_identical_singleton_steps_Then_fail_on_last_insert() public void When_AddStepIfNotExists_two_identical_singleton_steps_Then_insert_first_and_return_null_on_duplicate() { var engine = helper.Build(); - - var step = new Step(helper.RndName) { Singleton = true }; - SearchModel searchModel = new SearchModel(Name: step.Name); + var name = helper.RndName; + var step = new Step(name) { Singleton = true }; + SearchModel searchModel = new(Name: step.Name); engine.Data.AddStepIfNotExists(step, searchModel) .Should() .HaveValue(); - var step2 = new Step(helper.RndName) { Singleton = true }; + var step2 = new Step(name) { Singleton = true }; engine.Data.AddStepIfNotExists(step2, searchModel) .Should() .BeNull(); diff --git a/src/Demos/GreenFeetWorkFlow.Tests/AdoTests.cs b/src/Demos/MicroWorkflow.Tests/AdoTests.cs similarity index 92% rename from src/Demos/GreenFeetWorkFlow.Tests/AdoTests.cs rename to src/Demos/MicroWorkflow.Tests/AdoTests.cs index 21cc510..8b6fa60 100644 --- a/src/Demos/GreenFeetWorkFlow.Tests/AdoTests.cs +++ b/src/Demos/MicroWorkflow.Tests/AdoTests.cs @@ -2,14 +2,15 @@ using Newtonsoft.Json; using ReassureTest; using System.Diagnostics; -using static GreenFeetWorkflow.Tests.TestHelper; +using static MicroWorkflow.TestHelper; -namespace GreenFeetWorkflow.Tests; +namespace MicroWorkflow; public class WorkerTests { - TestHelper helper = new TestHelper(); - private readonly WorkflowConfiguration cfg = new WorkflowConfiguration( + TestHelper helper = new(); + + readonly WorkflowConfiguration cfg = new WorkflowConfiguration( new WorkerConfig() { StopWhenNoImmediateWork = true @@ -25,6 +26,7 @@ public void Setup() public void When_executing_OneStep_with_initialstate_Then_that_state_is_accessible_and_step_is_executed() { string? stepResult = null; + bool? stepResultIsSingleton = null; const string StepName = "OneStep"; helper.Steps = [new Step(StepName) { @@ -35,12 +37,14 @@ public void When_executing_OneStep_with_initialstate_Then_that_state_is_accessib { int counter = helper.Formatter!.Deserialize(step.State); stepResult = $"hello {counter}"; + stepResultIsSingleton = step.Singleton; return ExecutionResult.Done(); }))]; helper.StopWhenNoWork().BuildAndStart(); stepResult.Should().Be("hello 1234"); + stepResultIsSingleton.Should().BeFalse(); helper.AssertTableCounts(helper.FlowId, ready: 0, done: 1, failed: 0); } @@ -160,7 +164,7 @@ public void When_executing_step_throwing_special_FailCurrentStepException_and_ad CreatedByStepId = 0 ScheduleTime = now CorrelationId = null - Description = `Exception of type 'GreenFeetWorkflow.FailCurrentStepException' was thrown.` + Description = `Exception of type 'MicroWorkflow.FailCurrentStepException' was thrown.` } ] } @@ -172,7 +176,7 @@ public void When_executing_step_throwing_special_FailCurrentStepException_and_ad public void When_executing_step_throwing_exception_Then_rerun_current_step_and_ensure_state_is_unchanged() { int? dbid = null; - const string name = "test-throw-exception"; + string name = helper.RndName; helper.StepHandlers = [Handle(name, step => { @@ -197,7 +201,7 @@ public void When_connecting_unsecurely_to_DB_Then_see_the_exception() { const string IllegalConnectionString = "Server=localhost;Database=adotest;Integrated Security=False;TrustServerCertificate=False"; - helper.StepHandlers = [Handle("onestep_fails", step => step.Fail())]; + helper.StepHandlers = [Handle("any", step => step.Fail())]; helper.ConnectionString = IllegalConnectionString; Action act = () => helper.StopWhenNoWork().BuildAndStart(); @@ -210,7 +214,7 @@ public void When_connecting_unsecurely_to_DB_Then_see_the_exception() [Test] public void When_step_is_failing_Then_it_is_marked_as_failed() { - const string name = "onestep_fails"; + string name = helper.RndName; helper.StepHandlers = [(name, new GenericImplementation(step => step.Fail()))]; helper.Steps = [new Step(name) { FlowId = helper.FlowId }]; helper.StopWhenNoWork().BuildAndStart(); @@ -222,12 +226,13 @@ public void When_step_is_failing_Then_it_is_marked_as_failed() public void When_executing_step_for_the_first_time_Then_execution_count_is_1() { int? stepResult = null; - helper.StepHandlers = [(helper.RndName, new GenericImplementation(step => + var name = helper.RndName; + helper.StepHandlers = [(name, new GenericImplementation(step => { stepResult = step.ExecutionCount; return ExecutionResult.Done(); }))]; - helper.Steps = [new Step(helper.RndName)]; + helper.Steps = [new Step(name)]; helper.StopWhenNoWork().BuildAndStart(); stepResult.Should().Be(1); @@ -236,7 +241,7 @@ public void When_executing_step_for_the_first_time_Then_execution_count_is_1() [Test] public void When_step_returns_rerun_Then_it_is_rerun() { - const string name = "OneStep_Repeating_Thrice"; + string name = helper.RndName; string? stepResult = null; helper.StepHandlers = [Handle(name, step => { @@ -284,8 +289,8 @@ public void When_one_step_executes_as_done_with_a_new_step_Then_new_step_has_the public void When_a_step_creates_a_new_step_Then_new_step_may_change_correlationid() { string? stepResult = null; - string oldId = Guid.NewGuid().ToString(); - string newId = Guid.NewGuid().ToString(); + string oldId = guid(); + string newId = guid(); helper.StepHandlers = [("check-correlationidchange/cookFood", new GenericImplementation(step => { @@ -316,8 +321,8 @@ public void When_a_step_creates_a_new_step_Then_new_step_may_change_correlationi public void When_a_step_creates_a_new_step_Then_new_step_may_change_correlationid2() { string? stepResult = null; - string oldId = Guid.NewGuid().ToString(); - string newId = Guid.NewGuid().ToString(); + string oldId = guid(); + string newId = guid(); helper.StepHandlers = [ Handle("check-correlationidchange/cookFood", step => @@ -510,7 +515,7 @@ class BuyInstructions class GroceryBuyer : IStepImplementation { - internal static readonly List<(Guid id, string name, int total)> SalesDb = new(); + internal static readonly List<(Guid id, string name, int total)> SalesDb = []; static readonly Dictionary prices = new() { { "milk", 1 }, { "cookies", 2 } }; public async Task ExecuteAsync(Step step) diff --git a/src/Demos/GreenFeetWorkFlow.Tests/AttributeRegistrationTests.cs b/src/Demos/MicroWorkflow.Tests/AttributeRegistrationTests.cs similarity index 93% rename from src/Demos/GreenFeetWorkFlow.Tests/AttributeRegistrationTests.cs rename to src/Demos/MicroWorkflow.Tests/AttributeRegistrationTests.cs index f621830..ed2e52f 100644 --- a/src/Demos/GreenFeetWorkFlow.Tests/AttributeRegistrationTests.cs +++ b/src/Demos/MicroWorkflow.Tests/AttributeRegistrationTests.cs @@ -1,8 +1,8 @@ -namespace GreenFeetWorkflow.Tests; +namespace MicroWorkflow; public class AttributeRegistrationTests { - private static readonly Dictionary StepResult = new(); + private static readonly Dictionary StepResult = []; [Test] public void When_using_stepnameattribute_Then_stepimplementation_is_registered() @@ -37,4 +37,5 @@ public async Task ExecuteAsync(Step step) return await Task.FromResult(step.Done()); } } -} \ No newline at end of file +} + diff --git a/src/Demos/GreenFeetWorkFlow.Tests/EngineTests.cs b/src/Demos/MicroWorkflow.Tests/EngineTests.cs similarity index 93% rename from src/Demos/GreenFeetWorkFlow.Tests/EngineTests.cs rename to src/Demos/MicroWorkflow.Tests/EngineTests.cs index 85c56e7..1eddbbd 100644 --- a/src/Demos/GreenFeetWorkFlow.Tests/EngineTests.cs +++ b/src/Demos/MicroWorkflow.Tests/EngineTests.cs @@ -1,9 +1,9 @@  -namespace GreenFeetWorkflow.Tests; +namespace MicroWorkflow; public class EngineTests { - TestHelper helper = new TestHelper(); + TestHelper helper = new(); [SetUp] public void Setup() @@ -14,14 +14,15 @@ public void Setup() [Test] public void When_adding_an_event_Then_an_id_PK_is_returned() { - Step step = new Step(helper.RndName) { ScheduleTime = DateTime.Now.AddMonths(1) }; + var name = helper.RndName; + Step step = new(name) { ScheduleTime = DateTime.Now.AddMonths(1) }; helper.Build(); var id = helper.Engine!.Data.AddStep(step); var result = helper.Engine.Data.SearchSteps(new(Id: id), StepStatus.Ready); - result.Single().Name.Should().Be(helper.RndName); + result.Single().Name.Should().Be(name); } [Test] diff --git a/src/Demos/GreenFeetWorkFlow.Tests/LICENSE b/src/Demos/MicroWorkflow.Tests/LICENSE similarity index 100% rename from src/Demos/GreenFeetWorkFlow.Tests/LICENSE rename to src/Demos/MicroWorkflow.Tests/LICENSE diff --git a/src/Demos/GreenFeetWorkFlow.Tests/LineCounterUpdateReadme.cs b/src/Demos/MicroWorkflow.Tests/LineCounterUpdateReadme.cs similarity index 95% rename from src/Demos/GreenFeetWorkFlow.Tests/LineCounterUpdateReadme.cs rename to src/Demos/MicroWorkflow.Tests/LineCounterUpdateReadme.cs index e543c62..1af3290 100644 --- a/src/Demos/GreenFeetWorkFlow.Tests/LineCounterUpdateReadme.cs +++ b/src/Demos/MicroWorkflow.Tests/LineCounterUpdateReadme.cs @@ -1,7 +1,7 @@ using KbgSoft.LineCounter; using System.Reflection; -namespace GreenFeetWorkflow.Tests; +namespace MicroWorkflow; public class LineCounterUpdateReadme { diff --git a/src/Demos/GreenFeetWorkFlow.Tests/GreenFeetWorkFlow.Tests.csproj b/src/Demos/MicroWorkflow.Tests/MicroWorkflow.Tests.csproj similarity index 66% rename from src/Demos/GreenFeetWorkFlow.Tests/GreenFeetWorkFlow.Tests.csproj rename to src/Demos/MicroWorkflow.Tests/MicroWorkflow.Tests.csproj index 616afd2..b753c83 100644 --- a/src/Demos/GreenFeetWorkFlow.Tests/GreenFeetWorkFlow.Tests.csproj +++ b/src/Demos/MicroWorkflow.Tests/MicroWorkflow.Tests.csproj @@ -9,6 +9,7 @@ + @@ -22,10 +23,9 @@ - - - - + + + diff --git a/src/Demos/GreenFeetWorkFlow.Tests/PerformanceTests.cs b/src/Demos/MicroWorkflow.Tests/PerformanceTests.cs similarity index 96% rename from src/Demos/GreenFeetWorkFlow.Tests/PerformanceTests.cs rename to src/Demos/MicroWorkflow.Tests/PerformanceTests.cs index 727bed2..9c771c1 100644 --- a/src/Demos/GreenFeetWorkFlow.Tests/PerformanceTests.cs +++ b/src/Demos/MicroWorkflow.Tests/PerformanceTests.cs @@ -1,9 +1,9 @@ using System.Collections.Concurrent; using System.Diagnostics; -using static GreenFeetWorkflow.Tests.TestHelper; +using static MicroWorkflow.TestHelper; -namespace GreenFeetWorkflow.Tests; +namespace MicroWorkflow; public class PerformanceTests { @@ -284,8 +284,8 @@ public void When_rerun_10_steps_each_repeating_1000_times_Then_expect_all_to_hav void doo(int workerCount) { - ConcurrentBag stepResults = new ConcurrentBag(); - var correlationIds = Enumerable.Range(0, 10).Select(x => Guid.NewGuid().ToString()).ToArray(); + ConcurrentBag stepResults = []; + var correlationIds = Enumerable.Range(0, 10).Select(x => guid()).ToArray(); var testhelper = new TestHelper(); testhelper.WorkflowConfiguration.WorkerConfig.MaxWorkerCount = workerCount; diff --git a/src/Demos/GreenFeetWorkFlow.Tests/RuntimeDataTests.cs b/src/Demos/MicroWorkflow.Tests/RuntimeDataTests.cs similarity index 88% rename from src/Demos/GreenFeetWorkFlow.Tests/RuntimeDataTests.cs rename to src/Demos/MicroWorkflow.Tests/RuntimeDataTests.cs index 8d63ae5..ffdc907 100644 --- a/src/Demos/GreenFeetWorkFlow.Tests/RuntimeDataTests.cs +++ b/src/Demos/MicroWorkflow.Tests/RuntimeDataTests.cs @@ -1,13 +1,13 @@ -using static GreenFeetWorkflow.Tests.TestHelper; +using static MicroWorkflow.TestHelper; -namespace GreenFeetWorkflow.Tests; +namespace MicroWorkflow; /// /// test the runtime data api /// public class RuntimeDataTests { - TestHelper helper = new TestHelper(); + TestHelper helper = new(); [SetUp] public void Setup() @@ -42,11 +42,11 @@ public void When_SearchSteps_for_nonmatch_Then_return_empty() var step = new Step(helper.RndName) { - FlowId = Guid.NewGuid().ToString(), - CorrelationId = Guid.NewGuid().ToString(), - SearchKey = Guid.NewGuid().ToString(), - Description = Guid.NewGuid().ToString(), - ExecutedBy = Guid.NewGuid().ToString(), + FlowId = guid(), + CorrelationId = guid(), + SearchKey = guid(), + Description = guid(), + ExecutedBy = guid(), Singleton = false }; var now = DateTime.Now; @@ -82,18 +82,17 @@ public void When_SearchSteps_for_nonmatch_Then_return_empty() steps[StepStatus.Ready].Should().BeEmpty(); } - [Test] public void When_SearchSteps_Then_return_data() { var engine = helper.Build(); var step = new Step(helper.RndName) { - FlowId = Guid.NewGuid().ToString(), - CorrelationId = Guid.NewGuid().ToString(), - SearchKey = Guid.NewGuid().ToString(), - Description = Guid.NewGuid().ToString(), - ExecutedBy = Guid.NewGuid().ToString(), + FlowId = guid(), + CorrelationId = guid(), + SearchKey = guid(), + Description = guid(), + ExecutedBy = guid(), Singleton = false }; @@ -148,7 +147,7 @@ public void When_SearchSteps_Then_return_data() public void When_reexecuting_a_step_Then_place_it_in_the_ready_queue() { const string name = "v1/fail-and-reactivate"; - Dictionary results = new(); + Dictionary results = []; var step = new Step(name) { FlowId = helper.FlowId, CorrelationId = helper.CorrelationId }; var engine = helper .With(e => diff --git a/src/Demos/GreenFeetWorkFlow.Tests/RuntimeMetricsTests.cs b/src/Demos/MicroWorkflow.Tests/RuntimeMetricsTests.cs similarity index 77% rename from src/Demos/GreenFeetWorkFlow.Tests/RuntimeMetricsTests.cs rename to src/Demos/MicroWorkflow.Tests/RuntimeMetricsTests.cs index b6e97ae..d629b30 100644 --- a/src/Demos/GreenFeetWorkFlow.Tests/RuntimeMetricsTests.cs +++ b/src/Demos/MicroWorkflow.Tests/RuntimeMetricsTests.cs @@ -1,8 +1,8 @@ -namespace GreenFeetWorkflow.Tests; +namespace MicroWorkflow; public class RuntimeMetricsTests { - TestHelper helper = new TestHelper(); + TestHelper helper = new(); [SetUp] public void Setup() diff --git a/src/Demos/GreenFeetWorkFlow.Tests/TestHelper.cs b/src/Demos/MicroWorkflow.Tests/TestHelper.cs similarity index 83% rename from src/Demos/GreenFeetWorkFlow.Tests/TestHelper.cs rename to src/Demos/MicroWorkflow.Tests/TestHelper.cs index 0bf75a1..fa968c3 100644 --- a/src/Demos/GreenFeetWorkFlow.Tests/TestHelper.cs +++ b/src/Demos/MicroWorkflow.Tests/TestHelper.cs @@ -1,28 +1,28 @@ using Autofac; -using GreenFeetWorkflow.Ioc.Autofac; -using GreenFeetWorkFlow.AdoMsSql; -namespace GreenFeetWorkflow.Tests; +namespace MicroWorkflow; public class TestHelper { - public string RndName = "test" + Guid.NewGuid().ToString(); + public static string guid() => Guid.NewGuid().ToString(); + + public string RndName { get => (TestContext.CurrentContext.Test.FullName + guid()).Substring("MicroWorkflow.".Length); } public NewtonsoftStateFormatterJson? Formatter; public CancellationTokenSource cts = new(); public AutofacAdaptor? iocContainer; public SqlServerPersister Persister => (SqlServerPersister)iocContainer!.GetInstance(); - public readonly string CorrelationId = Guid.NewGuid().ToString(); - public readonly string FlowId = Guid.NewGuid().ToString(); + public readonly string CorrelationId = guid(); + public readonly string FlowId = guid(); public IWorkflowLogger? Logger; public WorkflowEngine? Engine; - public (string, IStepImplementation)[] StepHandlers { get; set; } = new (string, IStepImplementation)[0]; + public (string, IStepImplementation)[] StepHandlers { get; set; } = Array.Empty<(string, IStepImplementation)>(); - readonly ContainerBuilder builder = new ContainerBuilder(); + readonly ContainerBuilder builder = new(); public string ConnectionString = "Server=localhost;Database=adotest;Integrated Security=True;TrustServerCertificate=True"; - public Step[] Steps = Array.Empty(); + public Step[] Steps = []; - public LoggerConfiguration LoggerConfiguration = new LoggerConfiguration() + public LoggerConfiguration LoggerConfiguration = new() { ErrorLoggingEnabledUntil = DateTime.MaxValue, InfoLoggingEnabledUntil = DateTime.MaxValue, diff --git a/src/Demos/GreenFeetWorkFlow.Tests/Usings.cs b/src/Demos/MicroWorkflow.Tests/Usings.cs similarity index 100% rename from src/Demos/GreenFeetWorkFlow.Tests/Usings.cs rename to src/Demos/MicroWorkflow.Tests/Usings.cs diff --git a/src/Demos/GreenFeetWorkFlow.Tests/readme.md b/src/Demos/MicroWorkflow.Tests/readme.md similarity index 100% rename from src/Demos/GreenFeetWorkFlow.Tests/readme.md rename to src/Demos/MicroWorkflow.Tests/readme.md diff --git a/src/Demos/GreenFeetWorkFlow.WebApiDemo/Controllers/WeatherForecastController.cs b/src/Demos/WebApiDemo/Controllers/WeatherForecastController.cs similarity index 81% rename from src/Demos/GreenFeetWorkFlow.WebApiDemo/Controllers/WeatherForecastController.cs rename to src/Demos/WebApiDemo/Controllers/WeatherForecastController.cs index 23ac195..1cddb64 100644 --- a/src/Demos/GreenFeetWorkFlow.WebApiDemo/Controllers/WeatherForecastController.cs +++ b/src/Demos/WebApiDemo/Controllers/WeatherForecastController.cs @@ -1,6 +1,6 @@ using Microsoft.AspNetCore.Mvc; -namespace GreenFeetWorkflow.WebApiDemo.Controllers; +namespace MicroWorkflow; [ApiController] [Route("[controller]")] diff --git a/src/Demos/GreenFeetWorkFlow.WebApiDemo/LICENSE b/src/Demos/WebApiDemo/LICENSE similarity index 100% rename from src/Demos/GreenFeetWorkFlow.WebApiDemo/LICENSE rename to src/Demos/WebApiDemo/LICENSE diff --git a/src/Demos/GreenFeetWorkFlow.WebApiDemo/GreenFeetWorkFlow.WebApiDemo.csproj b/src/Demos/WebApiDemo/MicroWorkflow.WebApiDemo.csproj similarity index 70% rename from src/Demos/GreenFeetWorkFlow.WebApiDemo/GreenFeetWorkFlow.WebApiDemo.csproj rename to src/Demos/WebApiDemo/MicroWorkflow.WebApiDemo.csproj index 71b57f3..ea64d64 100644 --- a/src/Demos/GreenFeetWorkFlow.WebApiDemo/GreenFeetWorkFlow.WebApiDemo.csproj +++ b/src/Demos/WebApiDemo/MicroWorkflow.WebApiDemo.csproj @@ -15,8 +15,8 @@ - - + + diff --git a/src/Demos/GreenFeetWorkFlow.WebApiDemo/Program.cs b/src/Demos/WebApiDemo/Program.cs similarity index 75% rename from src/Demos/GreenFeetWorkFlow.WebApiDemo/Program.cs rename to src/Demos/WebApiDemo/Program.cs index 69d875e..5c6b078 100644 --- a/src/Demos/GreenFeetWorkFlow.WebApiDemo/Program.cs +++ b/src/Demos/WebApiDemo/Program.cs @@ -1,6 +1,6 @@ using Autofac; using Autofac.Extensions.DependencyInjection; -using GreenFeetWorkflow.WebApiDemo; +using MicroWorkflow; var builder = WebApplication.CreateBuilder(args); @@ -9,13 +9,12 @@ builder.Host.ConfigureContainer(builder => { - builder.RegisterModule(); + builder.RegisterModule(); }); builder.Services.AddControllers(); -// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); diff --git a/src/Demos/GreenFeetWorkFlow.WebApiDemo/Properties/launchSettings.json b/src/Demos/WebApiDemo/Properties/launchSettings.json similarity index 91% rename from src/Demos/GreenFeetWorkFlow.WebApiDemo/Properties/launchSettings.json rename to src/Demos/WebApiDemo/Properties/launchSettings.json index b3f1017..0214e3c 100644 --- a/src/Demos/GreenFeetWorkFlow.WebApiDemo/Properties/launchSettings.json +++ b/src/Demos/WebApiDemo/Properties/launchSettings.json @@ -9,7 +9,7 @@ } }, "profiles": { - "GreenFeetWorkFlowWorkflow.WebApiDemo": { + "WebApiDemo": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, diff --git a/src/Demos/GreenFeetWorkFlow.WebApiDemo/RegisterGreenFeetWF.cs b/src/Demos/WebApiDemo/RegisterGreenFeetWF.cs similarity index 77% rename from src/Demos/GreenFeetWorkFlow.WebApiDemo/RegisterGreenFeetWF.cs rename to src/Demos/WebApiDemo/RegisterGreenFeetWF.cs index c4112c9..d63b489 100644 --- a/src/Demos/GreenFeetWorkFlow.WebApiDemo/RegisterGreenFeetWF.cs +++ b/src/Demos/WebApiDemo/RegisterGreenFeetWF.cs @@ -1,9 +1,9 @@ using Autofac; -using GreenFeetWorkflow.Ioc.Autofac; +using MicroWorkflow.DemoImplementation; -namespace GreenFeetWorkflow.WebApiDemo; +namespace MicroWorkflow; -public class RegisterGreenFeetWorkFlow : Module +public class RegisterWorkflow : Module { protected override void Load(ContainerBuilder builder) { @@ -23,6 +23,6 @@ protected override void Load(ContainerBuilder builder) builder.RegisterType().As(); // find and register all step-implementations - builder.RegisterStepImplementations(GetType().Assembly); + builder.RegisterStepImplementations(null, GetType().Assembly); } } \ No newline at end of file diff --git a/src/Demos/GreenFeetWorkFlow.WebApiDemo/StepFetchWeatherForecast.cs b/src/Demos/WebApiDemo/StepFetchWeatherForecast.cs similarity index 91% rename from src/Demos/GreenFeetWorkFlow.WebApiDemo/StepFetchWeatherForecast.cs rename to src/Demos/WebApiDemo/StepFetchWeatherForecast.cs index e375fb9..7489549 100644 --- a/src/Demos/GreenFeetWorkFlow.WebApiDemo/StepFetchWeatherForecast.cs +++ b/src/Demos/WebApiDemo/StepFetchWeatherForecast.cs @@ -1,4 +1,4 @@ -namespace GreenFeetWorkflow.WebApiDemo; +namespace MicroWorkflow; [StepName(Name)] class StepFetchWeatherForecast : IStepImplementation diff --git a/src/Demos/GreenFeetWorkFlow.WebApiDemo/WeatherForecast.cs b/src/Demos/WebApiDemo/WeatherForecast.cs similarity index 79% rename from src/Demos/GreenFeetWorkFlow.WebApiDemo/WeatherForecast.cs rename to src/Demos/WebApiDemo/WeatherForecast.cs index 906c525..6fa762a 100644 --- a/src/Demos/GreenFeetWorkFlow.WebApiDemo/WeatherForecast.cs +++ b/src/Demos/WebApiDemo/WeatherForecast.cs @@ -1,4 +1,4 @@ -namespace GreenFeetWorkflow.WebApiDemo; +namespace MicroWorkflow; public class WeatherForecast { @@ -19,8 +19,8 @@ public class WeaterForecastDB { public static List LazyFetchedWeatherForecasts { get; set; } = new List(); - internal static readonly string[] Summaries = new[] - { + internal static readonly string[] Summaries = + [ "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" - }; + ]; } \ No newline at end of file diff --git a/src/Demos/GreenFeetWorkFlow.WebApiDemo/WorkflowStarter.cs b/src/Demos/WebApiDemo/WorkflowStarter.cs similarity index 73% rename from src/Demos/GreenFeetWorkFlow.WebApiDemo/WorkflowStarter.cs rename to src/Demos/WebApiDemo/WorkflowStarter.cs index c85bcc2..b60907c 100644 --- a/src/Demos/GreenFeetWorkFlow.WebApiDemo/WorkflowStarter.cs +++ b/src/Demos/WebApiDemo/WorkflowStarter.cs @@ -1,4 +1,4 @@ -namespace GreenFeetWorkflow.WebApiDemo; +namespace MicroWorkflow; public class WorkflowStarter : BackgroundService @@ -12,12 +12,12 @@ public WorkflowStarter(WorkflowEngine engine) protected override async Task ExecuteAsync(CancellationToken stoppingToken) { - Step step = new Step(StepFetchWeatherForecast.Name) + Step step = new(StepFetchWeatherForecast.Name) { Singleton = true, Description= "continuously fetch the latest weather data and cache it" }; - SearchModel searchModel = new SearchModel(Name: step.Name, Singleton: step.Singleton); + SearchModel searchModel = new(Name: step.Name, Singleton: step.Singleton); engine.Data.AddStepIfNotExists(step, searchModel); engine.StartAsync(new WorkflowConfiguration(new WorkerConfig()), stoppingToken: stoppingToken); diff --git a/src/Demos/GreenFeetWorkFlow.WebApiDemo/appsettings.Development.json b/src/Demos/WebApiDemo/appsettings.Development.json similarity index 100% rename from src/Demos/GreenFeetWorkFlow.WebApiDemo/appsettings.Development.json rename to src/Demos/WebApiDemo/appsettings.Development.json diff --git a/src/Demos/GreenFeetWorkFlow.WebApiDemo/appsettings.json b/src/Demos/WebApiDemo/appsettings.json similarity index 100% rename from src/Demos/GreenFeetWorkFlow.WebApiDemo/appsettings.json rename to src/Demos/WebApiDemo/appsettings.json diff --git a/src/Demos/GreenFeetWorkFlow.WebApiDemo/readme.md b/src/Demos/WebApiDemo/readme.md similarity index 84% rename from src/Demos/GreenFeetWorkFlow.WebApiDemo/readme.md rename to src/Demos/WebApiDemo/readme.md index 43de7ef..d5520e3 100644 --- a/src/Demos/GreenFeetWorkFlow.WebApiDemo/readme.md +++ b/src/Demos/WebApiDemo/readme.md @@ -4,7 +4,7 @@ A standalone webapi demo that shows how to use the workflow engine as a task sch main classes to focus on are: -* `RegisterGreenFeetWorkFlow` - setting up the dependencies +* `RegisterGreenFeetWorkflow` - setting up the dependencies * `WorkflowStarter` - what starts and runs the workflow engine * `StepFetchWeatherForecast` - the repeating singleton step diff --git a/src/GreenFeetWF.All.sln b/src/MicroWorkflow.All.sln similarity index 69% rename from src/GreenFeetWF.All.sln rename to src/MicroWorkflow.All.sln index dc3ead5..b4c8371 100644 --- a/src/GreenFeetWF.All.sln +++ b/src/MicroWorkflow.All.sln @@ -3,13 +3,13 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.4.33205.214 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GreenFeetWorkFlow", "Product\GreenFeetWorkFlow\GreenFeetWorkFlow.csproj", "{BD6831E2-BC24-4F79-B1DF-BE4917511BE7}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MicroWorkflow", "Product\MicroWorkflow\MicroWorkflow.csproj", "{BD6831E2-BC24-4F79-B1DF-BE4917511BE7}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GreenFeetWorkFlow.AdoMsSql", "Product\GreenFeetWorkFlow.AdoPersistence\GreenFeetWorkFlow.AdoMsSql.csproj", "{131A097B-96D3-4FD0-BBD1-EE69FFB62E2A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MicroWorkflow.AdoMsSql", "Product\MicroWorkflow.AdoPersistence\MicroWorkflow.AdoMsSql.csproj", "{131A097B-96D3-4FD0-BBD1-EE69FFB62E2A}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GreenFeetWorkFlow.ConsoleDemo", "Demos\GreenFeetWorkFlow.ConsoleDemo\GreenFeetWorkFlow.ConsoleDemo.csproj", "{D34FAF8F-1F28-4610-88CA-A10970D81690}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MicroWorkflow.ConsoleDemo", "Demos\ConsoleDemo\MicroWorkflow.ConsoleDemo.csproj", "{D34FAF8F-1F28-4610-88CA-A10970D81690}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GreenFeetWorkFlow.Ioc.Autofac", "Product\GreenFeetWorkFlow.Ioc.Autofac\GreenFeetWorkFlow.Ioc.Autofac.csproj", "{42A6FECF-BE3E-467B-B74D-9C9AFC844A76}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MicroWorkflow.Ioc.Autofac", "Product\MicroWorkflow.Ioc.Autofac\MicroWorkflow.Ioc.Autofac.csproj", "{42A6FECF-BE3E-467B-B74D-9C9AFC844A76}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{5B7CC424-7590-4D44-9EF9-B54E05F33A56}" ProjectSection(SolutionItems) = preProject @@ -17,11 +17,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution ..\README.md = ..\README.md EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GreenFeetWorkFlow.Tests", "Demos\GreenFeetWorkFlow.Tests\GreenFeetWorkFlow.Tests.csproj", "{AC80493C-B71B-4631-8CF6-20D067FD9460}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MicroWorkflow.Tests", "Demos\MicroWorkflow.Tests\MicroWorkflow.Tests.csproj", "{AC80493C-B71B-4631-8CF6-20D067FD9460}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GreenFeetWorkFlow.Formatter.NewtonsoftJson", "Product\GreenFeetWorkFlow.Formatter.NewtonsoftJson\GreenFeetWorkFlow.Formatter.NewtonsoftJson.csproj", "{01DB9CED-771C-46C3-A6F8-528DAB818FBF}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MicroWorkflow.Formatter.NewtonsoftJson", "Product\MicroWorkflow.Formatter.NewtonsoftJson\MicroWorkflow.Formatter.NewtonsoftJson.csproj", "{01DB9CED-771C-46C3-A6F8-528DAB818FBF}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GreenFeetWorkFlow.WebApiDemo", "Demos\GreenFeetWorkFlow.WebApiDemo\GreenFeetWorkFlow.WebApiDemo.csproj", "{8F8576D7-E79E-4E7D-8FBF-0694D87D3759}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MicroWorkflow.WebApiDemo", "Demos\WebApiDemo\MicroWorkflow.WebApiDemo.csproj", "{8F8576D7-E79E-4E7D-8FBF-0694D87D3759}" ProjectSection(ProjectDependencies) = postProject {BD6831E2-BC24-4F79-B1DF-BE4917511BE7} = {BD6831E2-BC24-4F79-B1DF-BE4917511BE7} EndProjectSection diff --git a/src/Product/GreenFeetWorkFlow/FailCurrentStepException.cs b/src/Product/GreenFeetWorkFlow/FailCurrentStepException.cs deleted file mode 100644 index dec0d08..0000000 --- a/src/Product/GreenFeetWorkFlow/FailCurrentStepException.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace GreenFeetWorkflow; - -/// -/// throwing this exception makes a step FAIL rather than RETRY it later. -/// -public class FailCurrentStepException : Exception -{ - public Step[]? NewSteps { get; set; } - - public FailCurrentStepException() : this(null, null, null) { } - - public FailCurrentStepException(string? description) - : this(description, null, null) - { } - - public FailCurrentStepException(string? description, Exception? innerException) - : this(description, innerException, null) - { } - - public FailCurrentStepException(string? description, Exception? innerException, params Step[]? newSteps) - : base(description, innerException) - { - NewSteps = newSteps; - } -} diff --git a/src/Product/GreenFeetWorkFlow.AdoPersistence/AdoDb.cs b/src/Product/MicroWorkflow.AdoPersistence/AdoDb.cs similarity index 96% rename from src/Product/GreenFeetWorkFlow.AdoPersistence/AdoDb.cs rename to src/Product/MicroWorkflow.AdoPersistence/AdoDb.cs index 1a75f91..af5b0c9 100644 --- a/src/Product/GreenFeetWorkFlow.AdoPersistence/AdoDb.cs +++ b/src/Product/MicroWorkflow.AdoPersistence/AdoDb.cs @@ -1,9 +1,8 @@ -using GreenFeetWorkflow; -using Microsoft.Data.SqlClient; +using Microsoft.Data.SqlClient; using System.Data; using System.Text.RegularExpressions; -namespace GreenFeetWorkFlow.AdoMsSql; +namespace MicroWorkflow; public class SqlServerPersister : IStepPersister { diff --git a/src/Product/GreenFeetWorkFlow.AdoPersistence/AdoHelper.cs b/src/Product/MicroWorkflow.AdoPersistence/AdoHelper.cs similarity index 96% rename from src/Product/GreenFeetWorkFlow.AdoPersistence/AdoHelper.cs rename to src/Product/MicroWorkflow.AdoPersistence/AdoHelper.cs index 80be242..e593be2 100644 --- a/src/Product/GreenFeetWorkFlow.AdoPersistence/AdoHelper.cs +++ b/src/Product/MicroWorkflow.AdoPersistence/AdoHelper.cs @@ -1,8 +1,6 @@ -using GreenFeetWorkflow; -using GreenFeetWorkflow.AdoPersistence; -using Microsoft.Data.SqlClient; +using Microsoft.Data.SqlClient; -namespace GreenFeetWorkFlow.AdoMsSql; +namespace MicroWorkflow; #pragma warning disable CA1822 // Mark members as static diff --git a/src/Product/GreenFeetWorkFlow.AdoPersistence/LICENSE b/src/Product/MicroWorkflow.AdoPersistence/LICENSE similarity index 100% rename from src/Product/GreenFeetWorkFlow.AdoPersistence/LICENSE rename to src/Product/MicroWorkflow.AdoPersistence/LICENSE diff --git a/src/Product/GreenFeetWorkFlow.AdoPersistence/GreenFeetWorkFlow.AdoMsSql.csproj b/src/Product/MicroWorkflow.AdoPersistence/MicroWorkflow.AdoMsSql.csproj similarity index 82% rename from src/Product/GreenFeetWorkFlow.AdoPersistence/GreenFeetWorkFlow.AdoMsSql.csproj rename to src/Product/MicroWorkflow.AdoPersistence/MicroWorkflow.AdoMsSql.csproj index 5e51e41..a6f1fba 100644 --- a/src/Product/GreenFeetWorkFlow.AdoPersistence/GreenFeetWorkFlow.AdoMsSql.csproj +++ b/src/Product/MicroWorkflow.AdoPersistence/MicroWorkflow.AdoMsSql.csproj @@ -7,7 +7,7 @@ true Kasper B. Graversen - https://github.com/kbilsted/GreenFeetWorkFlow/tree/master/src/Product/GreenFeetWorkFlow.AdoPersistence + https://github.com/kbilsted/MicroWorkflow.net/tree/master/src/Product/MicroWorkflow.AdoPersistence True LICENSE Ado Microsoft SQL Server Integration @@ -35,7 +35,7 @@ - + diff --git a/src/Product/GreenFeetWorkFlow.AdoPersistence/ObjectDataReader.cs b/src/Product/MicroWorkflow.AdoPersistence/ObjectDataReader.cs similarity index 95% rename from src/Product/GreenFeetWorkFlow.AdoPersistence/ObjectDataReader.cs rename to src/Product/MicroWorkflow.AdoPersistence/ObjectDataReader.cs index 609d7b0..b20a951 100644 --- a/src/Product/GreenFeetWorkFlow.AdoPersistence/ObjectDataReader.cs +++ b/src/Product/MicroWorkflow.AdoPersistence/ObjectDataReader.cs @@ -2,7 +2,7 @@ using System.Linq.Expressions; using System.Reflection; -namespace GreenFeetWorkFlow.AdoMsSql; +namespace MicroWorkflow; /// /// Datareader for bulk inserts. Assumes the order of the class fields are identical to the ordering of the db table. diff --git a/src/Product/GreenFeetWorkFlow.AdoPersistence/Sql.cs b/src/Product/MicroWorkflow.AdoPersistence/Sql.cs similarity index 92% rename from src/Product/GreenFeetWorkFlow.AdoPersistence/Sql.cs rename to src/Product/MicroWorkflow.AdoPersistence/Sql.cs index 327292c..594300f 100644 --- a/src/Product/GreenFeetWorkFlow.AdoPersistence/Sql.cs +++ b/src/Product/MicroWorkflow.AdoPersistence/Sql.cs @@ -1,6 +1,6 @@ using System.Text; -namespace GreenFeetWorkflow.AdoPersistence; +namespace MicroWorkflow; /// /// Dynamic SQL builder @@ -63,7 +63,7 @@ public Sql Where(Action code) { var orSqlBlock = (new Sql("AND (")); code(orSqlBlock); - orSqlBlock.AddWhere(")"); + orSqlBlock.Add(")"); return AddWhere(orSqlBlock.Build()); } diff --git a/src/Product/GreenFeetWorkFlow.AdoPersistence/createdb.sql b/src/Product/MicroWorkflow.AdoPersistence/createdb.sql similarity index 100% rename from src/Product/GreenFeetWorkFlow.AdoPersistence/createdb.sql rename to src/Product/MicroWorkflow.AdoPersistence/createdb.sql diff --git a/src/Product/GreenFeetWorkFlow.AdoPersistence/readme.md b/src/Product/MicroWorkflow.AdoPersistence/readme.md similarity index 90% rename from src/Product/GreenFeetWorkFlow.AdoPersistence/readme.md rename to src/Product/MicroWorkflow.AdoPersistence/readme.md index 4f304b4..09026a8 100644 --- a/src/Product/GreenFeetWorkFlow.AdoPersistence/readme.md +++ b/src/Product/MicroWorkflow.AdoPersistence/readme.md @@ -7,7 +7,7 @@ This package provides integration with Microsoft SQL server to persist steps in To get started -* Create database scemas and tables with https://github.com/kbilsted/MinimaWorkflow.Net/blob/master/src/GreenFeetWorkFlow.AdoPersistence/createdb.sql +* Create database scemas and tables with https://github.com/kbilsted/MicroWorkflow.net/blob/master/src/MicroWorkFlow.AdoPersistence/createdb.sql * Optionally you rename the schemas and tables to whatever you see fit. Then, on an instance of `SqlServerPersister` set the values `TableNameReady`, `TableNameFail`, `TableNameDone`. * Register in your IOC container `SqlServerPersister` such that a new instance is created when the type is resolved. This is due to the fact that each instance controls its local transaction. ``` diff --git a/src/Product/GreenFeetWorkFlow.Formatter.NewtonsoftJson/LICENSE b/src/Product/MicroWorkflow.Formatter.NewtonsoftJson/LICENSE similarity index 100% rename from src/Product/GreenFeetWorkFlow.Formatter.NewtonsoftJson/LICENSE rename to src/Product/MicroWorkflow.Formatter.NewtonsoftJson/LICENSE diff --git a/src/Product/GreenFeetWorkFlow.Formatter.NewtonsoftJson/GreenFeetWorkFlow.Formatter.NewtonsoftJson.csproj b/src/Product/MicroWorkflow.Formatter.NewtonsoftJson/MicroWorkflow.Formatter.NewtonsoftJson.csproj similarity index 81% rename from src/Product/GreenFeetWorkFlow.Formatter.NewtonsoftJson/GreenFeetWorkFlow.Formatter.NewtonsoftJson.csproj rename to src/Product/MicroWorkflow.Formatter.NewtonsoftJson/MicroWorkflow.Formatter.NewtonsoftJson.csproj index e7d46ea..7542b9e 100644 --- a/src/Product/GreenFeetWorkFlow.Formatter.NewtonsoftJson/GreenFeetWorkFlow.Formatter.NewtonsoftJson.csproj +++ b/src/Product/MicroWorkflow.Formatter.NewtonsoftJson/MicroWorkflow.Formatter.NewtonsoftJson.csproj @@ -7,7 +7,7 @@ true Kasper B. Graversen - https://github.com/kbilsted/GreenFeetWorkFlow/tree/master/src/Product/GreenFeetWorkFlow.Formatter.NewtonsoftJson + https://github.com/kbilsted/MicroWorkflow.net/tree/master/src/Product/MicroWorkflow.Formatter.NewtonsoftJson True LICENSE Newtonsoft Json integration @@ -32,7 +32,7 @@ - + diff --git a/src/Product/GreenFeetWorkFlow.Formatter.NewtonsoftJson/NewtonsoftStateFormatterJson.cs b/src/Product/MicroWorkflow.Formatter.NewtonsoftJson/NewtonsoftStateFormatterJson.cs similarity index 93% rename from src/Product/GreenFeetWorkFlow.Formatter.NewtonsoftJson/NewtonsoftStateFormatterJson.cs rename to src/Product/MicroWorkflow.Formatter.NewtonsoftJson/NewtonsoftStateFormatterJson.cs index 813f73c..26a7e88 100644 --- a/src/Product/GreenFeetWorkFlow.Formatter.NewtonsoftJson/NewtonsoftStateFormatterJson.cs +++ b/src/Product/MicroWorkflow.Formatter.NewtonsoftJson/NewtonsoftStateFormatterJson.cs @@ -1,9 +1,9 @@ using Newtonsoft.Json; -namespace GreenFeetWorkflow; +namespace MicroWorkflow; -public class NewtonsoftStateFormatterJson : IWorkflowStepStateFormatter +public class NewtonsoftStateFormatterJson : IWorkflowStepStateFormatter { private readonly IWorkflowLogger logger; diff --git a/src/Product/GreenFeetWorkFlow.Formatter.NewtonsoftJson/readme.md b/src/Product/MicroWorkflow.Formatter.NewtonsoftJson/readme.md similarity index 100% rename from src/Product/GreenFeetWorkFlow.Formatter.NewtonsoftJson/readme.md rename to src/Product/MicroWorkflow.Formatter.NewtonsoftJson/readme.md diff --git a/src/Product/GreenFeetWorkFlow.Ioc.Autofac/AutofacAdaptor.cs b/src/Product/MicroWorkflow.Ioc.Autofac/AutofacAdaptor.cs similarity index 90% rename from src/Product/GreenFeetWorkFlow.Ioc.Autofac/AutofacAdaptor.cs rename to src/Product/MicroWorkflow.Ioc.Autofac/AutofacAdaptor.cs index 2d3e083..6240438 100644 --- a/src/Product/GreenFeetWorkFlow.Ioc.Autofac/AutofacAdaptor.cs +++ b/src/Product/MicroWorkflow.Ioc.Autofac/AutofacAdaptor.cs @@ -1,6 +1,6 @@ using Autofac; -namespace GreenFeetWorkflow.Ioc.Autofac; +namespace MicroWorkflow; public class AutofacAdaptor : IWorkflowIocContainer { diff --git a/src/Product/GreenFeetWorkFlow.Ioc.Autofac/AutofacHelper.cs b/src/Product/MicroWorkflow.Ioc.Autofac/AutofacHelper.cs similarity index 71% rename from src/Product/GreenFeetWorkFlow.Ioc.Autofac/AutofacHelper.cs rename to src/Product/MicroWorkflow.Ioc.Autofac/AutofacHelper.cs index 545338e..0775039 100644 --- a/src/Product/GreenFeetWorkFlow.Ioc.Autofac/AutofacHelper.cs +++ b/src/Product/MicroWorkflow.Ioc.Autofac/AutofacHelper.cs @@ -1,7 +1,7 @@ using Autofac; using System.Reflection; -namespace GreenFeetWorkflow.Ioc.Autofac; +namespace MicroWorkflow; public static class AutofacExtensions { @@ -25,13 +25,11 @@ public static void RegisterStepImplementation(this ContainerBuilder builder, IWo builder.RegisterType(implementationType).Named(stepName); } - /// Register all implementations that are anotated with the - public static void RegisterStepImplementations(this ContainerBuilder builder, params Assembly[] assemblies) => RegisterStepImplementations(builder, null, assemblies); - + /// Register all implementations that are anotated with the public static void RegisterStepImplementations(this ContainerBuilder builder, IWorkflowLogger? logger, params Assembly[] assemblies) { - foreach (var x in ReflectionHelper.GetStepsFromAttribute(assemblies)) - RegisterStepImplementation(builder, logger, x.implementationType, x.stepName); + foreach (var (implementationType, stepName) in ReflectionHelper.GetStepsFromAttribute(assemblies)) + RegisterStepImplementation(builder, logger, implementationType, stepName); } } \ No newline at end of file diff --git a/src/Product/GreenFeetWorkFlow.Ioc.Autofac/LICENSE b/src/Product/MicroWorkflow.Ioc.Autofac/LICENSE similarity index 100% rename from src/Product/GreenFeetWorkFlow.Ioc.Autofac/LICENSE rename to src/Product/MicroWorkflow.Ioc.Autofac/LICENSE diff --git a/src/Product/GreenFeetWorkFlow.Ioc.Autofac/GreenFeetWorkFlow.Ioc.Autofac.csproj b/src/Product/MicroWorkflow.Ioc.Autofac/MicroWorkflow.Ioc.Autofac.csproj similarity index 78% rename from src/Product/GreenFeetWorkFlow.Ioc.Autofac/GreenFeetWorkFlow.Ioc.Autofac.csproj rename to src/Product/MicroWorkflow.Ioc.Autofac/MicroWorkflow.Ioc.Autofac.csproj index c594ff9..caffd8d 100644 --- a/src/Product/GreenFeetWorkFlow.Ioc.Autofac/GreenFeetWorkFlow.Ioc.Autofac.csproj +++ b/src/Product/MicroWorkflow.Ioc.Autofac/MicroWorkflow.Ioc.Autofac.csproj @@ -7,11 +7,11 @@ true Kasper B. Graversen - https://github.com/kbilsted/GreenFeetWorkFlow/tree/master/src/Product/GreenFeetWorkFlow.Ioc.Autofac + https://github.com/kbilsted/MicroWorkflow.net/tree/master/src/Product/MicroWorkflow.Ioc.Autofac True LICENSE Autofac íntegration - Autofac; GreenFeetWorkFlow + Autofac; MicroWorkflow readme.md False snupkg @@ -37,7 +37,7 @@ - + diff --git a/src/Product/GreenFeetWorkFlow.Ioc.Autofac/readme.md b/src/Product/MicroWorkflow.Ioc.Autofac/readme.md similarity index 85% rename from src/Product/GreenFeetWorkFlow.Ioc.Autofac/readme.md rename to src/Product/MicroWorkflow.Ioc.Autofac/readme.md index 5b9b715..5cb89e1 100644 --- a/src/Product/GreenFeetWorkFlow.Ioc.Autofac/readme.md +++ b/src/Product/MicroWorkflow.Ioc.Autofac/readme.md @@ -13,4 +13,4 @@ builder.RegisterType().As(); If you want to scan assemblies for workflow step implementations using the `[StepName]` attribute, you can use `builder.RegisterStepImplementations(GetType().Assembly)`. Otherwise you can manually register step implementations with `builder.RegisterType(implementationType).Named(stepName);` -A complete example of a usage is found in https://github.com/kbilsted/GreenFeetWorkFlow/blob/master/src/Demos/GreenFeetWorkFlow.WebApiDemo/RegisterGreenFeetWF.cs +A complete example of a usage is found in https://github.com/kbilsted/MicroWorkflow.net/blob/master/src/Demos/WebApiDemo/RegisterGreenFeetWF.cs diff --git a/src/Product/GreenFeetWorkFlow/DemoImplementations/DemoInMemoryPersister.cs b/src/Product/MicroWorkflow/DemoImplementations/DemoInMemoryPersister.cs similarity index 93% rename from src/Product/GreenFeetWorkFlow/DemoImplementations/DemoInMemoryPersister.cs rename to src/Product/MicroWorkflow/DemoImplementations/DemoInMemoryPersister.cs index ecadb60..938d5ef 100644 --- a/src/Product/GreenFeetWorkFlow/DemoImplementations/DemoInMemoryPersister.cs +++ b/src/Product/MicroWorkflow/DemoImplementations/DemoInMemoryPersister.cs @@ -1,4 +1,4 @@ -namespace GreenFeetWorkflow; +namespace MicroWorkflow.DemoImplementation; /// /// Simple in-memory storage FOR DEMO PURPOSES ONLY. @@ -34,7 +34,7 @@ public class DemoInMemoryPersister : IStepPersister return null; Locked.Add(step.Id); - if (LocalTransaction.Any()) + if (LocalTransaction.Count != 0) throw new Exception("inside an existing transaction"); LocalTransaction.Add(step.Id); @@ -75,7 +75,7 @@ public List SearchSteps(SearchModel criteria, StepStatus target) public Dictionary> SearchSteps(SearchModel criteria, FetchLevels fetchLevels) { - List ready = new List(); + List ready = new(); if (fetchLevels.Ready) { ready = ReadySteps.Where(x => @@ -157,7 +157,7 @@ public int Insert(StepStatus target, Step step) { if (target == StepStatus.Ready) { - Insert(StepStatus.Ready, new[] { step }); + _ = Insert(StepStatus.Ready, new[] { step }); return step.Id; } diff --git a/src/Product/GreenFeetWorkFlow/DemoImplementations/DemoIocContainer.cs b/src/Product/MicroWorkflow/DemoImplementations/DemoIocContainer.cs similarity index 84% rename from src/Product/GreenFeetWorkFlow/DemoImplementations/DemoIocContainer.cs rename to src/Product/MicroWorkflow/DemoImplementations/DemoIocContainer.cs index 17ad866..eaee760 100644 --- a/src/Product/GreenFeetWorkFlow/DemoImplementations/DemoIocContainer.cs +++ b/src/Product/MicroWorkflow/DemoImplementations/DemoIocContainer.cs @@ -1,6 +1,6 @@ using System.Reflection; -namespace GreenFeetWorkflow; +namespace MicroWorkflow.DemoImplementation; /// /// a demo holder for instances that can be retrieved by the engine @@ -31,6 +31,12 @@ public T GetInstance() return null; } + public DemoIocContainer RegisterInstance(Type t, object x) + { + Entries.Add(t.FullName!, x); + return this; + } + public DemoIocContainer RegisterNamedSteps(Assembly assembly) { (Type implementationType, string stepName)[] registrations = ReflectionHelper.GetStepsFromAttribute(assembly).ToArray(); diff --git a/src/Product/GreenFeetWorkFlow/DotNetStepStateFormatterJson.cs b/src/Product/MicroWorkflow/DotNetStepStateFormatterJson.cs similarity index 94% rename from src/Product/GreenFeetWorkFlow/DotNetStepStateFormatterJson.cs rename to src/Product/MicroWorkflow/DotNetStepStateFormatterJson.cs index edce565..3b75e28 100644 --- a/src/Product/GreenFeetWorkFlow/DotNetStepStateFormatterJson.cs +++ b/src/Product/MicroWorkflow/DotNetStepStateFormatterJson.cs @@ -1,45 +1,45 @@ -using System.Text.Json; - -namespace GreenFeetWorkflow; - -public class DotNetStepStateFormatterJson : IWorkflowStepStateFormatter -{ - private readonly IWorkflowLogger logger; - - public string StateFormatName => "json"; - - public DotNetStepStateFormatterJson(IWorkflowLogger logger) - { - this.logger = logger; - } - - public string Serialize(object? binaryState) - { - try - { - return JsonSerializer.Serialize(binaryState); - } - catch (Exception ex) - { - if (logger.ErrorLoggingEnabled) - logger.LogError($"Error serializing object.", ex, new Dictionary() { { "state", binaryState } }); - throw; - } - } - - public T? Deserialize(string? state) - { - try - { +using System.Text.Json; + +namespace MicroWorkflow; + +public class DotNetStepStateFormatterJson : IWorkflowStepStateFormatter +{ + private readonly IWorkflowLogger logger; + + public string StateFormatName => "json"; + + public DotNetStepStateFormatterJson(IWorkflowLogger logger) + { + this.logger = logger; + } + + public string Serialize(object? binaryState) + { + try + { + return JsonSerializer.Serialize(binaryState); + } + catch (Exception ex) + { + if (logger.ErrorLoggingEnabled) + logger.LogError($"Error serializing object.", ex, new Dictionary() { { "state", binaryState } }); + throw; + } + } + + public T? Deserialize(string? state) + { + try + { if (state == null) - return default; - return JsonSerializer.Deserialize(state); - } - catch (Exception ex) - { - if (logger.ErrorLoggingEnabled) - logger.LogError($"Error deserializing object.", ex, new Dictionary() { { "json", state } }); - throw; - } - } + return default; + return JsonSerializer.Deserialize(state); + } + catch (Exception ex) + { + if (logger.ErrorLoggingEnabled) + logger.LogError($"Error deserializing object.", ex, new Dictionary() { { "json", state } }); + throw; + } + } } \ No newline at end of file diff --git a/src/Product/GreenFeetWorkFlow/ExecutionResult.cs b/src/Product/MicroWorkflow/ExecutionResult.cs similarity index 94% rename from src/Product/GreenFeetWorkFlow/ExecutionResult.cs rename to src/Product/MicroWorkflow/ExecutionResult.cs index bf75244..19232d9 100644 --- a/src/Product/GreenFeetWorkFlow/ExecutionResult.cs +++ b/src/Product/MicroWorkflow/ExecutionResult.cs @@ -1,4 +1,4 @@ -namespace GreenFeetWorkflow; +namespace MicroWorkflow; public class ExecutionResult { @@ -86,8 +86,7 @@ public static FailCurrentStepException FailAsException(string? description = nul public ExecutionResult With(Step newstep) { - if (NewSteps == null) - NewSteps = new List(); + NewSteps ??= new List(); NewSteps.Add(newstep); diff --git a/src/Product/MicroWorkflow/FailCurrentStepException.cs b/src/Product/MicroWorkflow/FailCurrentStepException.cs new file mode 100644 index 0000000..a9a6c23 --- /dev/null +++ b/src/Product/MicroWorkflow/FailCurrentStepException.cs @@ -0,0 +1,15 @@ +namespace MicroWorkflow; + +/// +/// throwing this exception makes a step FAIL rather than RETRY it later. +/// +public class FailCurrentStepException : Exception +{ + public Step[]? NewSteps { get; set; } + + public FailCurrentStepException(string? description = null, Exception? innerException = null, params Step[]? newSteps) + : base(description, innerException) + { + NewSteps = newSteps; + } +} diff --git a/src/Product/GreenFeetWorkFlow/GenericImplementation.cs b/src/Product/MicroWorkflow/GenericImplementation.cs similarity index 86% rename from src/Product/GreenFeetWorkFlow/GenericImplementation.cs rename to src/Product/MicroWorkflow/GenericImplementation.cs index cbaa9c4..747f282 100644 --- a/src/Product/GreenFeetWorkFlow/GenericImplementation.cs +++ b/src/Product/MicroWorkflow/GenericImplementation.cs @@ -1,4 +1,4 @@ -namespace GreenFeetWorkflow; +namespace MicroWorkflow; /// /// Class that converts an Action to a IStepImplementation @@ -9,8 +9,7 @@ public class GenericImplementation : IStepImplementation public GenericImplementation(Func code) { - if (code == null) - throw new ArgumentNullException(nameof(code)); + ArgumentNullException.ThrowIfNull(code); this.code = async (s) => await Task.FromResult(code(s)); } diff --git a/src/Product/GreenFeetWorkFlow/Interfaces.cs b/src/Product/MicroWorkflow/Interfaces.cs similarity index 88% rename from src/Product/GreenFeetWorkFlow/Interfaces.cs rename to src/Product/MicroWorkflow/Interfaces.cs index 5e0889e..ea94f8e 100644 --- a/src/Product/GreenFeetWorkFlow/Interfaces.cs +++ b/src/Product/MicroWorkflow/Interfaces.cs @@ -1,5 +1,8 @@ -namespace GreenFeetWorkflow; +namespace MicroWorkflow; +/// +/// Use steps in an untyped fashion where you deserialize the state of the step and handle errors +/// public interface IStepImplementation { Task ExecuteAsync(Step step); @@ -19,6 +22,9 @@ public interface IWorkflowLogger void LogError(string? msg, Exception? exception, Dictionary? arguments); } +/// +/// Implement this to use whatever ioc container youw ant +/// public interface IWorkflowIocContainer { /// implement to return null wnen registration is not found, and throw exception on creation failure. diff --git a/src/Product/GreenFeetWorkFlow/LICENSE b/src/Product/MicroWorkflow/LICENSE similarity index 100% rename from src/Product/GreenFeetWorkFlow/LICENSE rename to src/Product/MicroWorkflow/LICENSE diff --git a/src/Product/GreenFeetWorkFlow/Loggers.cs b/src/Product/MicroWorkflow/Loggers.cs similarity index 93% rename from src/Product/GreenFeetWorkFlow/Loggers.cs rename to src/Product/MicroWorkflow/Loggers.cs index cb3d11b..aaeabd4 100644 --- a/src/Product/GreenFeetWorkFlow/Loggers.cs +++ b/src/Product/MicroWorkflow/Loggers.cs @@ -1,7 +1,7 @@ using System.Diagnostics; using System.Text; -namespace GreenFeetWorkflow; +namespace MicroWorkflow; public abstract class GenericStepLogger : IWorkflowLogger @@ -78,10 +78,6 @@ public class ConsoleStepLogger : GenericStepLogger { private static readonly object Lock = new object(); - public ConsoleStepLogger() : this(new LoggerConfiguration()) - { - } - public ConsoleStepLogger(LoggerConfiguration cfg) : base(cfg, Print) { } @@ -110,10 +106,6 @@ static void Print(string severity, Exception? e, string? msg, Dictionary public class DiagnosticsStepLogger : GenericStepLogger { - public DiagnosticsStepLogger() : this(new LoggerConfiguration()) - { - } - public DiagnosticsStepLogger(LoggerConfiguration cfg) : base(cfg, Print) { } diff --git a/src/Product/GreenFeetWorkFlow/GreenFeetWorkFlow.csproj b/src/Product/MicroWorkflow/MicroWorkflow.csproj similarity index 86% rename from src/Product/GreenFeetWorkFlow/GreenFeetWorkFlow.csproj rename to src/Product/MicroWorkflow/MicroWorkflow.csproj index 9f48e6d..a35cb58 100644 --- a/src/Product/GreenFeetWorkFlow/GreenFeetWorkFlow.csproj +++ b/src/Product/MicroWorkflow/MicroWorkflow.csproj @@ -11,7 +11,7 @@ Kasper B. Graversen README.md - https://github.com/kbilsted/GreenFeetWorkflow + https://github.com/kbilsted/MicroWorkflow.net LICENSE latest @@ -23,9 +23,9 @@ Kasper B. Graversen true - https://github.com/kbilsted/GreenFeetWorkFlow + https://github.com/kbilsted/MicroWorkflow.net - workflow; work flow; workflows; Embedable; GreenFeetWorkFlow; free; Open source + workflow; work flow; workflows; Embedable; free; Open source True diff --git a/src/Product/GreenFeetWorkFlow/README.md b/src/Product/MicroWorkflow/README.md similarity index 52% rename from src/Product/GreenFeetWorkFlow/README.md rename to src/Product/MicroWorkflow/README.md index 08c94ec..2b5379d 100644 --- a/src/Product/GreenFeetWorkFlow/README.md +++ b/src/Product/MicroWorkflow/README.md @@ -1,6 +1,6 @@ -# GreenFeetWorkFlow .Net +# MicroWorkflow .Net .Net This is the main workflow engine implementation. Please check out the main readme at -https://github.com/kbilsted/GreenFeetWorkFlow +https://github.com/kbilsted/MicroWorkflow .Net diff --git a/src/Product/GreenFeetWorkFlow/ReflectionHelper.cs b/src/Product/MicroWorkflow/ReflectionHelper.cs similarity index 57% rename from src/Product/GreenFeetWorkFlow/ReflectionHelper.cs rename to src/Product/MicroWorkflow/ReflectionHelper.cs index 5fbc301..63603c6 100644 --- a/src/Product/GreenFeetWorkFlow/ReflectionHelper.cs +++ b/src/Product/MicroWorkflow/ReflectionHelper.cs @@ -1,6 +1,6 @@ using System.Reflection; -namespace GreenFeetWorkflow; +namespace MicroWorkflow; public class ReflectionHelper { @@ -10,18 +10,12 @@ public static IEnumerable<(Type implementationType, string stepName)> GetStepsFr { var result = new Dictionary(); - foreach (var assembly in assemblies) + foreach (var step in assemblies.SelectMany(x => GetSteps(x))) { - var steps = GetSteps(assembly); + if (result.TryGetValue(step.stepName, out var existingStep)) + throw new Exception($"Duplicate step name (name:{step.stepName}, type: {step.implementationType}) matches (name:{existingStep.stepName}, type: {existingStep.implementationType})"); - foreach (var step in steps) - { - if (result.TryGetValue(step.stepName, out var existingStep)) - throw new Exception( - $"Duplicate step name (name:{step.stepName}, type: {step.implementationType}) matches (name:{existingStep.stepName}, type: {existingStep.implementationType})"); - - result.Add(step.stepName, step); - } + result.Add(step.stepName, step); } return result.Values; @@ -31,9 +25,7 @@ static IEnumerable<(Type implementationType, string stepName)> GetSteps(Assembly { var x = a.GetTypes() .Select(x => new { type = x, attrs = x.GetCustomAttributes() }) - .SelectMany(x => x.attrs, resultSelector: (x, a) => (x.type, a.Name)) - .ToArray(); - + .SelectMany(x => x.attrs, resultSelector: (x, a) => (x.type, a.Name)); return x; } } diff --git a/src/Product/GreenFeetWorkFlow/SearchModel.cs b/src/Product/MicroWorkflow/SearchModel.cs similarity index 51% rename from src/Product/GreenFeetWorkFlow/SearchModel.cs rename to src/Product/MicroWorkflow/SearchModel.cs index 260d5ec..0888565 100644 --- a/src/Product/GreenFeetWorkFlow/SearchModel.cs +++ b/src/Product/MicroWorkflow/SearchModel.cs @@ -1,4 +1,4 @@ -namespace GreenFeetWorkflow; +namespace MicroWorkflow; public record SearchModel ( @@ -14,10 +14,10 @@ public record SearchModel string? Description = null ); -public record FetchLevels(bool Ready = false, bool Done = false, bool Fail = false, int MaxRows = 100) +public record FetchLevels(bool Ready = false, bool Done = false, bool Fail = false, int MaxRows = 1000) { - public static FetchLevels ALL = new FetchLevels(true, true, true); - public static FetchLevels READY = new FetchLevels(true, false, false); - public static FetchLevels NONREADY = new FetchLevels(false, true, true); - public static FetchLevels FAILED = new FetchLevels(false, false, true); + public static readonly FetchLevels ALL = new(true, true, true); + public static readonly FetchLevels READY = new(true, false, false); + public static readonly FetchLevels NONREADY = new(false, true, true); + public static readonly FetchLevels FAILED = new(false, false, true); }; diff --git a/src/Product/GreenFeetWorkFlow/Step.cs b/src/Product/MicroWorkflow/Step.cs similarity index 97% rename from src/Product/GreenFeetWorkFlow/Step.cs rename to src/Product/MicroWorkflow/Step.cs index b6d9210..b1f1af4 100644 --- a/src/Product/GreenFeetWorkFlow/Step.cs +++ b/src/Product/MicroWorkflow/Step.cs @@ -1,4 +1,4 @@ -namespace GreenFeetWorkflow; +namespace MicroWorkflow; public class Step { @@ -57,7 +57,7 @@ public class Step /// The time the step was created public DateTime CreatedTime { get; set; } - + /// The 'parent', i.e. the step which created this step. If there is no parent, 0 is used. /// Steps created from a step will have its parent set (unless you overwrite it). /// @@ -78,7 +78,7 @@ public Step(string name, object? state) Name = name; InitialState = state; } - + /// Mark the step as finished successfully. public ExecutionResult Done() => ExecutionResult.Done(); diff --git a/src/Product/GreenFeetWorkFlow/StepNameAttribute.cs b/src/Product/MicroWorkflow/StepNameAttribute.cs similarity index 84% rename from src/Product/GreenFeetWorkFlow/StepNameAttribute.cs rename to src/Product/MicroWorkflow/StepNameAttribute.cs index 4c9cec6..37a6ab9 100644 --- a/src/Product/GreenFeetWorkFlow/StepNameAttribute.cs +++ b/src/Product/MicroWorkflow/StepNameAttribute.cs @@ -1,4 +1,4 @@ -namespace GreenFeetWorkflow; +namespace MicroWorkflow; /// /// use this attribute as an easy way to register stepnames for implementations @@ -11,7 +11,7 @@ public StepNameAttribute(string name) { if (name == null) throw new ArgumentNullException(nameof(name)); - if (name.StartsWith(" ") || name.EndsWith(" ")) + if (name.StartsWith(' ') || name.EndsWith(' ')) throw new Exception($"{nameof(StepNameAttribute)} instance with Name '{name}' may not start or end with ' '."); Name = name; diff --git a/src/Product/GreenFeetWorkFlow/StepStatus.cs b/src/Product/MicroWorkflow/StepStatus.cs similarity index 60% rename from src/Product/GreenFeetWorkFlow/StepStatus.cs rename to src/Product/MicroWorkflow/StepStatus.cs index 7267c1c..bb70fc9 100644 --- a/src/Product/GreenFeetWorkFlow/StepStatus.cs +++ b/src/Product/MicroWorkflow/StepStatus.cs @@ -1,4 +1,4 @@ -namespace GreenFeetWorkflow; +namespace MicroWorkflow; public enum StepStatus { diff --git a/src/Product/GreenFeetWorkFlow/Worker.cs b/src/Product/MicroWorkflow/Worker.cs similarity index 94% rename from src/Product/GreenFeetWorkFlow/Worker.cs rename to src/Product/MicroWorkflow/Worker.cs index 14844cf..6fc961e 100644 --- a/src/Product/GreenFeetWorkFlow/Worker.cs +++ b/src/Product/MicroWorkflow/Worker.cs @@ -1,6 +1,6 @@ using System.Diagnostics; -namespace GreenFeetWorkflow; +namespace MicroWorkflow; public class Worker { @@ -154,11 +154,11 @@ async Task ExecuteLoop() catch (Exception ex) { Debug.WriteLine($"{nameof(Worker)}:****************************************************"); - Debug.WriteLine($"GreenFeetWorkflow unhandled exception{ex}\n{ex.StackTrace}"); + Debug.WriteLine($"MicroWorkflow.net unhandled exception{ex}\n{ex.StackTrace}"); Debug.WriteLine($"{nameof(Worker)}:****************************************************"); if (logger.ErrorLoggingEnabled) - logger.LogError($"{nameof(Worker)}: GreenFeetWorkflow unhandled exception", ex, null); + logger.LogError($"{nameof(Worker)}: MicroWorkflow.net unhandled exception", ex, null); StoppingToken.WaitHandle.WaitOne(workerConfig.DelayTechnicalTransientError); } @@ -257,7 +257,7 @@ async Task FetchExecuteStoreStep() { var args = CreateLogContext(step); args.Add("executionDuration", step.ExecutionDurationMillis); - args.Add("newSteps", result.NewSteps?.Count() ?? 0); + args.Add("newSteps", result.NewSteps?.Count ?? 0); logger.LogInfo($"{nameof(Worker)}: Execution result: {result.Status}.", null, args); } @@ -313,7 +313,7 @@ private bool PersistChanges(IStepPersister persister, Step step, ExecutionResult } if (result.NewSteps != null) - persister.Insert(StepStatus.Ready, result.NewSteps.ToArray()); + _ = persister.Insert(StepStatus.Ready, result.NewSteps.ToArray()); persister.Commit(); } diff --git a/src/Product/GreenFeetWorkFlow/WorkerCoordinator.cs b/src/Product/MicroWorkflow/WorkerCoordinator.cs similarity index 96% rename from src/Product/GreenFeetWorkFlow/WorkerCoordinator.cs rename to src/Product/MicroWorkflow/WorkerCoordinator.cs index 6cf58fb..4f85349 100644 --- a/src/Product/GreenFeetWorkFlow/WorkerCoordinator.cs +++ b/src/Product/MicroWorkflow/WorkerCoordinator.cs @@ -1,4 +1,4 @@ -namespace GreenFeetWorkflow; +namespace MicroWorkflow; /// /// Shared among all workers of the same engine. Coordinates when new tasks spawn and may die diff --git a/src/Product/GreenFeetWorkFlow/WorkflowConfiguration.cs b/src/Product/MicroWorkflow/WorkflowConfiguration.cs similarity index 79% rename from src/Product/GreenFeetWorkFlow/WorkflowConfiguration.cs rename to src/Product/MicroWorkflow/WorkflowConfiguration.cs index 1abdbcb..ec68289 100644 --- a/src/Product/GreenFeetWorkFlow/WorkflowConfiguration.cs +++ b/src/Product/MicroWorkflow/WorkflowConfiguration.cs @@ -1,8 +1,8 @@ -namespace GreenFeetWorkflow; +namespace MicroWorkflow; public record WorkflowConfiguration(WorkerConfig WorkerConfig) { - public LoggerConfiguration LoggerConfiguration { get; set; } + public LoggerConfiguration LoggerConfiguration { get; set; } = LoggerConfiguration.INFO; } public class LoggerConfiguration @@ -17,13 +17,21 @@ public class LoggerConfiguration public bool InfoLoggingEnabled => DateTime.Now < InfoLoggingEnabledUntil; public bool ErrorLoggingEnabled => DateTime.Now < ErrorLoggingEnabledUntil; - public static LoggerConfiguration OFF = new LoggerConfiguration() + public static readonly LoggerConfiguration OFF = new LoggerConfiguration() { ErrorLoggingEnabledUntil = DateTime.MinValue, InfoLoggingEnabledUntil = DateTime.MinValue, DebugLoggingEnabledUntil = DateTime.MinValue, TraceLoggingEnabledUntil = DateTime.MinValue, }; + + public static readonly LoggerConfiguration INFO = new LoggerConfiguration() + { + ErrorLoggingEnabledUntil = DateTime.MaxValue, + InfoLoggingEnabledUntil = DateTime.MaxValue, + DebugLoggingEnabledUntil = DateTime.MinValue, + TraceLoggingEnabledUntil = DateTime.MinValue, + }; } public record WorkerConfig() diff --git a/src/Product/GreenFeetWorkFlow/WorkflowEngine.cs b/src/Product/MicroWorkflow/WorkflowEngine.cs similarity index 96% rename from src/Product/GreenFeetWorkFlow/WorkflowEngine.cs rename to src/Product/MicroWorkflow/WorkflowEngine.cs index f915f1c..4369051 100644 --- a/src/Product/GreenFeetWorkFlow/WorkflowEngine.cs +++ b/src/Product/MicroWorkflow/WorkflowEngine.cs @@ -1,4 +1,4 @@ -namespace GreenFeetWorkflow; +namespace MicroWorkflow; public class WorkflowEngine { diff --git a/src/Product/GreenFeetWorkFlow/WorkflowRuntimeData.cs b/src/Product/MicroWorkflow/WorkflowRuntimeData.cs similarity index 97% rename from src/Product/GreenFeetWorkFlow/WorkflowRuntimeData.cs rename to src/Product/MicroWorkflow/WorkflowRuntimeData.cs index 527041d..e7c0338 100644 --- a/src/Product/GreenFeetWorkFlow/WorkflowRuntimeData.cs +++ b/src/Product/MicroWorkflow/WorkflowRuntimeData.cs @@ -1,4 +1,4 @@ -namespace GreenFeetWorkflow; +namespace MicroWorkflow; public class WorkflowRuntimeData { diff --git a/src/Product/GreenFeetWorkFlow/WorkflowRuntimeMetrics.cs b/src/Product/MicroWorkflow/WorkflowRuntimeMetrics.cs similarity index 89% rename from src/Product/GreenFeetWorkFlow/WorkflowRuntimeMetrics.cs rename to src/Product/MicroWorkflow/WorkflowRuntimeMetrics.cs index c0966c8..f1d2e2d 100644 --- a/src/Product/GreenFeetWorkFlow/WorkflowRuntimeMetrics.cs +++ b/src/Product/MicroWorkflow/WorkflowRuntimeMetrics.cs @@ -1,4 +1,4 @@ -namespace GreenFeetWorkflow; +namespace MicroWorkflow; public class WorkflowRuntimeMetrics { diff --git a/src/Product/GreenFeetWorkFlow/todos.md b/src/Product/MicroWorkflow/todos.md similarity index 96% rename from src/Product/GreenFeetWorkFlow/todos.md rename to src/Product/MicroWorkflow/todos.md index b1ab312..cdbdcf5 100644 --- a/src/Product/GreenFeetWorkFlow/todos.md +++ b/src/Product/MicroWorkflow/todos.md @@ -18,7 +18,7 @@ * explain why we dont store the raw type from step state objects. will be serialized eg into System.Collections.Generic.Dictionary`2[[System.String, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Object, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]] or - GreenFeetWorkflow.Tests+BuyInstructions + MicroWorkflow.Tests+BuyInstructions we dont want to rely on corelib in v6 or that we use very specific private classes diff --git a/src/createRelease.cmd b/src/createRelease.cmd index 9ef9fa8..6fd66b9 100644 --- a/src/createRelease.cmd +++ b/src/createRelease.cmd @@ -1,5 +1,5 @@ -cd C:\src\GreenFeetWorkFlow\src -copy ..\README.md .\Product\GreenFeetWorkFlow\README.md +cd C:\src\MicroWorkflow\src +copy ..\README.md .\Product\MicroWorkflow\README.md dotnet build dotnet pack --include-source -p:PackageVersion=1.3.2.0 -o:.\releases cd releases