private async Task <WorkflowTriggersContainer> GetWorkflowEventTriggersForNewArtifactEventInternal(int userId, IEnumerable <int> artifactIds, int revisionId, bool addDrafts) { var param = new DynamicParameters(); param.Add("@userId", userId); var artifactIdsTable = SqlConnectionWrapper.ToDataTable(artifactIds); param.Add("@artifactIds", artifactIdsTable); param.Add("@revisionId", revisionId); param.Add("@addDrafts", addDrafts); var newArtifactEvents = (await ConnectionWrapper.QueryAsync <SqlWorkflowNewArtifactEvent>("GetWorkflowEventTriggersForNewArtifact", param, commandType: CommandType.StoredProcedure)).ToList(); var eventTriggers = new WorkflowEventTriggers(); newArtifactEvents.Where(n => n != null).ForEach(n => { eventTriggers.AddRange(ToWorkflowTriggers(SerializationHelper.FromXml <XmlWorkflowEventTriggers>(n.Triggers), userId)); }); return(GetWorkflowTriggersContainer(eventTriggers)); }
private WorkflowEventTriggers ToWorkflowTriggers(XmlWorkflowEventTriggers xmlWorkflowEventTriggers, int currentUserId) { WorkflowEventTriggers triggers = new WorkflowEventTriggers(); if (xmlWorkflowEventTriggers == null || xmlWorkflowEventTriggers.Triggers == null) { return(triggers); } triggers.AddRange(xmlWorkflowEventTriggers.Triggers.Select(xmlWorkflowEventTrigger => new WorkflowEventTrigger { Name = xmlWorkflowEventTrigger.Name, Condition = new WorkflowEventCondition(), Action = GenerateAction(xmlWorkflowEventTrigger.Action, currentUserId) })); return(triggers); }
public async Task <ExecutionParameters> BuildTriggerExecutionParameters( int userId, VersionControlArtifactInfo artifactInfo, WorkflowEventTriggers triggers, IDbTransaction transaction = null) { if (triggers.IsEmpty()) { return(null); } var artifactId = artifactInfo.Id; var isArtifactReadOnlyReuse = await _stateChangeExecutorRepositories.ReuseRepository.DoItemsContainReadonlyReuse(new[] { artifactId }, transaction); ItemTypeReuseTemplate reuseTemplate = null; var artifactId2StandardTypeId = await _stateChangeExecutorRepositories.ReuseRepository.GetStandardTypeIdsForArtifactsIdsAsync(new HashSet <int> { artifactId }); var instanceItemTypeId = artifactId2StandardTypeId[artifactId].InstanceTypeId; if (instanceItemTypeId == null) { throw new BadRequestException("Artifact is not a standard artifact type"); } if (isArtifactReadOnlyReuse.ContainsKey(artifactId) && isArtifactReadOnlyReuse[artifactId]) { reuseTemplate = await LoadReuseSettings(instanceItemTypeId.Value); } var customItemTypeToPropertiesMap = await LoadCustomPropertyInformation(new[] { instanceItemTypeId.Value }, triggers, artifactInfo.ProjectId, userId, artifactId); var propertyTypes = new List <WorkflowPropertyType>(); if (customItemTypeToPropertiesMap.ContainsKey(artifactInfo.ItemTypeId)) { propertyTypes = customItemTypeToPropertiesMap[artifactInfo.ItemTypeId]; } var usersAndGroups = await LoadUsersAndGroups(triggers); return(new ExecutionParameters( userId, artifactInfo, reuseTemplate, propertyTypes, _stateChangeExecutorRepositories.SaveArtifactRepository, transaction, new ValidationContext(usersAndGroups.Item1, usersAndGroups.Item2))); }
private static WorkflowTriggersContainer GetWorkflowTriggersContainer(WorkflowEventTriggers eventTriggers) { var workflowTriggersContainer = new WorkflowTriggersContainer(); foreach (var workflowEventTrigger in eventTriggers.Where(t => t?.Action != null)) { if (workflowEventTrigger.Action is IWorkflowEventSynchronousAction) { workflowTriggersContainer.SynchronousTriggers.Add(workflowEventTrigger); } else if (workflowEventTrigger.Action is IWorkflowEventASynchronousAction) { workflowTriggersContainer.AsynchronousTriggers.Add(workflowEventTrigger); } } return(workflowTriggersContainer); }
private async Task <Dictionary <int, List <WorkflowPropertyType> > > LoadCustomPropertyInformation( IEnumerable <int> instanceItemTypeIds, WorkflowEventTriggers triggers, int projectId, int userId, int artifactId) { var propertyChangeActions = triggers.Select(t => t.Action).OfType <PropertyChangeAction>().ToList(); if (propertyChangeActions.Count == 0) { return(new Dictionary <int, List <WorkflowPropertyType> >()); } var instancePropertyTypeIds = propertyChangeActions.Select(b => b.InstancePropertyTypeId); return(await _stateChangeExecutorRepositories.WorkflowRepository.GetCustomItemTypeToPropertiesMap(userId, artifactId, projectId, instanceItemTypeIds, instancePropertyTypeIds)); }
public void TestInitialize() { _userId = 0; _revisionId = 0; _userName = ""; _transactionId = 123; _workflowEventTriggers = new WorkflowEventTriggers(); _baseArtifactVersionControlInfo = new WorkflowMessageArtifactInfo(); _projectName = ""; _modifiedProperties = new Dictionary <int, IList <Property> >(); _currentState = new WorkflowState(); _artifactUrl = ""; _baseUrl = ""; _ancestorArtifactTypeIds = new int[] { }; _mockUsersRepository = new Mock <IUsersRepository>(MockBehavior.Strict); _mockServiceLogRepository = new Mock <IServiceLogRepository>(MockBehavior.Strict); _mockWebhooksRepository = new Mock <IWebhooksRepository>(MockBehavior.Strict); _mockProjectMetaRepository = new Mock <IProjectMetaRepository>(MockBehavior.Strict); }
public async Task BuildTriggerExecutionParameters_WhenValid_ReturnsExecutionParameters() { // Arrange var artifactId = 1; var artifactStandardItemTypeId = 2; var artifactItemTypeId = 3; var artifactInfo = new VersionControlArtifactInfo() { Id = artifactId, ItemTypeId = artifactItemTypeId }; var triggers = new WorkflowEventTriggers(); triggers.Add(new WorkflowEventTrigger()); var sqlItemTypeInfo = new SqlItemTypeInfo() { InstanceTypeId = artifactStandardItemTypeId }; var isArtifactReadonlyReuseDictionary = new Dictionary <int, bool>() { { artifactId, false } }; var artifactStandardItemTypeDictionary = new Dictionary <int, SqlItemTypeInfo>() { { artifactId, sqlItemTypeInfo } }; _reuseRepository.Setup( r => r.DoItemsContainReadonlyReuse(It.IsAny <IEnumerable <int> >(), It.IsAny <IDbTransaction>())) .ReturnsAsync(isArtifactReadonlyReuseDictionary); _reuseRepository.Setup( r => r.GetStandardTypeIdsForArtifactsIdsAsync(It.IsAny <ISet <int> >())) .ReturnsAsync(artifactStandardItemTypeDictionary); var result = await _stateChangeExecutorHelper.BuildTriggerExecutionParameters(1, artifactInfo, triggers, null); // Assert Assert.IsNotNull(result); }
public static async Task <IList <IWorkflowMessage> > GenerateMessages(int userId, int revisionId, string userName, long transactionId, WorkflowEventTriggers postOpTriggers, IBaseArtifactVersionControlInfo artifactInfo, string projectName, IDictionary <int, IList <Property> > modifiedProperties, WorkflowState currentState, string artifactUrl, string baseUrl, IEnumerable <int> ancestorArtifactTypeIds, IUsersRepository usersRepository, IServiceLogRepository serviceLogRepository, IWebhooksRepository webhooksRepository, IProjectMetaRepository projectMetaRepository) { var resultMessages = new List <IWorkflowMessage>(); var baseHostUri = baseUrl ?? ServerUriHelper.GetBaseHostUri()?.ToString(); foreach (var workflowEventTrigger in postOpTriggers) { if (workflowEventTrigger?.Action == null) { continue; } switch (workflowEventTrigger.ActionType) { case MessageActionType.Notification: var notificationAction = workflowEventTrigger.Action as EmailNotificationAction; if (notificationAction == null) { continue; } var notificationMessage = await GetNotificationMessage(userId, revisionId, transactionId, artifactInfo, projectName, notificationAction, artifactUrl, baseHostUri, usersRepository); if (notificationMessage == null) { await serviceLogRepository.LogInformation(LogSource, $"Skipping Email notification action for artifact {artifactInfo.Id}"); Log.Debug($" Skipping Email notification action for artifact {artifactInfo.Id}. Message: Notification."); continue; } resultMessages.Add(notificationMessage); break; case MessageActionType.GenerateChildren: var generateChildrenAction = workflowEventTrigger.Action as GenerateChildrenAction; if (generateChildrenAction == null) { continue; } var ancestors = new List <int>(ancestorArtifactTypeIds ?? new int[0]); ancestors.Add(artifactInfo.ItemTypeId); var generateChildrenMessage = new GenerateDescendantsMessage { TransactionId = transactionId, ChildCount = generateChildrenAction.ChildCount.GetValueOrDefault(10), DesiredArtifactTypeId = generateChildrenAction.ArtifactTypeId, ArtifactId = artifactInfo.Id, AncestorArtifactTypeIds = ancestors, RevisionId = revisionId, UserId = userId, ProjectId = artifactInfo.ProjectId, UserName = userName, BaseHostUri = baseHostUri, ProjectName = projectName, TypePredefined = (int)artifactInfo.PredefinedType }; resultMessages.Add(generateChildrenMessage); break; case MessageActionType.GenerateTests: var generateTestsAction = workflowEventTrigger.Action as GenerateTestCasesAction; if (generateTestsAction == null || artifactInfo.PredefinedType != ItemTypePredefined.Process) { await serviceLogRepository.LogInformation(LogSource, $"Skipping GenerateTestCasesAction for artifact {artifactInfo.Id} as it is not a process"); Log.Debug($"Skipping GenerateTestCasesAction for artifact {artifactInfo.Id} as it is not a process. Message: Notification."); continue; } var generateTestsMessage = new GenerateTestsMessage { TransactionId = transactionId, ArtifactId = artifactInfo.Id, RevisionId = revisionId, UserId = userId, ProjectId = artifactInfo.ProjectId, UserName = userName, BaseHostUri = baseHostUri, ProjectName = projectName }; resultMessages.Add(generateTestsMessage); break; case MessageActionType.GenerateUserStories: var generateUserStories = workflowEventTrigger.Action as GenerateUserStoriesAction; if (generateUserStories == null || artifactInfo.PredefinedType != ItemTypePredefined.Process) { await serviceLogRepository.LogInformation(LogSource, $"Skipping GenerateUserStories for artifact {artifactInfo.Id} as it is not a process"); Log.Debug($"Skipping GenerateUserStories for artifact {artifactInfo.Id} as it is not a process. Message: Notification."); continue; } var generateUserStoriesMessage = new GenerateUserStoriesMessage { TransactionId = transactionId, ArtifactId = artifactInfo.Id, RevisionId = revisionId, UserId = userId, ProjectId = artifactInfo.ProjectId, UserName = userName, BaseHostUri = baseHostUri, ProjectName = projectName }; resultMessages.Add(generateUserStoriesMessage); break; case MessageActionType.Webhooks: var webhookAction = workflowEventTrigger.Action as WebhookAction; if (webhookAction == null) { continue; } var customTypes = await projectMetaRepository.GetCustomProjectTypesAsync(artifactInfo.ProjectId, userId); var artifactType = customTypes.ArtifactTypes.FirstOrDefault(at => at.Id == artifactInfo.ItemTypeId); var artifactPropertyInfos = await webhooksRepository.GetArtifactsWithPropertyValuesAsync( userId, new List <int> { artifactInfo.Id }, new List <int> { (int)PropertyTypePredefined.Name, (int)PropertyTypePredefined.Description, (int)PropertyTypePredefined.ID, (int)PropertyTypePredefined.CreatedBy, (int)PropertyTypePredefined.LastEditedOn, (int)PropertyTypePredefined.LastEditedBy, (int)PropertyTypePredefined.CreatedOn }, artifactType.CustomPropertyTypeIds); var webhookArtifactInfo = new WebhookArtifactInfo { Id = Guid.NewGuid().ToString(), EventType = WebhookEventType, PublisherId = WebhookPublisherId, Scope = new WebhookArtifactInfoScope { Type = WebhookType, WorkflowId = currentState.WorkflowId }, Resource = new WebhookResource { Name = artifactInfo.Name, ProjectId = artifactInfo.ProjectId, ParentId = ((WorkflowMessageArtifactInfo)artifactInfo).ParentId, ArtifactTypeId = artifactInfo.ItemTypeId, ArtifactTypeName = artifactType?.Name, BaseArtifactType = artifactType?.PredefinedType?.ToString(), ArtifactPropertyInfo = await ConvertToWebhookPropertyInfo(artifactPropertyInfos, customTypes.PropertyTypes, usersRepository), State = new WebhookStateInfo { Id = currentState.Id, Name = currentState.Name, WorkflowId = currentState.WorkflowId }, Revision = revisionId, Version = WebhookArtifactVersion, Id = artifactInfo.Id, BlueprintUrl = string.Format($"{baseHostUri}?ArtifactId={artifactInfo.Id}"), Link = string.Format($"{baseHostUri}api/v1/projects/{artifactInfo.ProjectId}/artifacts/{artifactInfo.Id}") } }; var webhookMessage = await GetWebhookMessage(userId, revisionId, transactionId, webhookAction, webhooksRepository, webhookArtifactInfo); if (webhookMessage == null) { await serviceLogRepository.LogInformation(LogSource, $"Skipping Webhook action for artifact {artifactInfo.Id}: {artifactInfo.Name}."); continue; } resultMessages.Add(webhookMessage); break; } } return(resultMessages); }
private async Task <Tuple <IEnumerable <SqlUser>, IEnumerable <SqlGroup> > > LoadUsersAndGroups(WorkflowEventTriggers triggers) { var userGroups = triggers.Select(a => a.Action).OfType <PropertyChangeUserGroupsAction>().SelectMany(b => b.UserGroups).ToList(); var userIds = userGroups.Where(u => !u.IsGroup.GetValueOrDefault(false) && u.Id.HasValue).Select(u => u.Id.Value).ToHashSet(); var groupIds = userGroups.Where(u => u.IsGroup.GetValueOrDefault(false) && u.Id.HasValue).Select(u => u.Id.Value).ToHashSet(); var users = new List <SqlUser>(); if (userIds.Any()) { users.AddRange(await _stateChangeExecutorRepositories.UsersRepository.GetExistingUsersByIdsAsync(userIds)); } var groups = new List <SqlGroup>(); if (groupIds.Any()) { groups.AddRange( await _stateChangeExecutorRepositories.UsersRepository.GetExistingGroupsByIds(groupIds, false)); } return(new Tuple <IEnumerable <SqlUser>, IEnumerable <SqlGroup> >(users, groups)); }