Skip to content

Commit

Permalink
Merge pull request #26 from osstotalsoft/feature/process_manager
Browse files Browse the repository at this point in the history
add process manager
  • Loading branch information
fraliv13 authored Oct 17, 2019
2 parents 586bdb2 + 41a1e42 commit e4e5995
Show file tree
Hide file tree
Showing 51 changed files with 2,224 additions and 6 deletions.
4 changes: 2 additions & 2 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
<Version>$(GitVersion_NuGetVersion)</Version>
<Authors>Totalsoft</Authors>
<Company>Totalsoft</Company>
<PackageTags>totalsoft charisma</PackageTags>
<PackageTags>totalsoft nbb</PackageTags>

<PublishRepositoryUrl>true</PublishRepositoryUrl>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-18618-05" PrivateAssets="All"/>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-19367-01" PrivateAssets="All"/>
</ItemGroup>
</Project>
29 changes: 28 additions & 1 deletion NBB.sln
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,17 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{F577
.github\release-drafter.yml = .github\release-drafter.yml
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NBB.Correlation.Serilog.SqlServer", "src\Correlation\NBB.Correlation.Serilog.SqlServer\NBB.Correlation.Serilog.SqlServer.csproj", "{F442DC3C-D2E9-468F-A6E3-D639E6F5D168}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NBB.Correlation.Serilog.SqlServer", "src\Correlation\NBB.Correlation.Serilog.SqlServer\NBB.Correlation.Serilog.SqlServer.csproj", "{F442DC3C-D2E9-468F-A6E3-D639E6F5D168}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Orchestration", "Orchestration", "{7D20C931-B59B-4227-A916-3DE892F7A78A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NBB.ProcessManager.Definition", "src\Orchestration\NBB.ProcessManager.Definition\NBB.ProcessManager.Definition.csproj", "{501EF886-EF0C-4067-BBF8-1768F2747E67}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NBB.ProcessManager.Runtime", "src\Orchestration\NBB.ProcessManager.Runtime\NBB.ProcessManager.Runtime.csproj", "{D11FE59A-F3FE-4A7D-85B3-252294B6447C}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Orchestration", "Orchestration", "{FE39B11B-26E0-4EDA-AA33-18E1D5EB63D8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NBB.ProcessManager.Tests", "test\UnitTests\Orchestration\NBB.ProcessManager.Tests\NBB.ProcessManager.Tests.csproj", "{DB6CACB0-CDC1-47CD-B89E-BE24D9238472}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -670,6 +680,18 @@ Global
{F442DC3C-D2E9-468F-A6E3-D639E6F5D168}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F442DC3C-D2E9-468F-A6E3-D639E6F5D168}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F442DC3C-D2E9-468F-A6E3-D639E6F5D168}.Release|Any CPU.Build.0 = Release|Any CPU
{501EF886-EF0C-4067-BBF8-1768F2747E67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{501EF886-EF0C-4067-BBF8-1768F2747E67}.Debug|Any CPU.Build.0 = Debug|Any CPU
{501EF886-EF0C-4067-BBF8-1768F2747E67}.Release|Any CPU.ActiveCfg = Release|Any CPU
{501EF886-EF0C-4067-BBF8-1768F2747E67}.Release|Any CPU.Build.0 = Release|Any CPU
{D11FE59A-F3FE-4A7D-85B3-252294B6447C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D11FE59A-F3FE-4A7D-85B3-252294B6447C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D11FE59A-F3FE-4A7D-85B3-252294B6447C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D11FE59A-F3FE-4A7D-85B3-252294B6447C}.Release|Any CPU.Build.0 = Release|Any CPU
{DB6CACB0-CDC1-47CD-B89E-BE24D9238472}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DB6CACB0-CDC1-47CD-B89E-BE24D9238472}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DB6CACB0-CDC1-47CD-B89E-BE24D9238472}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DB6CACB0-CDC1-47CD-B89E-BE24D9238472}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -803,6 +825,11 @@ Global
{9DDF53B1-7728-4CF3-BEBE-2057A6956F59} = {48E5BC6A-5846-4AD7-BFFB-C1D04C5C1BC2}
{F57779EB-9107-427D-A65C-5AA262C348E1} = {EB7B0468-DE25-4350-80AD-50E7C4D09120}
{F442DC3C-D2E9-468F-A6E3-D639E6F5D168} = {307E1650-6128-4A36-9C98-297F2BF71C83}
{7D20C931-B59B-4227-A916-3DE892F7A78A} = {7311E32F-C1B0-41C9-B5F1-DE9EBB6ABB55}
{501EF886-EF0C-4067-BBF8-1768F2747E67} = {7D20C931-B59B-4227-A916-3DE892F7A78A}
{D11FE59A-F3FE-4A7D-85B3-252294B6447C} = {7D20C931-B59B-4227-A916-3DE892F7A78A}
{FE39B11B-26E0-4EDA-AA33-18E1D5EB63D8} = {83E383BB-C9D9-4F5F-BAAF-FF1ADFF0B151}
{DB6CACB0-CDC1-47CD-B89E-BE24D9238472} = {FE39B11B-26E0-4EDA-AA33-18E1D5EB63D8}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {23A42379-616A-43EF-99BC-803DF151F54E}
Expand Down
6 changes: 3 additions & 3 deletions dependencies.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
<PropertyGroup Label="Package Versions">
<NewtonsoftJsonPackageVersion>11.0.2</NewtonsoftJsonPackageVersion>
<MediatRPackageVersion>4.1.0</MediatRPackageVersion>
<ScrutorPackageVersion>3.0.1</ScrutorPackageVersion>
<ScrutorPackageVersion>3.1.0</ScrutorPackageVersion>
<BenchmarkDotNetPackageVersion>0.10.14</BenchmarkDotNetPackageVersion>
<MoqPackageVersion>4.8.2</MoqPackageVersion>
<XunitPackageVersion>2.3.1</XunitPackageVersion>
<XunitRunnerVisualStudioPackageVersion>2.4.0-beta.1.build3958</XunitRunnerVisualStudioPackageVersion>
<FluentAssertionsPackageVersion>5.3.2</FluentAssertionsPackageVersion>
<MicrosoftExtensionsPackagesVersion>2.1.1</MicrosoftExtensionsPackagesVersion>
<MicrosoftExtensionsPackagesVersion>2.2.0</MicrosoftExtensionsPackagesVersion>
<MicrosoftEntityFrameworkPackagesVersion>2.1.4</MicrosoftEntityFrameworkPackagesVersion>
<MicrosoftAspNetCoreAppPackageVersion>2.1.5</MicrosoftAspNetCoreAppPackageVersion>
<MicrosoftCSharpPackageVersion>4.5.0</MicrosoftCSharpPackageVersion>
<MicrosoftCSharpPackageVersion>4.6.0</MicrosoftCSharpPackageVersion>
<SerilogPackageVersion>2.7.1</SerilogPackageVersion>
<SerilogExtensionsLoggingPackageVersion>2.0.2</SerilogExtensionsLoggingPackageVersion>
<SerilogSinksMSSqlServerPackageVersion>5.1.2</SerilogSinksMSSqlServerPackageVersion>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
using NBB.Core.Abstractions;
using System;
using System.Collections.Generic;
using System.Linq;

namespace NBB.ProcessManager.Definition.Builder
{
public abstract class AbstractDefinition<TData> : IDefinition<TData>
where TData : struct
{
private readonly List<IEventActivitySet<TData>> _eventActivities = new List<IEventActivitySet<TData>>();
private readonly Dictionary<Type, EventCorrelation<IEvent, TData>> _eventCorrelations = new Dictionary<Type, EventCorrelation<IEvent, TData>>();


public EventActivitySetBuilder<TEvent, TData> StartWith<TEvent>(EventPredicate<TEvent, TData> predicate = null)
where TEvent : IEvent
{
var ea = new EventActivitySet<TEvent, TData>(true, predicate);
_eventActivities.Add(ea);
return new EventActivitySetBuilder<TEvent, TData>(ea);
}

public EventActivitySetBuilder<TEvent, TData> When<TEvent>(EventPredicate<TEvent, TData> predicate = null)
where TEvent : IEvent
{
var ea = new EventActivitySet<TEvent, TData>(false, predicate);
_eventActivities.Add(ea);
return new EventActivitySetBuilder<TEvent, TData>(ea);
}

public void Event<TEvent>(Action<EventCorrelationBuilder<TEvent, TData>> configureEventCorrelation)
{
Preconditions.NotNull(configureEventCorrelation, nameof(configureEventCorrelation));

var configurator = new EventCorrelationBuilder<TEvent, TData>();
configureEventCorrelation(configurator);
var correl = configurator.Build();
_eventCorrelations.Add(typeof(TEvent), new EventCorrelation<IEvent, TData>(@event => correl.CorrelationFilter((TEvent) @event)));
}

public Func<TEvent, object> GetCorrelationFilter<TEvent>() where TEvent : IEvent
{
if (_eventCorrelations.ContainsKey(typeof(TEvent)))
{
var func = _eventCorrelations[typeof(TEvent)];
return @event => func.CorrelationFilter(@event);
}

return null;
}

public IEnumerable<Type> GetEventTypes() => _eventActivities.Select(x => x.EventType).Distinct();

public IEnumerable<ValueTuple<EventPredicate<IEvent, TData>, IEnumerable<EffectHandler<IEvent, TData>>>> GetEffectHandlers(Type eventType)
{
return _eventActivities
.Where(x => x.EventType == eventType)
.Select(x => (x.WhenPredicate, x.GetEffectHandlers()));
}

public IEnumerable<ValueTuple<EventPredicate<IEvent, TData>, IEnumerable<StateHandler<IEvent, TData>>>> GetStateHandlers(Type eventType)
{
return _eventActivities
.Where(x => x.EventType == eventType)
.Select(x => (x.WhenPredicate, x.GetStateHandlers()));
}

public EventPredicate<TEvent, TData> GetStarterPredicate<TEvent>() where TEvent : IEvent
{
var act = _eventActivities
.SingleOrDefault(x => x.EventType == typeof(TEvent) && x.StartsProcess);
return (@event, data) =>
{
if (act == null)
return false;
return act.WhenPredicate?.Invoke(@event, data) ?? true;
};
}

public IEnumerable<EventPredicate<TEvent, TData>> GetCompletionPredicates<TEvent>() where TEvent : IEvent
{
foreach (var x in _eventActivities)
{
if (x.EventType == typeof(TEvent) && x.CompletesProcess)
yield return (@event, data) =>
{
if (x.CompletionPredicate != null && x.WhenPredicate != null)
return x.CompletionPredicate(@event, data) && x.WhenPredicate(@event, data);
if (x.CompletionPredicate == null && x.WhenPredicate != null)
return x.WhenPredicate(@event, data);
if (x.CompletionPredicate != null && x.WhenPredicate == null)
return x.CompletionPredicate(@event, data);
return true;
};
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using NBB.Core.Abstractions;
using System;
using System.Collections.Generic;

namespace NBB.ProcessManager.Definition.Builder
{

public class EventActivitySet<TEvent, TData> : IEventActivitySet<TData>
where TEvent : IEvent
where TData : struct
{
private readonly List<EffectHandler<IEvent, TData>> _handlers = new List<EffectHandler<IEvent, TData>>();
private readonly List<StateHandler<IEvent, TData>> _setStateHandlers = new List<StateHandler<IEvent, TData>>();
private readonly EventPredicate<TEvent, TData> _whenPredicate;
private EventPredicate<TEvent, TData> _completionPredicate;
public bool StartsProcess { get; set; }
public bool CompletesProcess { get; set; }

public EventActivitySet(bool startsProcess, EventPredicate<TEvent, TData> whenPredicate = null)
{
StartsProcess = startsProcess;
_whenPredicate = whenPredicate;
}

public Type EventType => typeof(TEvent);

public IEnumerable<EffectHandler<IEvent, TData>> GetEffectHandlers()
{
return _handlers;
}

public IEnumerable<StateHandler<IEvent, TData>> GetStateHandlers()
{
return _setStateHandlers;
}

public void AddEffectHandler(EffectHandler<TEvent, TData> handler)
{
_handlers.Add((@event, data) => handler((TEvent) @event, data));
}

public void AddSetStateHandler(StateHandler<TEvent, TData> handler)
{
_setStateHandlers.Add((@event, data) => handler((TEvent) @event, data));
}

public EventPredicate<IEvent, TData> WhenPredicate
{
get
{
if (_whenPredicate == null)
return null;
return (@event, data) => _whenPredicate((TEvent) @event, data);
}
}

public EventPredicate<IEvent, TData> CompletionPredicate
{
get
{
if (_completionPredicate == null)
return null;
return (@event, data) => _completionPredicate((TEvent) @event, data);
}
}

public void UseForCompletion(EventPredicate<TEvent, TData> predicate)
{
_completionPredicate = predicate;
CompletesProcess = true;
}
}

public interface IEventActivitySet<TData>
where TData : struct
{
Type EventType { get; }
bool CompletesProcess { get; }
bool StartsProcess { get; }
EventPredicate<IEvent, TData> WhenPredicate { get; }
EventPredicate<IEvent, TData> CompletionPredicate { get; }
IEnumerable<EffectHandler<IEvent, TData>> GetEffectHandlers();
IEnumerable<StateHandler<IEvent, TData>> GetStateHandlers();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
using NBB.Core.Abstractions;
using NBB.ProcessManager.Definition.Effects;
using System;

namespace NBB.ProcessManager.Definition.Builder
{
public class EventActivitySetBuilder<TEvent, TData>
where TEvent : IEvent
where TData : struct
{
private readonly EventActivitySet<TEvent, TData> _eventActivitySet;

public EventActivitySetBuilder(EventActivitySet<TEvent, TData> eventActivitySet)
{
_eventActivitySet = eventActivitySet;
}

public EventActivitySetBuilder<TEvent, TData> Then(EffectHandler<TEvent, TData> handler, EventPredicate<TEvent, TData> predicate = null)
{
_eventActivitySet.AddEffectHandler((whenEvent, data) =>
{
if (predicate != null && !predicate(whenEvent, data))
return NoEffect.Instance;
return handler(whenEvent, data);
});
return this;
}

public EventActivitySetBuilder<TEvent, TData> SetState(StateHandler<TEvent, TData> handler, EventPredicate<TEvent, TData> predicate = null)
{
_eventActivitySet.AddSetStateHandler((whenEvent, data) =>
{
if (predicate != null && !predicate(whenEvent, data))
return data.Data;
return handler(whenEvent, data);
});
return this;
}

public EventActivitySetBuilder<TEvent, TData> SendCommand<T>(Func<TEvent, InstanceData<TData>, T> handler, EventPredicate<TEvent, TData> predicate = null)
where T : ICommand
{
Then((whenEvent, state) =>
{
var command = handler(whenEvent, state);
return new SendCommand(command);
}, predicate);
return this;
}

public EventActivitySetBuilder<TEvent, TData> RequestTimeout<T>(TimeSpan timeSpan, EventPredicate<TEvent, TData> predicate = null)
where T : IEvent, new()
{
RequestTimeout(timeSpan, new T(), predicate);
return this;
}

public EventActivitySetBuilder<TEvent, TData> RequestTimeout<T>(TimeSpan timeSpan, T message, EventPredicate<TEvent, TData> predicate = null)
where T : IEvent
{
Then((whenEvent, state) => new RequestTimeout(state.CorrelationId.ToString(), timeSpan, message, typeof(T)), predicate);
return this;
}

public EventActivitySetBuilder<TEvent, TData> PublishEvent<T>(Func<TEvent, InstanceData<TData>, T> handler, EventPredicate<TEvent, TData> predicate = null)
where T : IEvent
{
Then((whenEvent, state) =>
{
var @event = handler(whenEvent, state);
return new PublishEvent(@event);
}, predicate);
return this;
}

public void Complete(EventPredicate<TEvent, TData> predicate = null)
{
_eventActivitySet.UseForCompletion(predicate);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using System.Linq.Expressions;
using NBB.Core.Abstractions;

namespace NBB.ProcessManager.Definition.Builder
{
public class EventCorrelation<TEvent, TData>
{
public Func<TEvent, object> CorrelationFilter { get; set; }

public EventCorrelation(Func<TEvent, object> correlationFilter)
{
CorrelationFilter = correlationFilter;
}
}
}
Loading

0 comments on commit e4e5995

Please sign in to comment.