Started working on the engine for the workflow processor
This commit is contained in:
parent
ad8363b5d6
commit
4bf1ab73fa
@ -5,7 +5,7 @@ namespace e_suite.API.Common;
|
||||
|
||||
public class GetWorkflowTemplate : IGeneralId
|
||||
{
|
||||
public GetWorkflowTemplate( Workflow workflow)
|
||||
public GetWorkflowTemplate( Database.Core.Tables.Workflow.Workflow workflow)
|
||||
{
|
||||
Id = workflow.Id;
|
||||
Guid = workflow.Guid;
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
<ProjectReference Include="..\..\e-suite.Database.Core\e-suite.Database.Core\e-suite.Database.Core.csproj" />
|
||||
<ProjectReference Include="..\..\e-suite.DependencyInjection\e-suite.DependencyInjection.csproj" />
|
||||
<ProjectReference Include="..\..\e-suite.Utilities.Pagination\e-suite.Utilities.Pagination\e-suite.Utilities.Pagination.csproj" />
|
||||
<ProjectReference Include="..\..\e-suite.Workflow.Core\e-suite.Workflow.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@ -1,10 +1,25 @@
|
||||
using e_suite.Database.Audit;
|
||||
using e_suite.Database.Core;
|
||||
using e_suite.Database.Core.Tables.Activity;
|
||||
using eSuite.Core.Miscellaneous;
|
||||
|
||||
namespace e_suite.API.Common.repository;
|
||||
|
||||
public interface IActivityRepository : IRepository
|
||||
{
|
||||
Task CreateActivityInstanceAsync(AuditUserDetails auditUserDetails, Activity template, CancellationToken cancellationToken);
|
||||
Task CreateActivityInstanceAsync(
|
||||
AuditUserDetails auditUserDetails,
|
||||
Activity template,
|
||||
CancellationToken cancellationToken
|
||||
);
|
||||
|
||||
Task<Activity?> GetActivityInstanceAsync(GeneralIdRef activityId, CancellationToken cancellationToken);
|
||||
|
||||
Task UpdateActivityInstanceAsync(
|
||||
AuditUserDetails auditUserDetails,
|
||||
Activity activityInstance,
|
||||
CancellationToken cancellationToken
|
||||
);
|
||||
|
||||
Task AddActivityTasksAsync(AuditUserDetails auditUserDetails, IEnumerable<ActivityTask> activityTasks, CancellationToken cancellationToken);
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
namespace e_suite.API.Common.repository;
|
||||
|
||||
public interface IWorkflowConverter
|
||||
{
|
||||
Workflow.Core.WorkflowVersion DeserialiseFromDatabase(e_suite.Database.Core.Tables.Workflow.WorkflowVersion dbVersion);
|
||||
|
||||
Task<e_suite.Database.Core.Tables.Workflow.WorkflowVersion> SerialiseToDatabase(
|
||||
Workflow.Core.WorkflowVersion runtime,
|
||||
e_suite.Database.Core.Tables.Workflow.WorkflowVersion? dbObject = null,
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
}
|
||||
@ -6,9 +6,9 @@ namespace e_suite.API.Common.repository;
|
||||
|
||||
public interface IWorkflowTemplateRepository : IRepository
|
||||
{
|
||||
public IQueryable<Workflow> GetWorkflows();
|
||||
public IQueryable<Database.Core.Tables.Workflow.Workflow> GetWorkflows();
|
||||
IQueryable<WorkflowVersion> GetWorkflowVersions();
|
||||
Task EditWorkflowVersionAsync(AuditUserDetails auditUserDetails, WorkflowVersion workflowVersion, CancellationToken cancellationToken);
|
||||
Task AddWorkflow(AuditUserDetails auditUserDetails, Workflow workflow, CancellationToken cancellationToken);
|
||||
Task AddWorkflow(AuditUserDetails auditUserDetails, Database.Core.Tables.Workflow.Workflow workflow, CancellationToken cancellationToken);
|
||||
Task AddWorkflowVersion(AuditUserDetails auditUserDetails, WorkflowVersion workflowVersion, CancellationToken cancellationToken);
|
||||
}
|
||||
@ -1,4 +1,6 @@
|
||||
using e_suite.Messaging.Common.models;
|
||||
using e_suite.Database.Audit;
|
||||
using e_suite.Messaging.Common.models;
|
||||
using e_suite.Service.WorkflowProcessor;
|
||||
using eSuite.Core.Clock;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using RabbitMQ.Client.Events;
|
||||
@ -9,13 +11,21 @@ public class ActivityQueueHandler : QueueHandlerBase
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly IClock _clock;
|
||||
private readonly IWorkflowProcessor _workflowProgressor;
|
||||
|
||||
public ActivityQueueHandler(ILogger logger, IClock clock)
|
||||
public ActivityQueueHandler(ILogger logger, IClock clock, IWorkflowProcessor workflowProgressor)
|
||||
{
|
||||
_logger = logger;
|
||||
_clock = clock;
|
||||
_workflowProgressor = workflowProgressor;
|
||||
}
|
||||
|
||||
private readonly AuditUserDetails _auditUserDetails = new()
|
||||
{
|
||||
Comment = "ActivityQueueHandler",
|
||||
UserDisplayName = "Workflow processor"
|
||||
};
|
||||
|
||||
public override async Task OnReceived(string queueName, BasicDeliverEventArgs basicDeliverEventArgs)
|
||||
{
|
||||
var activityMessage = await TranslateMessage<ActivityMessage>(basicDeliverEventArgs);
|
||||
@ -24,7 +34,7 @@ public class ActivityQueueHandler : QueueHandlerBase
|
||||
{
|
||||
case ActivityMessageTypes.ProgressActivity:
|
||||
var progressActivityMessage = await TranslateMessage<ProgressActivityMessage>(basicDeliverEventArgs);
|
||||
_logger.LogInformation("{DateTime}: Progressing Activity {messageId}", _clock.GetNow, progressActivityMessage.ActivityId);
|
||||
await _workflowProgressor.ProgressActivity(_auditUserDetails, progressActivityMessage.ActivityId, CancellationToken.None);
|
||||
break;
|
||||
default:
|
||||
#pragma warning disable CA2208 // Instantiate argument exceptions correctly
|
||||
|
||||
@ -43,16 +43,20 @@
|
||||
<ProjectReference Include="..\..\e-suite.Modules.FormsManager\e-suite.Modules.FormsManager\e-suite.Modules.FormsManager.csproj" />
|
||||
<ProjectReference Include="..\..\e-suite.Modules.GlossariesManager\e-suite.Modules.GlossariesManager\e-suite.Modules.GlossariesManager.csproj" />
|
||||
<ProjectReference Include="..\..\e-suite.Modules.OrganisationManager\e-Suite.Modules.OrganisationsManager\e-suite.Modules.OrganisationsManager.csproj" />
|
||||
<ProjectReference Include="..\..\e-suite.Modules.RoleManager\e-suite.Modules.RoleManager\e-suite.Modules.RoleManager.csproj" />
|
||||
<ProjectReference Include="..\..\e-suite.Modules.RunningActivityManager\e-suite.Modules.RunningActivityManager.csproj" />
|
||||
<ProjectReference Include="..\..\e-suite.Modules.SequenceManager\e-Suite.Modules.SequenceManager\e-suite.Modules.SequenceManager.csproj" />
|
||||
<ProjectReference Include="..\..\e-suite.Modules.SiteManager\e-suite.Modules.SiteManager\e-suite.Modules.SiteManager.csproj" />
|
||||
<ProjectReference Include="..\..\e-suite.Modules.SpecificationManager\e-suite.Modules.SpecificationManager\e-suite.Modules.SpecificationManager.csproj" />
|
||||
<ProjectReference Include="..\..\e-suite.Modules.SSOManager\e-suite.Modules.SSOManager\e-suite.Modules.SSOManager.csproj" />
|
||||
<ProjectReference Include="..\..\e-suite.Modules.UserManager\e-suite.Modules.UserManager\e-suite.Modules.UserManager.csproj" />
|
||||
<ProjectReference Include="..\..\e-suite.Modules.WorkflowTemplatesManager\e-suite.Modules.WorkflowTemplatesManager.csproj" />
|
||||
<ProjectReference Include="..\..\e-suite.Service.CustomFieldValidation\e-suite.Service.CustomFieldValidation\e-suite.Service.CustomFieldValidation.csproj" />
|
||||
<ProjectReference Include="..\..\e-suite.Service.EFlowSync\e-suite.Service.EFlowSync\e-suite.Service.EFlowSync.csproj" />
|
||||
<ProjectReference Include="..\..\e-suite.Service.Performance\e-suite.Service.Performance\e-suite.Service.Performance.csproj" />
|
||||
<ProjectReference Include="..\..\e-suite.Service.Sentinel\e-suite.Service.Sentinel\e-suite.Service.Sentinel.csproj" />
|
||||
<ProjectReference Include="..\..\e-suite.Service.SigmaImporter\e-suite.Service.SigmaImporter\e-suite.Service.SigmaImporter.csproj" />
|
||||
<ProjectReference Include="..\..\e-suite.Service.WorkflowProcessor\e-suite.Service.WorkflowProcessor.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
using e_suite.API.Common.repository;
|
||||
using e_suite.Database.Audit;
|
||||
using e_suite.Database.Core;
|
||||
using e_suite.Database.Core.Extensions;
|
||||
using e_suite.Database.Core.Tables.Activity;
|
||||
using eSuite.Core.Miscellaneous;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace e_suite.Modules.RunningActivityManager.repository;
|
||||
|
||||
@ -20,4 +23,27 @@ public class ActivityRepository : RepositoryBase, IActivityRepository
|
||||
DatabaseDbContext.Activities.Add(activity);
|
||||
await DatabaseDbContext.SaveChangesAsync(auditUserDetails, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<Activity?> GetActivityInstanceAsync(GeneralIdRef activityId, CancellationToken cancellationToken)
|
||||
{
|
||||
return await DatabaseDbContext.Activities
|
||||
.Include( x=> x.WorkflowVersion)
|
||||
.Include( x => x.Tasks)
|
||||
.FindByGeneralIdRefAsync(activityId, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task UpdateActivityInstanceAsync(AuditUserDetails auditUserDetails, Activity activityInstance, CancellationToken cancellationToken)
|
||||
{
|
||||
await DatabaseDbContext.SaveChangesAsync(auditUserDetails, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task AddActivityTasksAsync(
|
||||
AuditUserDetails auditUserDetails,
|
||||
IEnumerable<ActivityTask> activityTasks,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
DatabaseDbContext.ActivityTasks.AddRange(activityTasks);
|
||||
await DatabaseDbContext.SaveChangesAsync(auditUserDetails, cancellationToken);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using eSuite.Core.Miscellaneous;
|
||||
|
||||
namespace e_suite.Modules.WorkflowTemplatesManager.Repository;
|
||||
|
||||
public class GeneralIdRefConverter<T> : JsonConverter<T>
|
||||
{
|
||||
private readonly Func<GeneralIdRef, T?> _lookup;
|
||||
|
||||
public GeneralIdRefConverter(Func<GeneralIdRef, T?> lookup)
|
||||
{
|
||||
_lookup = lookup;
|
||||
}
|
||||
public override bool CanConvert(Type typeToConvert)
|
||||
{
|
||||
// Only convert actual domain types, not enums or primitives
|
||||
return typeToConvert == typeof(T) &&
|
||||
!typeToConvert.IsEnum &&
|
||||
!typeToConvert.IsPrimitive &&
|
||||
typeToConvert != typeof(string);
|
||||
}
|
||||
|
||||
public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
// Parse the incoming JSON into a GeneralIdRef
|
||||
using var doc = JsonDocument.ParseValue(ref reader);
|
||||
var json = doc.RootElement.GetRawText();
|
||||
|
||||
var idRef = JsonSerializer.Deserialize<GeneralIdRef>(json, options);
|
||||
|
||||
if (idRef == null)
|
||||
return default;
|
||||
|
||||
return _lookup(idRef);
|
||||
}
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
|
||||
{
|
||||
throw new NotImplementedException("Writing not needed.");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,97 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using e_suite.API.Common.repository;
|
||||
using e_suite.Database.Core.Extensions;
|
||||
using e_suite.Database.Core.Tables.Domain;
|
||||
using e_suite.Database.Core.Tables.UserManager;
|
||||
using e_suite.Workflow.Core;
|
||||
using e_suite.Workflow.Core.Extensions;
|
||||
|
||||
namespace e_suite.Modules.WorkflowTemplatesManager.Repository;
|
||||
|
||||
public class WorkflowConverter : IWorkflowConverter
|
||||
{
|
||||
private readonly IDomainRepository _domainRepository;
|
||||
private readonly IRoleManagerRepository _roleManagerRepository;
|
||||
private readonly IUserManagerRepository _userManagerRepository;
|
||||
|
||||
private readonly JsonSerializerOptions _jsonSerializerOptions;
|
||||
|
||||
public WorkflowConverter(IDomainRepository domainRepository, IRoleManagerRepository roleManagerRepository, IUserManagerRepository userManagerRepository)
|
||||
{
|
||||
_domainRepository = domainRepository;
|
||||
_roleManagerRepository = roleManagerRepository;
|
||||
_userManagerRepository = userManagerRepository;
|
||||
|
||||
|
||||
_jsonSerializerOptions = new JsonSerializerOptions
|
||||
{
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
_jsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
|
||||
_jsonSerializerOptions.Converters.Add(new GeneralIdRefConverter<Role>(id => _roleManagerRepository.GetRoleById(id)));
|
||||
_jsonSerializerOptions.Converters.Add(new GeneralIdRefConverter<User>(id => _userManagerRepository.GetUserById(id)));
|
||||
}
|
||||
|
||||
public Workflow.Core.WorkflowVersion DeserialiseFromDatabase(e_suite.Database.Core.Tables.Workflow.WorkflowVersion dbVersion)
|
||||
{
|
||||
var runtime = new Workflow.Core.WorkflowVersion
|
||||
{
|
||||
Id = dbVersion.Id,
|
||||
Guid = dbVersion.Guid,
|
||||
Version = dbVersion.Version,
|
||||
ActivityNameTemplate = dbVersion.ActivityNameTemplate,
|
||||
Description = dbVersion.Description,
|
||||
Domain = dbVersion.Domain.ToGeneralIdRef()!,
|
||||
Template = new WorkflowTemplate
|
||||
{
|
||||
Name = "Need to fix",
|
||||
Id = 1,
|
||||
Guid = Guid.Empty
|
||||
} // however you load templates
|
||||
};
|
||||
|
||||
foreach (var def in dbVersion.Tasks)
|
||||
{
|
||||
var task = def.ToTask(_jsonSerializerOptions);
|
||||
runtime.Tasks.Add(task);
|
||||
}
|
||||
|
||||
return runtime;
|
||||
}
|
||||
|
||||
public async Task<e_suite.Database.Core.Tables.Workflow.WorkflowVersion> SerialiseToDatabase(Workflow.Core.WorkflowVersion runtime, e_suite.Database.Core.Tables.Workflow.WorkflowVersion? dbObject = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (runtime is null)
|
||||
throw new NullReferenceException();
|
||||
|
||||
var domain = await _domainRepository.GetDomainById(runtime.Domain, cancellationToken);
|
||||
if (domain is null)
|
||||
throw new Exception($"Domain with id {runtime.Domain} not found.");
|
||||
|
||||
var dbVersion = dbObject ?? new e_suite.Database.Core.Tables.Workflow.WorkflowVersion();
|
||||
|
||||
if (dbObject == null)
|
||||
{
|
||||
dbVersion.Id = runtime.Id;
|
||||
dbVersion.Guid = runtime.Guid;
|
||||
}
|
||||
else
|
||||
{
|
||||
//note cannot move a version from one workflow to another, that requires a new version.
|
||||
//todo make sure that the Workflow is populated here.
|
||||
//dbVersion.Workflow = runtime.Template.ToGeneralIdRef()
|
||||
}
|
||||
|
||||
dbVersion.Version = runtime.Version; //todo make sure that the version number get incremented somewhere logical.
|
||||
dbVersion.ActivityNameTemplate = runtime.ActivityNameTemplate;
|
||||
dbVersion.Description = runtime.Description;
|
||||
dbVersion.DomainId = domain.Id;
|
||||
dbVersion.Tasks = runtime.Tasks
|
||||
.Select(t => t.ToDefinition())
|
||||
.ToList();
|
||||
|
||||
return dbVersion;
|
||||
}
|
||||
}
|
||||
@ -1,156 +1,12 @@
|
||||
using e_suite.API.Common.repository;
|
||||
using e_suite.Database.Audit;
|
||||
using e_suite.Database.Core;
|
||||
using e_suite.Database.Core.Extensions;
|
||||
using e_suite.Database.Core.Tables.Contacts;
|
||||
using e_suite.Database.Core.Tables.Domain;
|
||||
using e_suite.Database.Core.Tables.UserManager;
|
||||
using e_suite.Workflow.Core;
|
||||
using e_suite.Workflow.Core.Extensions;
|
||||
using eSuite.Core.Miscellaneous;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace e_suite.Modules.WorkflowTemplatesManager.Repository;
|
||||
|
||||
|
||||
public class GeneralIdRefConverter<T> : JsonConverter<T>
|
||||
{
|
||||
private readonly Func<GeneralIdRef, T?> _lookup;
|
||||
|
||||
public GeneralIdRefConverter(Func<GeneralIdRef, T?> lookup)
|
||||
{
|
||||
_lookup = lookup;
|
||||
}
|
||||
public override bool CanConvert(Type typeToConvert)
|
||||
{
|
||||
// Only convert actual domain types, not enums or primitives
|
||||
return typeToConvert == typeof(T) &&
|
||||
!typeToConvert.IsEnum &&
|
||||
!typeToConvert.IsPrimitive &&
|
||||
typeToConvert != typeof(string);
|
||||
}
|
||||
|
||||
public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
// Parse the incoming JSON into a GeneralIdRef
|
||||
using var doc = JsonDocument.ParseValue(ref reader);
|
||||
var json = doc.RootElement.GetRawText();
|
||||
|
||||
var idRef = JsonSerializer.Deserialize<GeneralIdRef>(json, options);
|
||||
|
||||
if (idRef == null)
|
||||
return default;
|
||||
|
||||
return _lookup(idRef);
|
||||
}
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
|
||||
{
|
||||
throw new NotImplementedException("Writing not needed.");
|
||||
}
|
||||
}
|
||||
|
||||
public interface IWorkflowConverter
|
||||
{
|
||||
Workflow.Core.WorkflowVersion DeserialiseFromDatabase(e_suite.Database.Core.Tables.Workflow.WorkflowVersion dbVersion);
|
||||
|
||||
Task<e_suite.Database.Core.Tables.Workflow.WorkflowVersion> SerialiseToDatabase(
|
||||
Workflow.Core.WorkflowVersion runtime,
|
||||
e_suite.Database.Core.Tables.Workflow.WorkflowVersion? dbObject = null,
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
}
|
||||
public class WorkflowConverter : IWorkflowConverter
|
||||
{
|
||||
private readonly IDomainRepository _domainRepository;
|
||||
private readonly IRoleManagerRepository _roleManagerRepository;
|
||||
private readonly IUserManagerRepository _userManagerRepository;
|
||||
|
||||
private readonly JsonSerializerOptions _jsonSerializerOptions;
|
||||
|
||||
public WorkflowConverter(IDomainRepository domainRepository, IRoleManagerRepository roleManagerRepository, IUserManagerRepository userManagerRepository)
|
||||
{
|
||||
_domainRepository = domainRepository;
|
||||
_roleManagerRepository = roleManagerRepository;
|
||||
_userManagerRepository = userManagerRepository;
|
||||
|
||||
|
||||
_jsonSerializerOptions = new JsonSerializerOptions
|
||||
{
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
_jsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
|
||||
_jsonSerializerOptions.Converters.Add(new GeneralIdRefConverter<Role>(id => _roleManagerRepository.GetRoleById(id)));
|
||||
_jsonSerializerOptions.Converters.Add(new GeneralIdRefConverter<User>(id => _userManagerRepository.GetUserById(id)));
|
||||
}
|
||||
|
||||
public Workflow.Core.WorkflowVersion DeserialiseFromDatabase(e_suite.Database.Core.Tables.Workflow.WorkflowVersion dbVersion)
|
||||
{
|
||||
var runtime = new Workflow.Core.WorkflowVersion
|
||||
{
|
||||
Id = dbVersion.Id,
|
||||
Guid = dbVersion.Guid,
|
||||
Version = dbVersion.Version,
|
||||
ActivityNameTemplate = dbVersion.ActivityNameTemplate,
|
||||
Description = dbVersion.Description,
|
||||
Domain = dbVersion.Domain.ToGeneralIdRef()!,
|
||||
Template = new WorkflowTemplate
|
||||
{
|
||||
Name = "Need to fix",
|
||||
Id = 1,
|
||||
Guid = Guid.Empty
|
||||
} // however you load templates
|
||||
};
|
||||
|
||||
foreach (var def in dbVersion.Tasks)
|
||||
{
|
||||
var task = def.ToTask(_jsonSerializerOptions);
|
||||
runtime.Tasks.Add(task);
|
||||
}
|
||||
|
||||
return runtime;
|
||||
}
|
||||
|
||||
public async Task<e_suite.Database.Core.Tables.Workflow.WorkflowVersion> SerialiseToDatabase(Workflow.Core.WorkflowVersion runtime, e_suite.Database.Core.Tables.Workflow.WorkflowVersion? dbObject = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (runtime is null)
|
||||
throw new NullReferenceException();
|
||||
|
||||
var domain = await _domainRepository.GetDomainById(runtime.Domain, cancellationToken);
|
||||
if (domain is null)
|
||||
throw new Exception($"Domain with id {runtime.Domain} not found.");
|
||||
|
||||
var dbVersion = dbObject ?? new e_suite.Database.Core.Tables.Workflow.WorkflowVersion();
|
||||
|
||||
if (dbObject == null)
|
||||
{
|
||||
dbVersion.Id = runtime.Id;
|
||||
dbVersion.Guid = runtime.Guid;
|
||||
}
|
||||
else
|
||||
{
|
||||
//note cannot move a version from one workflow to another, that requires a new version.
|
||||
//todo make sure that the Workflow is populated here.
|
||||
//dbVersion.Workflow = runtime.Template.ToGeneralIdRef()
|
||||
}
|
||||
|
||||
dbVersion.Version = runtime.Version; //todo make sure that the version number get incremented somewhere logical.
|
||||
dbVersion.ActivityNameTemplate = runtime.ActivityNameTemplate;
|
||||
dbVersion.Description = runtime.Description;
|
||||
dbVersion.DomainId = domain.Id;
|
||||
dbVersion.Tasks = runtime.Tasks
|
||||
.Select(t => t.ToDefinition())
|
||||
.ToList();
|
||||
|
||||
return dbVersion;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class WorkflowTemplateRepository : RepositoryBase, IWorkflowTemplateRepository
|
||||
{
|
||||
public WorkflowTemplateRepository(IEsuiteDatabaseDbContext databaseDbContext) : base(databaseDbContext)
|
||||
|
||||
9
e-suite.Service.WorkflowProcessor/IWorkflowProcessor.cs
Normal file
9
e-suite.Service.WorkflowProcessor/IWorkflowProcessor.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using e_suite.Database.Audit;
|
||||
using eSuite.Core.Miscellaneous;
|
||||
|
||||
namespace e_suite.Service.WorkflowProcessor;
|
||||
|
||||
public interface IWorkflowProcessor
|
||||
{
|
||||
Task ProgressActivity(AuditUserDetails auditUserDetails, GeneralIdRef activityId, CancellationToken cancellationToken);
|
||||
}
|
||||
13
e-suite.Service.WorkflowProcessor/IocRegistration.cs
Normal file
13
e-suite.Service.WorkflowProcessor/IocRegistration.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using Autofac;
|
||||
using e_suite.DependencyInjection;
|
||||
|
||||
namespace e_suite.Service.WorkflowProcessor;
|
||||
|
||||
public class IocRegistration : IIocRegistration
|
||||
{
|
||||
public void RegisterTypes(ContainerBuilder builder)
|
||||
{
|
||||
builder.RegisterType<WorkflowProcessor>().As<IWorkflowProcessor>().InstancePerLifetimeScope();
|
||||
|
||||
}
|
||||
}
|
||||
107
e-suite.Service.WorkflowProcessor/WorkflowProcessor.cs
Normal file
107
e-suite.Service.WorkflowProcessor/WorkflowProcessor.cs
Normal file
@ -0,0 +1,107 @@
|
||||
using e_suite.API.Common.repository;
|
||||
using e_suite.Database.Audit;
|
||||
using e_suite.Database.Core.Tables.Activity;
|
||||
using e_suite.Workflow.Core;
|
||||
using e_suite.Workflow.Core.Interfaces;
|
||||
using eSuite.Core.Clock;
|
||||
using eSuite.Core.Enums;
|
||||
using eSuite.Core.Miscellaneous;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace e_suite.Service.WorkflowProcessor;
|
||||
|
||||
public class WorkflowProcessor : IWorkflowProcessor
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly IClock _clock;
|
||||
private readonly IWorkflowTemplateRepository _workflowTemplateRepository;
|
||||
private readonly IWorkflowConverter _workflowConverter;
|
||||
private readonly IActivityRepository _activityRepository;
|
||||
|
||||
public WorkflowProcessor(ILogger logger, IClock clock, IWorkflowTemplateRepository workflowTemplateRepository, IActivityRepository activityRepository, IWorkflowConverter workflowConverter)
|
||||
{
|
||||
_logger = logger;
|
||||
_clock = clock;
|
||||
_workflowTemplateRepository = workflowTemplateRepository;
|
||||
_activityRepository = activityRepository;
|
||||
_workflowConverter = workflowConverter;
|
||||
}
|
||||
|
||||
public async Task ProgressActivity(
|
||||
AuditUserDetails auditUserDetails,
|
||||
GeneralIdRef activityId,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
_logger.LogInformation("{DateTime}: Progressing Activity {messageId}", _clock.GetNow, activityId);
|
||||
|
||||
var activityInstance = await _activityRepository.GetActivityInstanceAsync(activityId, cancellationToken);
|
||||
if (activityInstance == null)
|
||||
{
|
||||
_logger.LogInformation("{DateTime}: Unable to find activity {messageId}", _clock.GetNow, activityId);
|
||||
throw new InvalidDataException("activityInstance not found");
|
||||
}
|
||||
|
||||
if (activityInstance.ActivityState == ActivityState.Cancelled)
|
||||
{
|
||||
_logger.LogInformation("{DateTime}: Activity {messageId} is cancelled, skipping", _clock.GetNow,
|
||||
activityId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (activityInstance.ActivityState == ActivityState.Completed)
|
||||
{
|
||||
_logger.LogInformation("{DateTime}: Activity {messageId} is already completed, skipping", _clock.GetNow,
|
||||
activityId);
|
||||
return;
|
||||
}
|
||||
|
||||
var workflowVersion = _workflowConverter.DeserialiseFromDatabase(activityInstance.WorkflowVersion);
|
||||
|
||||
await _activityRepository.TransactionAsync(async () =>
|
||||
{
|
||||
|
||||
ICollection<ActivityTask> tasks;
|
||||
if (activityInstance.ActivityState == ActivityState.Pending)
|
||||
{
|
||||
activityInstance.ActivityState = ActivityState.Active;
|
||||
await _activityRepository.UpdateActivityInstanceAsync(auditUserDetails, activityInstance,
|
||||
cancellationToken);
|
||||
|
||||
tasks = await PlanTaskExecution(auditUserDetails, activityInstance, workflowVersion, cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
tasks = activityInstance.Tasks;
|
||||
}
|
||||
|
||||
//Invoke startable tasks.
|
||||
});
|
||||
}
|
||||
|
||||
private async Task<ICollection<ActivityTask>> PlanTaskExecution(AuditUserDetails auditUserDetails, Activity activityInstance, WorkflowVersion workflowVersion, CancellationToken cancellationToken)
|
||||
{
|
||||
var activityOrdinalCounter = 1;
|
||||
|
||||
//Create task instances for the activity
|
||||
var activityTasks = new List<ActivityTask>();
|
||||
|
||||
foreach (var task in workflowVersion.Tasks)
|
||||
{
|
||||
var activityTask = new ActivityTask
|
||||
{
|
||||
Guid = Guid.NewGuid(),
|
||||
Activity = activityInstance,
|
||||
ActivityState = ActivityState.Pending,
|
||||
TaskGuid = task.Guid,
|
||||
ActivityOrdinal = activityOrdinalCounter++,
|
||||
TaskName = task.Name,
|
||||
};
|
||||
activityTasks.Add(activityTask);
|
||||
|
||||
}
|
||||
await _activityRepository.AddActivityTasksAsync(auditUserDetails, activityTasks, cancellationToken);
|
||||
|
||||
return activityTasks;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<RootNamespace>e_suite.Service.WorkflowProcessor</RootNamespace>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\e-suite.API.Common\e-suite.API.Common\e-suite.API.Common.csproj" />
|
||||
<ProjectReference Include="..\e-suite.DependencyInjection\e-suite.DependencyInjection.csproj" />
|
||||
<ProjectReference Include="..\e-suite.Workflow.Core\e-suite.Workflow.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@ -167,6 +167,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eSuite.Translator", "eSuite
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "e-suite.Modules.RunningActivityManager", "e-suite.Modules.RunningActivityManager\e-suite.Modules.RunningActivityManager.csproj", "{DE96B3AE-986A-43FE-9C30-14553D0CFCE7}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "e-suite.Service.WorkflowProcessor", "e-suite.Service.WorkflowProcessor\e-suite.Service.WorkflowProcessor.csproj", "{F32346BC-26BF-4BD5-9691-DD23BEA58E99}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -469,6 +471,10 @@ Global
|
||||
{DE96B3AE-986A-43FE-9C30-14553D0CFCE7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DE96B3AE-986A-43FE-9C30-14553D0CFCE7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DE96B3AE-986A-43FE-9C30-14553D0CFCE7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F32346BC-26BF-4BD5-9691-DD23BEA58E99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F32346BC-26BF-4BD5-9691-DD23BEA58E99}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F32346BC-26BF-4BD5-9691-DD23BEA58E99}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F32346BC-26BF-4BD5-9691-DD23BEA58E99}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@ -543,6 +549,7 @@ Global
|
||||
{8D343418-7E3A-40E5-A5CF-6497221F3F7E} = {27EA902C-3CD0-4A8F-BA75-8D1AF87902AC}
|
||||
{ABF3CD19-D1CF-4407-9102-3FC31DAC04AB} = {B0DE567F-EA4E-43FA-8A16-A0D571852024}
|
||||
{DE96B3AE-986A-43FE-9C30-14553D0CFCE7} = {B0DE567F-EA4E-43FA-8A16-A0D571852024}
|
||||
{F32346BC-26BF-4BD5-9691-DD23BEA58E99} = {726E46E8-E6E2-44D1-AB3B-85481330A84E}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {C5175258-F776-4FF9-A9EE-386312E47061}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user