示例#1
0
        public void ArtifactsPublishedMessageHandler_RethrowsException()
        {
            // arrange
            _actionHelperMock.Setup(m => m.HandleAction(It.IsAny <TenantInformation>(), It.IsAny <ActionMessage>(), It.IsAny <BaseRepository>())).Throws(new TestException());
            var handler = new ArtifactsPublishedMessageHandler(_actionHelperMock.Object, _tenantInfoRetrieverMock.Object, _configHelperMock.Object, _transactionValidatorMock.Object);
            var message = new ArtifactsPublishedMessage();

            // act
            TestHandlerAndMessageWithHeader(handler, message);
            // assert
            _actionHelperMock.Verify(m => m.HandleAction(It.IsAny <TenantInformation>(), It.IsAny <ActionMessage>(), It.IsAny <BaseRepository>()), Times.Once);
        }
示例#2
0
        public void ArtifactsPublishedMessageHandler_HandlesMessageSuccessfully()
        {
            // arrange
            _actionHelperMock.Setup(m => m.HandleAction(It.IsAny <TenantInformation>(), It.IsAny <ActionMessage>(), It.IsAny <BaseRepository>())).Returns(Task.FromResult(true));
            var handler = new ArtifactsPublishedMessageHandler(_actionHelperMock.Object, _tenantInfoRetrieverMock.Object, _configHelperMock.Object, _transactionValidatorMock.Object);
            var message = new ArtifactsPublishedMessage();

            // act
            TestHandlerAndMessageWithHeader(handler, message);
            // assert
            Assert.IsNotNull(handler);
            _actionHelperMock.Verify(m => m.HandleAction(It.IsAny <TenantInformation>(), It.IsAny <ActionMessage>(), It.IsAny <BaseRepository>()), Times.Once);
        }
示例#3
0
        public async Task ArtifactsPublishedActionHelper_ReturnsFalse_WhenNoPublishedArtifactsAreFound()
        {
            // empty array of artifacts
            var message = new ArtifactsPublishedMessage {
                Artifacts = new PublishedArtifactInformation[] { }
            };

            _repositoryMock.Setup(m => m.GetWorkflowPropertyTransitionsForArtifactsAsync(It.IsAny <int>(), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <IEnumerable <int> >())).ReturnsAsync(_triggers);

            var actionHelper = new ArtifactsPublishedActionHelper();

            var result = await actionHelper.HandleAction(_tenantInformation, message, _repositoryMock.Object);

            Assert.IsFalse(result, "Message should not be processed successfully");
        }
示例#4
0
        public async Task ArtifactsPublishedActionHelper_ReturnsFalse_WhenNoWorkflowStatesAreFound()
        {
            var message = new ArtifactsPublishedMessage {
                Artifacts = new[] { new PublishedArtifactInformation() }
            };

            _repositoryMock.Setup(m => m.GetWorkflowPropertyTransitionsForArtifactsAsync(It.IsAny <int>(), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <IEnumerable <int> >())).ReturnsAsync(_triggers);
            // empty list of states
            var emptyStatesList = new List <SqlWorkFlowStateInformation>();

            _repositoryMock.Setup(m => m.GetWorkflowStatesForArtifactsAsync(It.IsAny <int>(), It.IsAny <IEnumerable <int> >(), It.IsAny <int>(), It.IsAny <bool>())).ReturnsAsync(emptyStatesList);

            var actionHelper = new ArtifactsPublishedActionHelper();

            var result = await actionHelper.HandleAction(_tenantInformation, message, _repositoryMock.Object);

            Assert.IsFalse(result, "Message should not be processed successfully");
        }
示例#5
0
        public async Task ProcessCreatedArtifacts_NoCreatedArtifacts_ReturnsFalse()
        {
            var message = new ArtifactsPublishedMessage
            {
                RevisionId = _revisionId,
                UserId     = _userId,
                UserName   = "******",
                Artifacts  = new List <PublishedArtifactInformation>()
            };
            // Act
            var result = await CreatedArtifactsNotificationHandler.ProcessCreatedArtifacts(_tenant,
                                                                                           message,
                                                                                           _artifactsPublishedRepositoryMock.Object,
                                                                                           _serviceLogRepositoryMock.Object,
                                                                                           _wfMessagingMock.Object);

            // Assert
            Assert.IsFalse(result, "Message should not be processed successfully");
        }
示例#6
0
        public async Task ArtifactsPublishedActionHelper_ReturnsFalse_WhenThereIsATriggerWithoutModifiedProperties()
        {
            // no modified properties
            var message = new ArtifactsPublishedMessage {
                Artifacts = new[] { new PublishedArtifactInformation() }
            };

            _repositoryMock.Setup(m => m.GetWorkflowPropertyTransitionsForArtifactsAsync(It.IsAny <int>(), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <IEnumerable <int> >())).ReturnsAsync(_triggers);
            _repositoryMock.Setup(m => m.GetWorkflowStatesForArtifactsAsync(It.IsAny <int>(), It.IsAny <IEnumerable <int> >(), It.IsAny <int>(), It.IsAny <bool>())).ReturnsAsync(_states);
            _repositoryMock.Setup(m => m.GetProjectNameByIdsAsync(It.IsAny <IEnumerable <int> >())).ReturnsAsync(_projects);

            var actionsParserMock = new Mock <IActionsParser>();

            actionsParserMock.Setup(m => m.GetNotificationActions(It.IsAny <IEnumerable <SqlWorkflowEvent> >())).Returns(_notificationActions);
            var actionHelper = new ArtifactsPublishedActionHelper(actionsParserMock.Object);

            var result = await actionHelper.HandleAction(_tenantInformation, message, _repositoryMock.Object);

            Assert.IsFalse(result);
        }
示例#7
0
        public async Task ArtifactsPublishedActionHelper_ReturnsFalse_WhenNoNotificationActionsAreFound()
        {
            var message = new ArtifactsPublishedMessage {
                Artifacts = new[] { new PublishedArtifactInformation() }
            };

            _repositoryMock.Setup(m => m.GetWorkflowPropertyTransitionsForArtifactsAsync(It.IsAny <int>(), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <IEnumerable <int> >())).ReturnsAsync(_triggers);
            _repositoryMock.Setup(m => m.GetWorkflowStatesForArtifactsAsync(It.IsAny <int>(), It.IsAny <IEnumerable <int> >(), It.IsAny <int>(), It.IsAny <bool>())).ReturnsAsync(_states);
            _repositoryMock.Setup(m => m.GetProjectNameByIdsAsync(It.IsAny <IEnumerable <int> >())).ReturnsAsync(_projects);

            var actionsParserMock = new Mock <IActionsParser>();
            // empty list of notification actions
            var emptyNotificationActionsList = new List <EmailNotificationAction>();

            actionsParserMock.Setup(m => m.GetNotificationActions(It.IsAny <IEnumerable <SqlWorkflowEvent> >())).Returns(emptyNotificationActionsList);
            var actionHelper = new ArtifactsPublishedActionHelper(actionsParserMock.Object);

            var result = await actionHelper.HandleAction(_tenantInformation, message, _repositoryMock.Object);

            Assert.IsFalse(result);
        }
示例#8
0
        public async Task ArtifactsPublishedActionHelper_ReturnsFalse_WhenPropertyTypeIdDoesNotMatchNotificationPropertyTypeId()
        {
            // non-matching PropertyChange Type IDs
            const int notificationPropertyTypeId = 1 + PropertyTypeId;
            var       emailNotification          = new EmailNotificationAction
            {
                ConditionalStateId = WorkflowStateId,
                PropertyTypeId     = notificationPropertyTypeId
            };

            emailNotification.Emails.Add("");
            var notificationActions = new List <EmailNotificationAction>
            {
                emailNotification
            };
            var message = new ArtifactsPublishedMessage {
                Artifacts = new[] { new PublishedArtifactInformation {
                                        ModifiedProperties = new List <PublishedPropertyInformation> {
                                            new PublishedPropertyInformation {
                                                TypeId = PropertyTypeId
                                            }
                                        }
                                    } }
            };

            _repositoryMock.Setup(m => m.GetWorkflowPropertyTransitionsForArtifactsAsync(It.IsAny <int>(), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <IEnumerable <int> >())).ReturnsAsync(_triggers);
            _repositoryMock.Setup(m => m.GetWorkflowStatesForArtifactsAsync(It.IsAny <int>(), It.IsAny <IEnumerable <int> >(), It.IsAny <int>(), It.IsAny <bool>())).ReturnsAsync(_states);
            _repositoryMock.Setup(m => m.GetProjectNameByIdsAsync(It.IsAny <IEnumerable <int> >())).ReturnsAsync(_projects);
            _repositoryMock.Setup(m => m.GetInstancePropertyTypeIdsMap(It.IsAny <IEnumerable <int> >())).ReturnsAsync(_instancePropertyTypeIds);
            var actionsParserMock = new Mock <IActionsParser>();

            actionsParserMock.Setup(m => m.GetNotificationActions(It.IsAny <IEnumerable <SqlWorkflowEvent> >())).Returns(notificationActions);
            var actionHelper = new ArtifactsPublishedActionHelper(actionsParserMock.Object);

            var result = await actionHelper.HandleAction(_tenantInformation, message, _repositoryMock.Object);

            Assert.IsFalse(result);
        }
        private static IWorkflowMessage GetPublishedMessage(int userId, int revisionId, long transactionId, IBaseArtifactVersionControlInfo artifactInfo, IDictionary <int, IList <Property> > modifiedProperties)
        {
            var message = new ArtifactsPublishedMessage
            {
                TransactionId = transactionId,
                UserId        = userId,
                RevisionId    = revisionId
            };
            var artifacts = new List <PublishedArtifactInformation>();
            var artifact  = new PublishedArtifactInformation
            {
                Id                   = artifactInfo.Id,
                Name                 = artifactInfo.Name,
                Predefined           = (int)artifactInfo.PredefinedType,
                IsFirstTimePublished = false, // State change always occurs on published artifacts
                ProjectId            = artifactInfo.ProjectId,
                Url                  = ServerUriHelper.GetArtifactUrl(artifactInfo.Id, true),
                ModifiedProperties   = new List <PublishedPropertyInformation>()
            };

            IList <Property> artifactModifiedProperties;

            if (modifiedProperties?.Count > 0 && modifiedProperties.TryGetValue(artifactInfo.Id, out artifactModifiedProperties) && artifactModifiedProperties?.Count > 0)
            {
                artifact.ModifiedProperties.AddRange(artifactModifiedProperties.Select(p => new PublishedPropertyInformation
                {
                    TypeId         = p.PropertyTypeId,
                    PredefinedType = (int)p.Predefined
                }));
                // Only add artifact to list if there is a list of modified properties
                artifacts.Add(artifact);
            }

            message.Artifacts = artifacts;
            return(message);
        }
        internal static async Task <bool> ProcessCreatedArtifacts(TenantInformation tenant,
                                                                  ArtifactsPublishedMessage message,
                                                                  IArtifactsPublishedRepository repository,
                                                                  IServiceLogRepository serviceLogRepository,
                                                                  IWorkflowMessagingProcessor messageProcessor,
                                                                  int transactionCommitWaitTimeInMilliSeconds = 60000)
        {
            var createdArtifacts = message?.Artifacts?.Where(p => p.IsFirstTimePublished && repository.WorkflowRepository.IsWorkflowSupported((ItemTypePredefined)p.Predefined)).ToList();

            if (createdArtifacts == null || createdArtifacts.Count <= 0)
            {
                Logger.Log("No created artifacts found", message, tenant);
                return(false);
            }
            Logger.Log($"{createdArtifacts.Count} created artifacts found", message, tenant);

            var artifactIds   = createdArtifacts.Select(a => a.Id).ToHashSet();
            var artifactInfos = (await repository.WorkflowRepository.GetWorkflowMessageArtifactInfoAsync(message.UserId, artifactIds, message.RevisionId)).ToDictionary(k => k.Id);

            Logger.Log($"{artifactInfos.Count} artifact infos found", message, tenant);
            var notificationMessages = new Dictionary <int, List <IWorkflowMessage> >();

            foreach (var createdArtifact in createdArtifacts)
            {
                WorkflowMessageArtifactInfo artifactInfo;
                if (!artifactInfos.TryGetValue(createdArtifact.Id, out artifactInfo))
                {
                    await serviceLogRepository.LogInformation(LogSource, $"Could not recover information for artifact Id: {createdArtifact.Id} and Name: {createdArtifact.Name} and Project Id: {createdArtifact.ProjectId}");

                    Logger.Log($"Could not recover information for artifact Id: {createdArtifact.Id} and Name: {createdArtifact.Name} and Project Id: {createdArtifact.ProjectId}", message, tenant);
                    continue;
                }

                var eventTriggers = await repository.WorkflowRepository.GetWorkflowEventTriggersForNewArtifactEvent(message.UserId,
                                                                                                                    new[] { createdArtifact.Id },
                                                                                                                    message.RevisionId, true);

                if (eventTriggers?.AsynchronousTriggers == null ||
                    eventTriggers.AsynchronousTriggers.Count == 0)
                {
                    Logger.Log($"Found no async triggers for artifact with ID {createdArtifact.Id}", message, tenant);
                    continue;
                }
                Logger.Log($"Found {eventTriggers.AsynchronousTriggers.Count} async triggers for artifact with ID {createdArtifact.Id}", message, tenant);

                int artifactId = createdArtifact.Id;

                var currentState = await repository.WorkflowRepository.GetStateForArtifactAsync(message.UserId, createdArtifact.Id, int.MaxValue, true);

                var actionMessages = await WorkflowEventsMessagesHelper.GenerateMessages(message.UserId,
                                                                                         message.RevisionId,
                                                                                         message.UserName,
                                                                                         message.TransactionId,
                                                                                         eventTriggers.AsynchronousTriggers,
                                                                                         artifactInfo,
                                                                                         artifactInfo.ProjectName,
                                                                                         new Dictionary <int, IList <Property> >(),
                                                                                         currentState,
                                                                                         createdArtifact.Url,
                                                                                         createdArtifact.BaseUrl,
                                                                                         createdArtifact.AncestorArtifactTypeIds,
                                                                                         repository.UsersRepository,
                                                                                         serviceLogRepository,
                                                                                         repository.WebhooksRepository,
                                                                                         repository.ProjectMetaRepository);

                if (actionMessages == null || actionMessages.Count == 0)
                {
                    continue;
                }

                if (!notificationMessages.ContainsKey(artifactId))
                {
                    notificationMessages.Add(artifactId, new List <IWorkflowMessage>());
                }

                notificationMessages[artifactId].AddRange(actionMessages);
            }

            if (notificationMessages.Count == 0)
            {
                Logger.Log("None of the created artifacts have async triggers", message, tenant);
                return(false);
            }
            Logger.Log($"Sending async trigger messages for artifacts: {string.Join(", ", notificationMessages.Select(kvp => kvp.Key))}", message, tenant);

            foreach (var notificationMessage in notificationMessages.Where(m => m.Value != null))
            {
                await WorkflowEventsMessagesHelper.ProcessMessages(LogSource,
                                                                   tenant,
                                                                   serviceLogRepository,
                                                                   notificationMessage.Value,
                                                                   $"Error on new artifact creation with Id: {notificationMessage.Key}",
                                                                   messageProcessor);
            }

            return(true);
        }
        private static async Task ProcessCustomPropertyChange(TenantInformation tenant,
                                                              ArtifactsPublishedMessage message,
                                                              IArtifactsPublishedRepository repository,
                                                              List <EmailNotificationAction> notifications,
                                                              HashSet <int> modifiedCustomPropertiesSet,
                                                              SqlWorkFlowStateInformation currentStateInfo,
                                                              List <PublishedArtifactInformation> updatedArtifacts,
                                                              int artifactId,
                                                              Dictionary <int, SqlWorkFlowStateInformation> workflowStates,
                                                              List <SqlProject> projects,
                                                              Dictionary <int, List <IWorkflowMessage> > notificationMessages)
        {
            if (modifiedCustomPropertiesSet.Count == 0)
            {
                return;
            }
            ////Dictionary<int, List<int>> instancePropertyTypeIds
            var instancePropertyTypeIds = await repository.GetInstancePropertyTypeIdsMap(modifiedCustomPropertiesSet);

            Logger.Log(
                $"{instancePropertyTypeIds.Count} instance property type IDs found: {string.Join(", ", instancePropertyTypeIds.Select(k => k.Key))}",
                message, tenant, LogLevel.Debug);

            foreach (var notificationAction in notifications)
            {
                Logger.Log("Processing notification action", message, tenant, LogLevel.Debug);

                if (!notificationAction.EventPropertyTypeId.HasValue)
                {
                    continue;
                }

                int eventPropertyTypeId = notificationAction.EventPropertyTypeId.Value;
                if (!instancePropertyTypeIds.ContainsKey(eventPropertyTypeId))
                {
                    Logger.Log(
                        $"The property type ID {notificationAction.EventPropertyTypeId} was not found in the dictionary of instance property type IDs.",
                        message, tenant, LogLevel.Debug);
                    continue;
                }

                List <int> propertyTypeIds;
                if (!instancePropertyTypeIds.TryGetValue(eventPropertyTypeId, out propertyTypeIds) || propertyTypeIds.IsEmpty())
                {
                    Logger.Log(
                        $"The property type ID {notificationAction.EventPropertyTypeId} was not found in the dictionary of instance property type IDs.",
                        message, tenant, LogLevel.Debug);
                    continue;
                }

                if (notificationAction.ConditionalStateId.HasValue &&
                    (currentStateInfo == null ||
                     currentStateInfo.WorkflowStateId != notificationAction.ConditionalStateId.Value))
                {
                    // The conditional state id is present, but either the current state info is not present or the current state is not same as conditional state
                    var currentStateId = currentStateInfo?.WorkflowStateId.ToString() ?? "none";
                    Logger.Log(
                        $"Conditional state ID {notificationAction.ConditionalStateId.Value} does not match current state ID: {currentStateId}",
                        message, tenant, LogLevel.Debug);
                    continue;
                }

                var artifact = updatedArtifacts.First(a => a.Id == artifactId);

                string messageHeader =
                    I18NHelper.FormatInvariant("You are being notified because artifact with Id: {0} has been updated.",
                                               artifactId);
                var artifactPartUrl = artifact.Url ?? ServerUriHelper.GetArtifactUrl(artifactId, true);
                var blueprintUrl    = artifact.BaseUrl ?? ServerUriHelper.GetBaseHostUri()?.ToString();
                var emails          = await WorkflowEventsMessagesHelper.GetEmailValues(message.RevisionId, artifactId,
                                                                                        notificationAction, repository.UsersRepository);

                var notificationMessage = new NotificationMessage
                {
                    TransactionId          = message.TransactionId,
                    ArtifactName           = workflowStates[artifactId].Name,
                    ProjectName            = projects.First(p => p.ItemId == artifact.ProjectId).Name,
                    Subject                = notificationAction.Subject,
                    From                   = notificationAction.FromDisplayName,
                    To                     = emails,
                    Header                 = messageHeader,
                    Message                = notificationAction.Message,
                    RevisionId             = message.RevisionId,
                    UserId                 = message.UserId,
                    ArtifactTypeId         = currentStateInfo.ItemTypeId,
                    ArtifactId             = artifactId,
                    ArtifactUrl            = artifactPartUrl,
                    ArtifactTypePredefined = artifact.Predefined,
                    ProjectId              = artifact.ProjectId,
                    BlueprintUrl           = blueprintUrl
                };

                if (notificationMessages.ContainsKey(artifactId))
                {
                    notificationMessages[artifactId].Add(notificationMessage);
                }
                else
                {
                    notificationMessages.Add(artifactId,
                                             new List <IWorkflowMessage>
                    {
                        notificationMessage
                    });
                }
            }
        }
        private static async Task ProcessSystemPropertyChange(TenantInformation tenant,
                                                              ArtifactsPublishedMessage message,
                                                              IArtifactsPublishedRepository repository,
                                                              List <EmailNotificationAction> notifications,
                                                              HashSet <PropertyTypePredefined> modifiedSystemPropertiesSet,
                                                              SqlWorkFlowStateInformation currentStateInfo,
                                                              List <PublishedArtifactInformation> updatedArtifacts,
                                                              int artifactId,
                                                              Dictionary <int, SqlWorkFlowStateInformation> workflowStates,
                                                              List <SqlProject> projects,
                                                              Dictionary <int, List <IWorkflowMessage> > notificationMessages)
        {
            if (modifiedSystemPropertiesSet.Count == 0)
            {
                return;
            }

            foreach (var notificationAction in notifications)
            {
                Logger.Log("Processing notification action", message, tenant, LogLevel.Debug);

                if (!notificationAction.EventPropertyTypeId.HasValue)
                {
                    continue;
                }

                int eventPropertyTypeId = notificationAction.EventPropertyTypeId.Value;

                // If system property provided is neither name or description
                if (eventPropertyTypeId != WorkflowConstants.PropertyTypeFakeIdName &&
                    eventPropertyTypeId != WorkflowConstants.PropertyTypeFakeIdDescription)
                {
                    Logger.Log(
                        $"The system property type ID {notificationAction.EventPropertyTypeId} is not supported. Only Name and Description are supported.",
                        message, tenant, LogLevel.Debug);
                    continue;
                }

                // If modified properties does not conatin event property type Id
                if (!modifiedSystemPropertiesSet.Contains(GetPropertyTypePredefined(notificationAction.EventPropertyTypeId.Value)))
                {
                    continue;
                }

                if (notificationAction.ConditionalStateId.HasValue &&
                    (currentStateInfo == null ||
                     currentStateInfo.WorkflowStateId != notificationAction.ConditionalStateId.Value))
                {
                    // The conditional state id is present, but either the current state info is not present or the current state is not same as conditional state
                    var currentStateId = currentStateInfo?.WorkflowStateId.ToString() ?? "none";
                    Logger.Log(
                        $"Conditional state ID {notificationAction.ConditionalStateId.Value} does not match current state ID: {currentStateId}",
                        message, tenant, LogLevel.Debug);
                    continue;
                }

                var artifact = updatedArtifacts.First(a => a.Id == artifactId);

                string messageHeader =
                    I18NHelper.FormatInvariant("You are being notified because artifact with Id: {0} has been updated.",
                                               artifactId);
                var artifactPartUrl = artifact.Url ?? ServerUriHelper.GetArtifactUrl(artifactId, true);
                var blueprintUrl    = artifact.BaseUrl ?? ServerUriHelper.GetBaseHostUri()?.ToString();
                var emails          = await WorkflowEventsMessagesHelper.GetEmailValues(message.RevisionId, artifactId,
                                                                                        notificationAction, repository.UsersRepository);

                var notificationMessage = new NotificationMessage
                {
                    TransactionId          = message.TransactionId,
                    ArtifactName           = workflowStates[artifactId].Name,
                    ProjectName            = projects.First(p => p.ItemId == artifact.ProjectId).Name,
                    Subject                = notificationAction.Subject,
                    From                   = notificationAction.FromDisplayName,
                    To                     = emails,
                    Header                 = messageHeader,
                    Message                = notificationAction.Message,
                    RevisionId             = message.RevisionId,
                    UserId                 = message.UserId,
                    ArtifactTypeId         = currentStateInfo.ItemTypeId,
                    ArtifactId             = artifactId,
                    ArtifactUrl            = artifactPartUrl,
                    ArtifactTypePredefined = artifact.Predefined,
                    ProjectId              = artifact.ProjectId,
                    BlueprintUrl           = blueprintUrl
                };

                if (notificationMessages.ContainsKey(artifactId))
                {
                    notificationMessages[artifactId].Add(notificationMessage);
                }
                else
                {
                    notificationMessages.Add(artifactId,
                                             new List <IWorkflowMessage>
                    {
                        notificationMessage
                    });
                }
            }
        }
        internal static async Task <bool> ProcessUpdatedArtifacts(
            TenantInformation tenant,
            ArtifactsPublishedMessage message,
            IArtifactsPublishedRepository repository,
            IServiceLogRepository serviceLogRepository,
            IActionsParser actionsParser,
            IWorkflowMessagingProcessor messageProcessor)
        {
            var allUpdatedArtifacts = message?.Artifacts?.Where(p => !p.IsFirstTimePublished).ToList();

            if (allUpdatedArtifacts == null || allUpdatedArtifacts.Count <= 0)
            {
                Logger.Log("No updated artifacts found", message, tenant);
                return(false);
            }
            Logger.Log($"{allUpdatedArtifacts.Count} updated artifacts found", message, tenant);

            var updatedArtifacts = allUpdatedArtifacts.Where(a => a.ModifiedProperties?.Count > 0).ToList();

            if (updatedArtifacts.Count == 0)
            {
                Logger.Log("No modified properties found for updated artifacts", message, tenant);
                return(false);
            }

            // Get artifacts which have modified properties list populated
            var allArtifactsModifiedProperties = updatedArtifacts.ToDictionary(k => k.Id,
                                                                               v => v.ModifiedProperties ?? new List <PublishedPropertyInformation>());

            Logger.Log(
                $"{allArtifactsModifiedProperties.Count} artifacts found: {string.Join(", ", allArtifactsModifiedProperties.Select(k => k.Key))}",
                message, tenant, LogLevel.Debug);

            if (allArtifactsModifiedProperties.Count == 0)
            {
                return(false);
            }

            // Get property transitions for published artifact ids.
            var publishedArtifactIds   = updatedArtifacts.Select(a => a.Id).ToHashSet();
            var artifactPropertyEvents =
                await
                repository.GetWorkflowPropertyTransitionsForArtifactsAsync(message.UserId,
                                                                           message.RevisionId,
                                                                           (int)TransitionType.Property, publishedArtifactIds);

            // If no property transitions found, then call does not need to proceed
            Logger.Log($"{artifactPropertyEvents?.Count ?? 0} workflow property events found", message, tenant, LogLevel.Debug);
            if (artifactPropertyEvents == null || artifactPropertyEvents.Count == 0)
            {
                Logger.Log("No property change triggers found", message, tenant);
                return(false);
            }

            // Convert all property transitions to a dictionary with artifact id as key
            var activePropertyTransitions = new Dictionary <int, IList <SqlWorkflowEvent> >();
            var publishedArtifactEvents   = artifactPropertyEvents.Where(ape => publishedArtifactIds.Contains(ape.VersionItemId));

            // key = artifact id, value = all events
            foreach (var artifactPropertyEvent in publishedArtifactEvents)
            {
                if (activePropertyTransitions.ContainsKey(artifactPropertyEvent.VersionItemId))
                {
                    activePropertyTransitions[artifactPropertyEvent.VersionItemId].Add(artifactPropertyEvent);
                }
                else
                {
                    activePropertyTransitions.Add(artifactPropertyEvent.VersionItemId,
                                                  new List <SqlWorkflowEvent> {
                        artifactPropertyEvent
                    });
                }
            }

            var sqlWorkflowStates =
                await
                repository.GetWorkflowStatesForArtifactsAsync(message.UserId, activePropertyTransitions.Keys,
                                                              message.RevisionId);

            var workflowStates = sqlWorkflowStates.Where(w => w.WorkflowStateId > 0).ToDictionary(k => k.ArtifactId);

            Logger.Log(
                $"{workflowStates.Count} workflow states found for artifacts: {string.Join(", ", workflowStates.Select(k => k.Key))}",
                message, tenant, LogLevel.Debug);
            if (workflowStates.Count == 0)
            {
                return(false);
            }

            // Get project names
            var projectIds = updatedArtifacts.Select(a => a.ProjectId).ToList();
            var projects   = await repository.GetProjectNameByIdsAsync(projectIds);

            Logger.Log($"{projects.Count} project names found for project IDs: {string.Join(", ", projectIds)}", message, tenant,
                       LogLevel.Debug);

            var notificationMessages = new Dictionary <int, List <IWorkflowMessage> >();

            // For artifacts in active property transitions
            foreach (var artifactId in activePropertyTransitions.Keys)
            {
                Logger.Log($"Processing artifact with ID: {artifactId}", message, tenant, LogLevel.Debug);

                var artifactTransitionInfo = activePropertyTransitions[artifactId];
                var notifications          = actionsParser.GetNotificationActions(artifactTransitionInfo).ToList();
                Logger.Log($"{notifications.Count} Notification actions found", message, tenant, LogLevel.Debug);
                if (notifications.Count == 0)
                {
                    continue;
                }

                List <PublishedPropertyInformation> artifactModifiedProperties;
                if (!allArtifactsModifiedProperties.TryGetValue(artifactId, out artifactModifiedProperties))
                {
                    Logger.Log($"modified properties not found for {artifactId}", message, tenant, LogLevel.Debug);
                    continue;
                }

                Logger.Log($"{artifactModifiedProperties?.Count ?? 0} modified properties found", message, tenant,
                           LogLevel.Debug);
                if (artifactModifiedProperties == null || !artifactModifiedProperties.Any())
                {
                    continue;
                }

                SqlWorkFlowStateInformation currentStateInfo;
                if (!workflowStates.TryGetValue(artifactId, out currentStateInfo))
                {
                    continue;
                }

                var modifiedSystemPropertiesSet = artifactModifiedProperties.Where(a => a.PredefinedType == (int)PropertyTypePredefined.Name ||
                                                                                   a.PredefinedType == (int)PropertyTypePredefined.Description)
                                                  .Select(a => (PropertyTypePredefined)a.PredefinedType)
                                                  .ToHashSet();

                await ProcessSystemPropertyChange(tenant, message, repository, notifications, modifiedSystemPropertiesSet, currentStateInfo, updatedArtifacts, artifactId, workflowStates, projects, notificationMessages);

                var modifiedCustomPropertiesSet = artifactModifiedProperties.Where(a => a.PredefinedType == (int)PropertyTypePredefined.CustomGroup)
                                                  .Select(a => a.TypeId)
                                                  .ToHashSet();

                // Process custom properties
                Logger.Log(
                    $"{modifiedCustomPropertiesSet.Count} instance property type IDs being located: {string.Join(", ", modifiedCustomPropertiesSet)}",
                    message, tenant, LogLevel.Debug);

                await ProcessCustomPropertyChange(tenant, message, repository, notifications, modifiedCustomPropertiesSet, currentStateInfo, updatedArtifacts, artifactId, workflowStates, projects, notificationMessages);
            }

            if (notificationMessages.Count == 0)
            {
                Logger.Log("None of the modified properties have property change notification triggers", message, tenant);
                return(false);
            }
            Logger.Log($"Sending property change notifications for artifacts: {string.Join(", ", notificationMessages.Select(kvp => kvp.Key))}", message, tenant);

            foreach (var notificationMessage in notificationMessages)
            {
                await WorkflowEventsMessagesHelper.ProcessMessages(LogSource,
                                                                   tenant,
                                                                   serviceLogRepository,
                                                                   notificationMessage.Value,
                                                                   $"Error on new artifact creation with Id: {notificationMessage.Key}",
                                                                   messageProcessor);
            }

            return(true);
        }
示例#14
0
        public void TestInitialize()
        {
            _userId     = 2;
            _revisionId = 2548;

            _tenant = new TenantInformation
            {
                TenantId    = "Blueprint",
                PackageName = "Professional",
                TenantName  = "Blueprint",
                BlueprintConnectionString = "DBConnection",
                AdminStoreLog             = "localhost",
                ExpirationDate            = DateTime.MaxValue,
                PackageLevel = 2,
                StartDate    = DateTime.Today
            };

            _message = new ArtifactsPublishedMessage
            {
                RevisionId = _revisionId,
                UserId     = _userId,
                UserName   = "******",
                Artifacts  = new List <PublishedArtifactInformation>
                {
                    new PublishedArtifactInformation
                    {
                        Id   = ArtifactId,
                        Name = ArtifactName,
                        ModifiedProperties   = new List <PublishedPropertyInformation>(),
                        ProjectId            = ProjectId,
                        IsFirstTimePublished = true,
                        Url        = "localhost:id",
                        BaseUrl    = "localhost",
                        Predefined = (int)Predefined
                    }
                }
            };

            _workflowMessageArtifactInfos = new List <WorkflowMessageArtifactInfo>
            {
                new WorkflowMessageArtifactInfo
                {
                    Id             = ArtifactId,
                    ProjectName    = "ProjectName",
                    ProjectId      = ProjectId,
                    Name           = ArtifactName,
                    PredefinedType = Predefined,
                    ItemTypeId     = ItemTypeId
                }
            };

            _artifactsPublishedRepositoryMock = new Mock <IArtifactsPublishedRepository>(MockBehavior.Loose);
            _serviceLogRepositoryMock         = new Mock <IServiceLogRepository>(MockBehavior.Loose);
            _workflowRepoMock = new Mock <IWorkflowRepository>(MockBehavior.Loose);
            _workflowRepoMock
            .Setup(r => r.IsWorkflowSupported(It.IsAny <ItemTypePredefined>()))
            .Returns((ItemTypePredefined p) => SqlWorkflowRepository.IsWorkflowSupportedForArtifactType(p));
            _userRepoMock    = new Mock <IUsersRepository>(MockBehavior.Loose);
            _wfMessagingMock = new Mock <IWorkflowMessagingProcessor>(MockBehavior.Loose);

            _artifactsPublishedRepositoryMock.Setup(t => t.WorkflowRepository).Returns(_workflowRepoMock.Object);
            _artifactsPublishedRepositoryMock.Setup(t => t.UsersRepository).Returns(_userRepoMock.Object);
        }
示例#15
0
        public void TestInitialize()
        {
            _repositoryMock    = new Mock <IArtifactsPublishedRepository>();
            _tenantInformation = new TenantInformation
            {
                BlueprintConnectionString = "",
                TenantId = ""
            };
            _triggers = new List <SqlWorkflowEvent>
            {
                new SqlWorkflowEvent
                {
                    CurrentStateId          = 0,
                    VersionItemId           = 0,
                    EventPropertyTypeId     = 0,
                    EventType               = 0,
                    HolderId                = 0,
                    RequiredNewStateId      = 0,
                    RequiredPreviousStateId = 0,
                    Triggers                = "",
                    WorkflowId              = 0
                },
                new SqlWorkflowEvent
                {
                    CurrentStateId          = 1,
                    VersionItemId           = 0,
                    EventPropertyTypeId     = 0,
                    EventType               = 0,
                    HolderId                = 0,
                    RequiredNewStateId      = 0,
                    RequiredPreviousStateId = 0,
                    Triggers                = "",
                    WorkflowId              = 0
                }
            };
            _states = new List <SqlWorkFlowStateInformation>
            {
                new SqlWorkFlowStateInformation
                {
                    WorkflowStateId   = WorkflowStateId,
                    ArtifactId        = 0,
                    EndRevision       = 0,
                    ItemId            = 0,
                    ItemTypeId        = 0,
                    LockedByUserId    = 0,
                    Name              = "",
                    ProjectId         = 0,
                    Result            = 0,
                    StartRevision     = 0,
                    WorkflowId        = 0,
                    WorkflowName      = "",
                    WorkflowStateName = ""
                }
            };
            _projects = new List <SqlProject>
            {
                new SqlProject
                {
                    ItemId = 0,
                    Name   = ""
                }
            };
            _instancePropertyTypeIds = new Dictionary <int, List <int> > {
                { 0, new List <int> {
                      0
                  } }
            };
            var emailNotification = new EmailNotificationAction
            {
                ConditionalStateId = WorkflowStateId,
                PropertyTypeId     = PropertyTypeId
            };

            emailNotification.Emails.Add("");
            _notificationActions = new List <EmailNotificationAction> {
                emailNotification
            };

            _messageWithModifiedProperties = new ArtifactsPublishedMessage
            {
                Artifacts = new[]
                {
                    new PublishedArtifactInformation
                    {
                        ModifiedProperties = new List <PublishedPropertyInformation>
                        {
                            new PublishedPropertyInformation
                            {
                                TypeId = PropertyTypeId
                            }
                        }
                    }
                }
            };
        }