Example #1
0
        public EventNotificationStatus ProcessEvent(IVssRequestContext requestContext, NotificationType notificationType,
                                                    object notificationEventArgs, out int statusCode, out string statusMessage,
                                                    out Microsoft.TeamFoundation.Common.ExceptionPropertyCollection properties)
        {
            statusCode    = 0;
            properties    = null;
            statusMessage = String.Empty;
            try
            {
                BuildUpdatedEvent updatedEvent = (BuildUpdatedEvent)notificationEventArgs;
                Build             build        = updatedEvent.Build;
                Log.Info($"ProcessEvent {notificationEventArgs.GetType().Name} for build {updatedEvent.BuildId} (Build Number : {updatedEvent.Build.BuildNumber}, Build Definition: {updatedEvent.Build.Definition.Name})");

                CiEvent ciEvent = CiEventUtils.ToCiEvent(build);
                if (notificationEventArgs is BuildStartedEvent)
                {
                    ciEvent.EventType = CiEventType.Started;
                    _pluginManager.GeneralEventsQueue.Add(ciEvent);
                }
                else if (notificationEventArgs is BuildCompletedEvent)
                {
                    ciEvent.EventType = CiEventType.Finished;
                    _pluginManager.HandleFinishEvent(ciEvent);
                }
            }
            catch (Exception e)
            {
                var msg = $"ProcessEvent {notificationEventArgs.GetType().Name} failed {e.Message}";
                Log.Error(msg, e);
                TeamFoundationApplicationCore.LogException(requestContext, msg, e);
            }
            return(EventNotificationStatus.ActionPermitted);
        }
        public EventNotificationStatus ProcessEvent(IVssRequestContext requestContext, NotificationType notificationType,
                                                    object notificationEventArgs, out int statusCode, out string statusMessage,
                                                    out Microsoft.TeamFoundation.Common.ExceptionPropertyCollection properties)
        {
            //Log.Info($"ProcessEvent {notificationEventArgs.GetType().Name} - {notificationEventArgs.ToString()}");
            //Log.Info(JsonHelper.SerializeObject(notificationEventArgs, true));
            statusCode    = 0;
            properties    = null;
            statusMessage = String.Empty;
            try
            {
#if Package2019
                if (notificationEventArgs is Microsoft.TeamFoundation.Build2.Server.BuildEventBase)
                {
                    Microsoft.TeamFoundation.Build2.Server.BuildData build = (Microsoft.TeamFoundation.Build2.Server.BuildData)((Microsoft.TeamFoundation.Build2.Server.BuildEventBase)notificationEventArgs).Build;
                    Log.Info($"ProcessEvent {notificationEventArgs.GetType().Name} for project {build.ProjectId}, status: {build.Status}, BuildNumber: {build.BuildNumber}, DefinitionName: {build.Definition.Name}, DefinitionId: {build.Definition.Id}");
                    CiEvent ciEvent = ConvertToCiEvent2019(build);
                    if (notificationEventArgs is Microsoft.TeamFoundation.Build2.Server.BuildStartedEvent)
                    {
                        ciEvent.EventType = CiEventType.Started;
                        _pluginManager.GeneralEventsQueue.Add(ciEvent);
                    }
                    else if (notificationEventArgs is Microsoft.TeamFoundation.Build2.Server.BuildCompletedEvent)
                    {
                        ciEvent.EventType = CiEventType.Finished;
                        _pluginManager.HandleFinishEvent(ciEvent);
                    }
                }
#endif
            }
            catch (Exception e)
            {
                var msg = $"ProcessEvent {notificationEventArgs.GetType().Name} failed {e.Message}";
                Log.Error(msg, e);
            }
            return(EventNotificationStatus.ActionPermitted);
        }
        public EventNotificationStatus ProcessEvent(
            TeamFoundationRequestContext requestContext, NotificationType notificationType,
            object notificationEventArgs,
            out int statusCode, out string statusMessage,
            out Microsoft.TeamFoundation.Common.ExceptionPropertyCollection properties)
        {
            statusCode    = 0;
            statusMessage = string.Empty;
            properties    = null;

            try
            {
                if (notificationType == NotificationType.DecisionPoint &&
                    notificationEventArgs is PushNotification)
                {
                    PushNotification pushNotification = notificationEventArgs as PushNotification;

                    // validation applies?
                    var policy = GetPolicy(requestContext, pushNotification);
                    if (policy != null)
                    {
                        Logger.LogStart("Request controlled by policy");

                        var gitRepoService = requestContext.GetService <TeamFoundationGitRepositoryService>();
                        using (var repository = gitRepoService.FindRepositoryById(requestContext, pushNotification.RepositoryId))
                        {
                            Logger.LogRequest(requestContext, pushNotification, repository);

                            var validationResults = policy.CheckRules(requestContext, pushNotification, repository);
                            //TODO accumulate failures
                            var failsAt = validationResults.FirstOrDefault(v => v.Fails);
                            if (failsAt != null)
                            {
                                if (PluginConfiguration.Instance.ShouldSendEmail)
                                {
                                    try
                                    {
                                        string email = GetEmailAddress(requestContext, pushNotification);
                                        if (string.IsNullOrWhiteSpace(email))
                                        {
                                            // no email for user -> notify admin
                                            email = PluginConfiguration.Instance.AdministratorEmail;
                                        }
                                        UserAlerter.InformUserOfFailure(email, requestContext, pushNotification, validationResults);
                                    }
                                    catch (Exception e)
                                    {
                                        Logger.Log(string.Format("Error: failed to notify user {0}, reason {1}", pushNotification.AuthenticatedUserName, e.Message));
                                    } //try
                                }     //if

                                Logger.LogDenied(failsAt.ReasonMessage);
                                statusCode    = failsAt.ReasonCode;
                                statusMessage = failsAt.ReasonMessage;
                                return(EventNotificationStatus.ActionDenied);
                            } //if
                        }     //using
                    }         //if
                }             //if
            }
            catch (Exception ex)
            {
                Logger.LogException(ex);
                throw; // TFS will disable plugin
            }//try

            /*
             * from https://msdn.microsoft.com/en-us/library/Gg214903%28v=vs.120%29.aspx
             * ActionDenied	Action denied; do not notify other subscribers.
             * ActionPermitted	Action permitted; continue with subscriber notification.
             * ActionApproved	Like ActionPermitted, but do not notify other subscribers.
             */
            return(EventNotificationStatus.ActionPermitted);
        }
Example #4
0
        public EventNotificationStatus ProcessEvent(TeamFoundationRequestContext requestContext, NotificationType notificationType,
                                                    object notificationEventArgs, out int statusCode, out string statusMessage, out Microsoft.TeamFoundation.Common.ExceptionPropertyCollection properties)
        {
            statusCode    = 0;
            statusMessage = string.Empty;
            properties    = null;

            try
            {
                if (notificationType == NotificationType.Notification && notificationEventArgs is PushNotification)
                {
                    Stopwatch timer = new Stopwatch();
                    timer.Start();

                    PushNotification pushNotification = notificationEventArgs as PushNotification;
                    var repositoryService             = requestContext.GetService <TeamFoundationGitRepositoryService>();
                    var commonService = requestContext.GetService <CommonStructureService>();

                    using (TfsGitRepository repository = repositoryService.FindRepositoryById(requestContext, pushNotification.RepositoryId))
                    {
                        string repoName    = pushNotification.RepositoryName;
                        string projectName = commonService.GetProject(requestContext, pushNotification.TeamProjectUri).Name;
                        string userName    = pushNotification.AuthenticatedUserName.Replace(DOMAIN_PREFIX, "");

                        var lines = new List <string>();

                        string pushText = pushNotification.IsForceRequired(requestContext, repository) ? "FORCE push" : "push";
                        lines.Add(String.Format("{0} by {1} to {2}/{3}", pushText, userName, projectName, repoName));

                        var refNames   = new Dictionary <byte[], List <string> >(new ByteArrayComparer());
                        var oldCommits = new HashSet <byte[]>(new ByteArrayComparer());
                        var unknowns   = new List <RefUpdateResultGroup>();

                        // Associate refs (branch, ligtweight and annotated tag) with corresponding commit
                        var refUpdateResultGroups = pushNotification.RefUpdateResults
                                                    .Where(r => r.Succeeded)
                                                    .GroupBy(r => r.NewObjectId, (key, items) => new RefUpdateResultGroup(key, items), new ByteArrayComparer());

                        foreach (var refUpdateResultGroup in refUpdateResultGroups)
                        {
                            byte[] newObjectId = refUpdateResultGroup.NewObjectId;
                            byte[] commitId    = null;

                            if (newObjectId.IsZero())
                            {
                                commitId = newObjectId;
                            }
                            else
                            {
                                TfsGitObject gitObject = repository.LookupObject(requestContext, newObjectId);

                                if (gitObject.ObjectType == TfsGitObjectType.Commit)
                                {
                                    commitId = newObjectId;
                                }
                                else if (gitObject.ObjectType == TfsGitObjectType.Tag)
                                {
                                    var tag    = (TfsGitTag)gitObject;
                                    var commit = tag.TryResolveToCommit(requestContext);
                                    if (commit != null)
                                    {
                                        commitId = commit.ObjectId;
                                    }
                                }
                            }

                            if (commitId != null)
                            {
                                List <string> names;
                                if (!refNames.TryGetValue(commitId, out names))
                                {
                                    names = new List <string>();
                                    refNames.Add(commitId, names);
                                }
                                names.AddRange(RefsToStrings(refUpdateResultGroup.RefUpdateResults));

                                if (commitId.IsZero() || !pushNotification.IncludedCommits.Any(r => r.SequenceEqual(commitId)))
                                {
                                    oldCommits.Add(commitId);
                                }
                            }
                            else
                            {
                                unknowns.Add(refUpdateResultGroup);
                            }
                        }

                        // Display new commits with refs
                        foreach (byte[] commitId in pushNotification.IncludedCommits)
                        {
                            TfsGitCommit gitCommit = (TfsGitCommit)repository.LookupObject(requestContext, commitId);
                            string       line      = CommitToString(requestContext, gitCommit, "commit", pushNotification, refNames);
                            lines.Add(line);
                        }

                        // Display updated refs to old commits
                        foreach (byte[] commitId in oldCommits)
                        {
                            string line = null;

                            if (commitId.IsZero())
                            {
                                line = String.Format("{0} deleted", String.Join("", refNames[commitId]));
                            }
                            else
                            {
                                TfsGitCommit gitCommit = (TfsGitCommit)repository.LookupObject(requestContext, commitId);
                                line = CommitToString(requestContext, gitCommit, "->", pushNotification, refNames);
                            }
                            lines.Add(line);
                        }

                        // Display "unknown" refs
                        foreach (var refUpdateResultGroup in unknowns)
                        {
                            byte[]       newObjectId = refUpdateResultGroup.NewObjectId;
                            TfsGitObject gitObject   = repository.LookupObject(requestContext, newObjectId);
                            string       line        = String.Format("{0} -> {1} {2}", RefsToString(refUpdateResultGroup.RefUpdateResults), gitObject.ObjectType, newObjectId.ToHexString());

                            lines.Add(line);
                        }

                        //Log(lines);

                        List <string> sendLines = lines;
                        if (lines.Count > MAX_LINES)
                        {
                            sendLines = lines.Take(MAX_LINES).ToList();
                            sendLines.Add(String.Format("{0} more line(s) suppressed.", lines.Count - MAX_LINES));
                        }

                        Task.Run(() => SendToBot(sendLines));
                    }

                    timer.Stop();
                    //Log("Time spent in ProcessEvent: " + timer.Elapsed);
                }
            }
            catch (Exception ex)
            {
                Log(ex.Message);
                Log(ex.StackTrace);
            }

            return(EventNotificationStatus.ActionPermitted);
        }