using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using WorkflowCore.Models; namespace VberZero.Workflow.Persistence { internal static class ExtensionMethods { private static readonly JsonSerializerSettings SerializerSettings = new() { TypeNameHandling = TypeNameHandling.All }; internal static WorkflowInfo ToPersistEntity(this WorkflowInstance instance, WorkflowInfo entity = null) { entity ??= new WorkflowInfo(); entity.Id = instance.Id; entity.Data = JsonConvert.SerializeObject(instance.Data, SerializerSettings); entity.Description = instance.Description; entity.Reference = instance.Reference; entity.NextExecution = instance.NextExecution; entity.Version = instance.Version; entity.WorkflowDefinitionId = instance.WorkflowDefinitionId; entity.Status = instance.Status; entity.CreateTime = instance.CreateTime; entity.CompleteTime = instance.CompleteTime; foreach (var ep in instance.ExecutionPointers) { var persistedEP = entity.ExecutionPointers.FindById(ep.Id); if (persistedEP == null) { persistedEP = new WorkflowExecutionPointerInfo { Id = ep.Id.Replace("-", "") }; entity.ExecutionPointers.Add(persistedEP); } persistedEP.StepId = ep.StepId; persistedEP.Active = ep.Active; persistedEP.SleepUntil = ep.SleepUntil; persistedEP.PersistenceData = JsonConvert.SerializeObject(ep.PersistenceData, SerializerSettings); persistedEP.StartTime = ep.StartTime; persistedEP.EndTime = ep.EndTime; persistedEP.StepName = ep.StepName; persistedEP.RetryCount = ep.RetryCount; persistedEP.PredecessorId = ep.PredecessorId; persistedEP.ContextItem = JsonConvert.SerializeObject(ep.ContextItem, SerializerSettings); persistedEP.Children = string.Empty; foreach (var child in ep.Children) persistedEP.Children += child + ";"; persistedEP.EventName = ep.EventName; persistedEP.EventKey = ep.EventKey?.Replace("-", ""); persistedEP.EventPublished = ep.EventPublished; persistedEP.EventData = JsonConvert.SerializeObject(ep.EventData, SerializerSettings); persistedEP.Outcome = JsonConvert.SerializeObject(ep.Outcome, SerializerSettings); persistedEP.Status = ep.Status; persistedEP.Scope = string.Empty; foreach (var item in ep.Scope) persistedEP.Scope += item + ";"; foreach (var attr in ep.ExtensionAttributes) { var persistedAttr = persistedEP.ExtensionAttributes.FirstOrDefault(x => x.AttributeKey == attr.Key); if (persistedAttr == null) { persistedAttr = new WorkflowExtensionAttributeInfo(); persistedEP.ExtensionAttributes.Add(persistedAttr); } persistedAttr.AttributeKey = attr.Key.Replace("-", ""); persistedAttr.AttributeValue = JsonConvert.SerializeObject(attr.Value, SerializerSettings); } } return entity; } internal static WorkflowExecutionErrorInfo ToPersistEntity(this ExecutionError instance) { var entity = new WorkflowExecutionErrorInfo { Id = $"{DateTime.Now:yyyyMMddHHmmssfff}", ErrorTime = instance.ErrorTime, Message = instance.Message, ExecutionPointerId = instance.ExecutionPointerId, WorkflowId = instance.WorkflowId }; return entity; } internal static WorkflowSubscriptionInfo ToPersistEntity(this EventSubscription instance) { WorkflowSubscriptionInfo entity = new WorkflowSubscriptionInfo { Id = instance.Id?.Replace("-", "") ?? Guid.NewGuid().ToString("N"), EventKey = instance.EventKey?.Replace("-", ""), EventName = instance.EventName, StepId = instance.StepId, ExecutionPointerId = instance.ExecutionPointerId, WorkflowId = instance.WorkflowId, SubscribeAsOf = DateTime.SpecifyKind(instance.SubscribeAsOf, DateTimeKind.Utc), SubscriptionData = JsonConvert.SerializeObject(instance.SubscriptionData, SerializerSettings), ExternalToken = instance.ExternalToken, ExternalTokenExpiry = instance.ExternalTokenExpiry, ExternalWorkerId = instance.ExternalWorkerId }; return entity; } internal static WorkflowEventInfo ToPersistEntity(this Event instance) { WorkflowEventInfo entity = new WorkflowEventInfo { Id = instance.Id.Replace("-", ""), EventKey = instance.EventKey.Replace("-", ""), EventName = instance.EventName, EventTime = DateTime.SpecifyKind(instance.EventTime, DateTimeKind.Utc), IsProcessed = instance.IsProcessed, EventData = JsonConvert.SerializeObject(instance.EventData, SerializerSettings) }; return entity; } internal static WorkflowInstance ToWorkflowInstance(this WorkflowInfo entity) { WorkflowInstance instance = new WorkflowInstance { Data = JsonConvert.DeserializeObject(entity.Data, SerializerSettings), Description = entity.Description, Reference = entity.Reference, Id = entity.Id, NextExecution = entity.NextExecution, Version = entity.Version, WorkflowDefinitionId = entity.WorkflowDefinitionId, Status = entity.Status, CreateTime = DateTime.SpecifyKind(entity.CreateTime, DateTimeKind.Utc) }; if (entity.CompleteTime.HasValue) instance.CompleteTime = DateTime.SpecifyKind(entity.CompleteTime.Value, DateTimeKind.Utc); instance.ExecutionPointers = new WorkflowCore.Models.ExecutionPointerCollection(entity.ExecutionPointers.Count + 8); foreach (var ep in entity.ExecutionPointers) { var pointer = new ExecutionPointer { Id = ep.Id, StepId = ep.StepId, Active = ep.Active }; if (ep.SleepUntil.HasValue) pointer.SleepUntil = DateTime.SpecifyKind(ep.SleepUntil.Value, DateTimeKind.Utc); pointer.PersistenceData = JsonConvert.DeserializeObject(ep.PersistenceData ?? string.Empty, SerializerSettings); if (ep.StartTime.HasValue) pointer.StartTime = DateTime.SpecifyKind(ep.StartTime.Value, DateTimeKind.Utc); if (ep.EndTime.HasValue) pointer.EndTime = DateTime.SpecifyKind(ep.EndTime.Value, DateTimeKind.Utc); pointer.StepName = ep.StepName; pointer.RetryCount = ep.RetryCount; pointer.PredecessorId = ep.PredecessorId; pointer.ContextItem = JsonConvert.DeserializeObject(ep.ContextItem ?? string.Empty, SerializerSettings); if (!string.IsNullOrEmpty(ep.Children)) pointer.Children = ep.Children.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries).ToList(); pointer.EventName = ep.EventName; pointer.EventKey = ep.EventKey; pointer.EventPublished = ep.EventPublished; pointer.EventData = JsonConvert.DeserializeObject(ep.EventData ?? string.Empty, SerializerSettings); pointer.Outcome = JsonConvert.DeserializeObject(ep.Outcome ?? string.Empty, SerializerSettings); pointer.Status = ep.Status; if (!string.IsNullOrEmpty(ep.Scope)) pointer.Scope = new List(ep.Scope.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)); foreach (var attr in ep.ExtensionAttributes) { pointer.ExtensionAttributes[attr.AttributeKey] = JsonConvert.DeserializeObject(attr.AttributeValue, SerializerSettings); } instance.ExecutionPointers.Add(pointer); } return instance; } internal static EventSubscription ToEventSubscription(this WorkflowSubscriptionInfo entity) { EventSubscription instance = new EventSubscription { Id = entity.Id, EventKey = entity.EventKey, EventName = entity.EventName, StepId = entity.StepId, ExecutionPointerId = entity.ExecutionPointerId, WorkflowId = entity.WorkflowId, SubscribeAsOf = DateTime.SpecifyKind(entity.SubscribeAsOf, DateTimeKind.Utc), SubscriptionData = JsonConvert.DeserializeObject(entity.SubscriptionData, SerializerSettings), ExternalToken = entity.ExternalToken, ExternalTokenExpiry = entity.ExternalTokenExpiry, ExternalWorkerId = entity.ExternalWorkerId }; return instance; } internal static Event ToEvent(this WorkflowEventInfo entity) { Event instance = new Event { Id = entity.Id, EventKey = entity.EventKey, EventName = entity.EventName, EventTime = DateTime.SpecifyKind(entity.EventTime, DateTimeKind.Utc), IsProcessed = entity.IsProcessed, EventData = JsonConvert.DeserializeObject(entity.EventData, SerializerSettings) }; return instance; } } }