private static bool IsWorkflowPropertiesChanged(IeWorkflow workflow, IeWorkflow currentWorkflow) { // Ignore IsActive return(workflow.Id.GetValueOrDefault() != currentWorkflow.Id.GetValueOrDefault() || !string.Equals(workflow.Name, currentWorkflow.Name) || !string.Equals(workflow.Description, currentWorkflow.Description)); }
private static void CollectUsersAndGroupsToLookup(IeWorkflow workflow, out ISet <string> userNamesToLookup, out ISet <string> groupNamesToLookup, out ISet <int> userIdsToLookup, out ISet <int> groupIdsToLookup, bool ignoreIds) { var userNames = new HashSet <string>(); var groupNames = new HashSet <string>(); var userIds = new HashSet <int>(); var groupIds = new HashSet <int>(); workflow.TransitionEvents?.ForEach(t => { t?.PermissionGroups?.ForEach(g => { if (!ignoreIds && g.Id.HasValue) { groupIds.Add(g.Id.Value); } else { groupNames.Add(g.Name); } }); }); workflow.TransitionEvents?.ForEach(te => CollectUsersAndGroupsToLookup(te, userNames, groupNames, userIds, groupIds, ignoreIds)); workflow.PropertyChangeEvents?.ForEach(pce => CollectUsersAndGroupsToLookup(pce, userNames, groupNames, userIds, groupIds, ignoreIds)); workflow.NewArtifactEvents?.ForEach(nae => CollectUsersAndGroupsToLookup(nae, userNames, groupNames, userIds, groupIds, ignoreIds)); userNamesToLookup = userNames; groupNamesToLookup = groupNames; userIdsToLookup = ignoreIds ? null : userIds; groupIdsToLookup = ignoreIds ? null : groupIds; }
// During the update data validation names of elements with Id are assigned according to the meta data. public async Task <WorkflowDataValidationResult> ValidateUpdateDataAsync(IeWorkflow workflow, ProjectTypes standardTypes) { if (workflow == null) { throw new ArgumentNullException(nameof(workflow)); } var result = await InitializeDataValidationResultAsync(workflow, false, standardTypes); await ValidateWorkflowNameForUniquenessAsync(result, workflow, workflow.Id); await ValidateProjectsDataAsync(result, workflow.Projects, true); ValidateArtifactTypesDataAsync(result, workflow.Projects, false); await ValidateEventsDataAsync(result, workflow, false); return(result); }
// Remove empty collections and nullable boolean properties with the default value. public static IeWorkflow NormalizeWorkflow(IeWorkflow workflow) { if (workflow == null) { return(null); } workflow.States = NormalizeList(workflow.States); workflow.TransitionEvents = NormalizeList(workflow.TransitionEvents); workflow.PropertyChangeEvents = NormalizeList(workflow.PropertyChangeEvents); workflow.NewArtifactEvents = NormalizeList(workflow.NewArtifactEvents); workflow.Projects = NormalizeList(workflow.Projects); workflow.States?.ForEach(s => s.IsInitial = NormalizeNullableBool(s.IsInitial)); workflow.TransitionEvents?.ForEach(NormalizeTransitionEvent); workflow.PropertyChangeEvents?.ForEach(NormalizeEvent); workflow.NewArtifactEvents?.ForEach(NormalizeEvent); workflow.Projects?.ForEach(p => p.ArtifactTypes = NormalizeList(p.ArtifactTypes)); return(workflow); }
// Id in IeProjects and GroupProjectId for groups in IeUserGroup should be filled in. public WorkflowDiffResult DiffWorkflows(IeWorkflow workflow, IeWorkflow currentWorkflow) { var result = new WorkflowDiffResult(); if (workflow == null) { throw new ArgumentNullException(nameof(workflow)); } if (currentWorkflow == null) { throw new ArgumentNullException(nameof(currentWorkflow)); } result.IsWorkflowPropertiesChanged = IsWorkflowPropertiesChanged(workflow, currentWorkflow); DiffWorkflowEntities(workflow.States, currentWorkflow.States, result.AddedStates, result.DeletedStates, result.ChangedStates, result.NotFoundStates, result.UnchangedStates); var events = workflow.TransitionEvents?.Select(e => e as IeEvent).ToList(); var currentEvents = currentWorkflow.TransitionEvents?.Select(e => e as IeEvent).ToList(); DiffWorkflowEntities(events, currentEvents, result.AddedEvents, result.DeletedEvents, result.ChangedEvents, result.NotFoundEvents, result.UnchangedEvents); events = workflow.PropertyChangeEvents?.Select(te => te as IeEvent).ToList(); currentEvents = currentWorkflow.PropertyChangeEvents?.Select(te => te as IeEvent).ToList(); DiffWorkflowEntities(events, currentEvents, result.AddedEvents, result.DeletedEvents, result.ChangedEvents, result.NotFoundEvents, result.UnchangedEvents); events = workflow.NewArtifactEvents?.Select(te => te as IeEvent).ToList(); currentEvents = currentWorkflow.NewArtifactEvents?.Select(te => te as IeEvent).ToList(); DiffWorkflowEntities(events, currentEvents, result.AddedEvents, result.DeletedEvents, result.ChangedEvents, result.NotFoundEvents, result.UnchangedEvents); DiffProjectArtifactTypes(workflow.Projects, currentWorkflow.Projects, result); return(result); }
private async Task <WorkflowDataValidationResult> InitializeDataValidationResultAsync(IeWorkflow workflow, bool ignoreIds, ProjectTypes standardTypes = null) { var result = new WorkflowDataValidationResult(); result.StandardTypes = standardTypes ?? await _projectMetaRepository.GetStandardProjectTypesAsync(); result.StandardTypes.ArtifactTypes?.RemoveAll(at => at.PredefinedType != null && !at.PredefinedType.Value.IsRegularArtifactType()); result.StandardArtifactTypeMapByName.AddRange(result.StandardTypes.ArtifactTypes.ToDictionary(pt => pt.Name)); result.StandardPropertyTypeMapByName.AddRange(result.StandardTypes.PropertyTypes.ToDictionary(pt => pt.Name)); ISet <string> groupNamesToLookup; ISet <string> userNamesToLookup; ISet <int> groupIdsToLookup; ISet <int> userIdsToLookup; CollectUsersAndGroupsToLookup(workflow, out userNamesToLookup, out groupNamesToLookup, out userIdsToLookup, out groupIdsToLookup, ignoreIds); result.Users.AddRange(await _userRepository.GetExistingUsersByNamesAsync(userNamesToLookup)); result.Groups.AddRange(await _userRepository.GetExistingGroupsByNamesAsync(groupNamesToLookup, false)); if (!ignoreIds) { result.StandardArtifactTypeMapById.AddRange(result.StandardTypes.ArtifactTypes.ToDictionary(pt => pt.Id)); result.StandardPropertyTypeMapById.AddRange(result.StandardTypes.PropertyTypes.ToDictionary(pt => pt.Id)); result.Users.AddRange(await _userRepository.GetExistingUsersByIdsAsync(userIdsToLookup)); result.Groups.AddRange(await _userRepository.GetExistingGroupsByIds(groupIdsToLookup, false)); } return(result); }
private async Task FillInGroupProjectIdsAsync(WorkflowDataValidationResult result, IeWorkflow workflow) { var groupsWithoutProjectId = new List <IeUserGroup>(); workflow.TransitionEvents?.ForEach(t => CollectGroupsWithUnassignedProjectId(t, groupsWithoutProjectId)); workflow.PropertyChangeEvents?.ForEach( pce => CollectGroupsWithUnassignedProjectId(pce, groupsWithoutProjectId)); workflow.NewArtifactEvents?.ForEach(nae => CollectGroupsWithUnassignedProjectId(nae, groupsWithoutProjectId)); if (!groupsWithoutProjectId.Any()) { return; } var projectMap = (await _workflowRepository.GetProjectIdsByProjectPathsAsync(groupsWithoutProjectId.Select(g => g.GroupProjectPath))) .ToDictionary(p => p.ProjectPath, p => p.ProjectId); groupsWithoutProjectId.ForEach(g => { int projectId; if (projectMap.TryGetValue(g.GroupProjectPath, out projectId)) { g.GroupProjectId = projectId; } else { result.Errors.Add(new WorkflowDataValidationError { Element = g.GroupProjectPath, ErrorCode = WorkflowDataValidationErrorCodes.ProjectByPathNotFound }); } }); }
private async Task ValidateEventsDataAsync(WorkflowDataValidationResult result, IeWorkflow workflow, bool ignoreIds) { // For the workflow update Ids are already filled in. if (ignoreIds) { await FillInGroupProjectIdsAsync(result, workflow); } workflow.TransitionEvents?.ForEach(t => ValidateTransitionData(result, t, ignoreIds)); workflow.PropertyChangeEvents?.ForEach(pce => ValidatePropertyChangeEventData(result, pce, ignoreIds)); workflow.NewArtifactEvents?.ForEach(nae => ValidateNewArtifactEventData(result, nae, ignoreIds)); }
private async Task ValidateWorkflowNameForUniquenessAsync(WorkflowDataValidationResult result, IeWorkflow workflow, int?exceptWorkflowId = null) { var duplicateNames = await _workflowRepository.CheckLiveWorkflowsForNameUniquenessAsync(new[] { workflow.Name }, exceptWorkflowId); if (duplicateNames.Any()) { result.Errors.Add(new WorkflowDataValidationError { Element = workflow, ErrorCode = WorkflowDataValidationErrorCodes.WorkflowNameNotUnique }); } }
public void DiffWorkflows_SameArtifactTypeDeletedAndAdded_SuccessfulDeletion() { // Arrange var currentWorkflow = new IeWorkflow { Projects = new List <IeProject> { new IeProject { Id = 1, ArtifactTypes = new List <IeArtifactType> { new IeArtifactType { Id = 11 }, // deleted new IeArtifactType { Id = 12 } // unchanged } } } }; var updatedWorkflow = new IeWorkflow { Projects = new List <IeProject> { new IeProject { Id = 1, ArtifactTypes = new List <IeArtifactType> { new IeArtifactType { Id = 12 } // unchanged } }, new IeProject { Id = 2, ArtifactTypes = new List <IeArtifactType> { new IeArtifactType { Id = -11 }, // added new IeArtifactType { Id = -13 } // added } } } }; var wDiff = new WorkflowDiff(); // Act var diff = wDiff.DiffWorkflows(updatedWorkflow, currentWorkflow); // Assert Assert.AreEqual(diff.UnchangedProjectArtifactTypes.Count, 1); Assert.AreEqual(diff.UnchangedProjectArtifactTypes[0].Key, currentWorkflow.Projects[0].Id.Value); // 1 Assert.AreEqual(diff.UnchangedProjectArtifactTypes[0].Value.Id, currentWorkflow.Projects[0].ArtifactTypes[1].Id); // 12 Assert.AreEqual(diff.AddedProjectArtifactTypes.Count, 2); Assert.AreEqual(diff.AddedProjectArtifactTypes[0].Key, updatedWorkflow.Projects[1].Id.Value); // 2 Assert.AreEqual(diff.AddedProjectArtifactTypes[0].Value.Id, updatedWorkflow.Projects[1].ArtifactTypes[0].Id); // 11 Assert.AreEqual(diff.AddedProjectArtifactTypes[1].Key, updatedWorkflow.Projects[1].Id.Value); // 2 Assert.AreEqual(diff.AddedProjectArtifactTypes[1].Value.Id, updatedWorkflow.Projects[1].ArtifactTypes[1].Id); // 13 Assert.AreEqual(diff.DeletedProjectArtifactTypes.Count, 1); Assert.AreEqual(diff.DeletedProjectArtifactTypes[0].Key, currentWorkflow.Projects[0].Id.Value); // 1 Assert.AreEqual(diff.DeletedProjectArtifactTypes[0].Value.Id, currentWorkflow.Projects[0].ArtifactTypes[0].Id); // 11 }
public static IeWorkflow MapDWorkflowToIeWorkflow(DWorkflow sourceWorkflow) { var destinationWorkflow = new IeWorkflow { Id = sourceWorkflow.Id, Name = sourceWorkflow.Name, Description = sourceWorkflow.Description, IsActive = sourceWorkflow.IsActive, HasProcessArtifactType = sourceWorkflow.HasProcessArtifactType, NewArtifactEvents = sourceWorkflow.NewArtifactEvents?.Select(dNewArtifactEvent => new IeNewArtifactEvent { Id = dNewArtifactEvent.Id, Name = dNewArtifactEvent.Name, Triggers = MapToIeTriggers(dNewArtifactEvent.Triggers) }) .ToList() ?? new List <IeNewArtifactEvent>(), Projects = sourceWorkflow.Projects?.Select(dProject => new IeProject { Id = dProject.Id, Path = dProject.Path, ArtifactTypes = dProject.ArtifactTypes ?.Select( dArtifactType => new IeArtifactType { Id = dArtifactType.Id, Name = dArtifactType.Name }) .ToList() ?? new List <IeArtifactType>() }) .ToList() ?? new List <IeProject>(), PropertyChangeEvents = sourceWorkflow.PropertyChangeEvents?.Select(dPropertyChangeEvent => new IePropertyChangeEvent { Id = dPropertyChangeEvent.Id, Name = dPropertyChangeEvent.Name, PropertyId = dPropertyChangeEvent.PropertyId, PropertyName = dPropertyChangeEvent.PropertyName, Triggers = MapToIeTriggers(dPropertyChangeEvent.Triggers) }) .ToList() ?? new List <IePropertyChangeEvent>(), States = sourceWorkflow.States?.Select(dState => new IeState { Id = dState.Id, Name = dState.Name, IsInitial = dState.IsInitial, Location = dState.Location }) .ToList() ?? new List <IeState>(), TransitionEvents = sourceWorkflow.TransitionEvents?.Select(dTransitionEvent => new IeTransitionEvent { Id = dTransitionEvent.Id, Name = dTransitionEvent.Name, FromState = dTransitionEvent.FromState, FromStateId = dTransitionEvent.FromStateId, ToState = dTransitionEvent.ToState, ToStateId = dTransitionEvent.ToStateId, SkipPermissionGroups = dTransitionEvent.SkipPermissionGroups, PortPair = dTransitionEvent.PortPair != null ? new IePortPair { FromPort = Enum.IsDefined(typeof(DiagramPort), dTransitionEvent.PortPair.FromPort) ? dTransitionEvent.PortPair.FromPort : DiagramPort.None, ToPort = Enum.IsDefined(typeof(DiagramPort), dTransitionEvent.PortPair.ToPort) ? dTransitionEvent.PortPair.ToPort : DiagramPort.None } : null, Triggers = MapToIeTriggers(dTransitionEvent.Triggers), PermissionGroups = dTransitionEvent.PermissionGroups?.Select(dGroup => new IeGroup { Id = dGroup.Id, Name = dGroup.Name }) .ToList() ?? new List <IeGroup>() }) .ToList() ?? new List <IeTransitionEvent>() }; return(destinationWorkflow); }
public static DWorkflow MapIeWorkflowToDWorkflow(IeWorkflow sourceWorkflow) { var destinationWorkflow = new DWorkflow(); destinationWorkflow.Id = sourceWorkflow.Id; destinationWorkflow.Name = sourceWorkflow.Name; destinationWorkflow.Description = sourceWorkflow.Description; destinationWorkflow.IsActive = sourceWorkflow.IsActive; destinationWorkflow.HasProcessArtifactType = sourceWorkflow.HasProcessArtifactType; destinationWorkflow.NewArtifactEvents = sourceWorkflow.NewArtifactEvents?.Select(ieNewArtifactEvent => new DNewArtifactEvent { Id = ieNewArtifactEvent.Id, Name = ieNewArtifactEvent.Name, Triggers = MapToDTriggers(ieNewArtifactEvent.Triggers) }).ToList(); destinationWorkflow.Projects = sourceWorkflow.Projects?.Select(ieProject => new DProject { Id = ieProject.Id, ArtifactTypes = ieProject.ArtifactTypes?.Select(ieArtifactType => new DArtifactType { Id = ieArtifactType.Id, Name = ieArtifactType.Name }) }).ToList(); destinationWorkflow.PropertyChangeEvents = sourceWorkflow.PropertyChangeEvents?.Select( iePropertyChangeEvent => new DPropertyChangeEvent { Id = iePropertyChangeEvent.Id, Name = iePropertyChangeEvent.Name, PropertyId = iePropertyChangeEvent.PropertyId, PropertyName = iePropertyChangeEvent.PropertyName, Triggers = MapToDTriggers(iePropertyChangeEvent.Triggers.ToList()) }).ToList(); destinationWorkflow.States = sourceWorkflow.States?.Select(ieState => new DState { Id = ieState.Id, Name = ieState.Name, IsInitial = ieState.IsInitial, Location = ieState.Location }) .ToList(); destinationWorkflow.TransitionEvents = sourceWorkflow.TransitionEvents?.Select(ieTransitionEvent => new DTransitionEvent { Id = ieTransitionEvent.Id, Name = ieTransitionEvent.Name, FromState = ieTransitionEvent.FromState, FromStateId = ieTransitionEvent.FromStateId, ToState = ieTransitionEvent.ToState, ToStateId = ieTransitionEvent.ToStateId, SkipPermissionGroups = ieTransitionEvent.SkipPermissionGroups, PortPair = ieTransitionEvent.PortPair != null ? new DPortPair { FromPort = ieTransitionEvent.PortPair.FromPort, ToPort = ieTransitionEvent.PortPair.ToPort } : null, Triggers = MapToDTriggers(ieTransitionEvent.Triggers), PermissionGroups = ieTransitionEvent.PermissionGroups?.Select(ieGroup => new DGroup { Id = ieGroup.Id, Name = ieGroup.Name }) .ToList() }).ToList(); return(destinationWorkflow); }