public EventNotificationStatus ProcessEvent(TeamFoundationRequestContext requestContext, NotificationType notificationType, object notificationEventArgs, out int statusCode, out string statusMessage, out ExceptionPropertyCollection properties)
        {
            statusCode = 0;
            properties = null;
            statusMessage = string.Empty;

            try
            {
                if (notificationType == NotificationType.DecisionPoint &&
                    notificationEventArgs is CheckinNotification)
                {
                    var args = notificationEventArgs as
                               CheckinNotification;
                    if (args.PolicyOverrideInfo.PolicyFailures.Length > 0)
                    {
                        statusMessage = "Policy Overriding is not allowed.";
                        return EventNotificationStatus.ActionDenied;
                    }
                }
                return EventNotificationStatus.ActionPermitted;
            }
            catch (Exception ex)
            {
                // log the error and fail the check in
                statusMessage = "Error in plugin '" + this.Name + "', error details: "
                                + ex;
                EventLog.WriteEntry("TFS Service", statusMessage,
                    EventLogEntryType.Error);
                return EventNotificationStatus.ActionDenied;
            }
        }
コード例 #2
0
        /// <summary>
        /// TFS Main Event Handler
        /// </summary>
        /// <param name="requestContext">Event context passed in by TFS</param>
        /// <param name="notificationType">DecisionPoint or Notification</param>
        /// <param name="notificationEventArgs">Object that was published</param>
        /// <param name="statusCode">Code to return to the user when a decision point fails</param>
        /// <param name="statusMessage">Message to return to the user when a decision point fails</param>
        /// <param name="properties">Properties to return to the user when a decision point fails</param>
        /// <returns></returns>
        public EventNotificationStatus ProcessEvent(TeamFoundationRequestContext requestContext, NotificationType notificationType,
                                                    object notificationEventArgs, out int statusCode, out string statusMessage,
                                                    out ExceptionPropertyCollection properties)
        {
            #region method outputs
            EventNotificationStatus returnStatus = EventNotificationStatus.ActionPermitted; //allows the action if no other subscribers reject
            statusCode = 0;
            properties = null;
            statusMessage = String.Empty;
            #endregion

            try {
                var ev = notificationEventArgs as WorkItemChangedEvent;
                if (notificationType == NotificationType.Notification && notificationEventArgs is WorkItemChangedEvent) {
                    int thisWorkItemID = getWorkItemID(ev);
                    if (ev.ChangeType == ChangeTypes.New) { //new TFS Work Item created
                        returnStatus = TfsEvent_WorkItemCreated(requestContext, notificationEventArgs, ev.PortfolioProject, thisWorkItemID);
                    }
                }
            }
            catch (Exception exception) {
                TeamFoundationApplicationCore.LogException("Error processing event", exception);
            }

            return returnStatus;
        }
        public EventNotificationStatus ProcessEvent(TeamFoundationRequestContext requestContext, NotificationType notificationType, object notificationEventArgs, out int statusCode, out string statusMessage, out ExceptionPropertyCollection properties)
        {
            statusCode = 0;
            properties = null;
            statusMessage = string.Empty;
            try
            {
                if (notificationType == NotificationType.Notification && notificationEventArgs is CheckinNotification)
                {
                    var checkinNotification = notificationEventArgs as CheckinNotification;
                    if (ShouldMergeItemsIfNecessary(requestContext, checkinNotification))
                    {
                        var changeset = requestContext.GetChangeset(checkinNotification.Changeset);
                        if (changeset != null)
                        {
                            TfsTeamProjectCollection impersonatedCollection = requestContext.GetImpersonatedCollection(changeset.Committer);
                            MergeWorkItems(impersonatedCollection, changeset.ChangesetId);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                TeamFoundationApplicationCore.LogException("Inmeta.TFS.MergeWorkItemEventHandler encountered an exception", ex);
            }

            return EventNotificationStatus.ActionPermitted;
        }
コード例 #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="message"></param>
        /// <param name="innerException"></param>
        public ServerException(string message, Exception innerException) : base(message, innerException)
        {
            var exception = innerException as System.Web.Services.Protocols.SoapException;

            if ((exception != null) && (exception.Detail != null))
            {
                try
                {
                    using (var reader = new System.IO.StringReader(exception.Detail.OuterXml))
                    {
                        var reader2 = System.Xml.XmlReader.Create(reader);
                        reader2.Read();
                        while (reader2.NodeType == System.Xml.XmlNodeType.Element)
                        {
                            if (reader2.Name == "ExceptionProperties")
                            {
                                reader2.Read();
                                m_properties = new Dictionary <object, object>();
                                foreach (KeyValuePair <string, object> pair in ExceptionPropertyCollection.FromXml(reader2))
                                {
                                    this.m_properties[pair.Key.ToUpperInvariant()] = pair.Value;
                                }
                            }
                            reader2.Read();
                        }
                    }
                }
                catch (Exception)
                {
                }
            }
        }
コード例 #5
0
 public ProcessingResult()
 {
     StatusCode          = 0;
     ExceptionProperties = new ExceptionPropertyCollection();
     StatusMessage       = String.Empty;
     NotificationStatus  = EventNotificationStatus.ActionPermitted;
 }
コード例 #6
0
        /// <summary>
        /// Recupera a <see cref="SoapException"/> equivalente.
        /// </summary>
        /// <returns></returns>
        internal virtual SoapException ToSoapException()
        {
            XmlNode detail     = null;
            var     properties = new ExceptionPropertyCollection();

            this.GetExceptionProperties(properties);
            if ((base.InnerException != null) || (properties.Count > 0))
            {
                using (var writer = new System.IO.StringWriter(System.Globalization.CultureInfo.InvariantCulture))
                {
                    XmlTextWriter writer2 = new XmlTextWriter(writer);
                    writer2.WriteStartDocument();
                    writer2.WriteStartElement(SoapException.DetailElementName.Name, SoapException.DetailElementName.Namespace);
                    writer2.WriteAttributeString("xmlns", "xsd", "http://www.w3.org/2000/xmlns/", "http://www.w3.org/2001/XMLSchema");
                    writer2.WriteAttributeString("xmlns", "xsi", "http://www.w3.org/2000/xmlns/", "http://www.w3.org/2001/XMLSchema-instance");
                    if (base.InnerException != null)
                    {
                        writer2.WriteAttributeString("InnerExceptionType", base.InnerException.GetType().Name);
                        writer2.WriteAttributeString("InnerExceptionMessage", base.InnerException.Message);
                    }
                    if (properties.Count > 0)
                    {
                    }
                    writer2.WriteEndElement();
                    writer2.WriteEndDocument();
                    XmlDocument document = new XmlDocument();
                    document.LoadXml(writer.ToString());
                    detail = document.DocumentElement;
                }
            }
            return(new SoapException(this.Message, this.FaultCode, string.Empty, string.Empty, detail, new SoapFaultSubCode(new XmlQualifiedName(base.GetType().Name)), null));
        }
コード例 #7
0
        /// <summary>
        /// This is the one where all the magic starts.  Main() so to speak.  I will load the settings, connect to TFS and apply the aggregation rules.
        /// </summary>
        public EventNotificationStatus ProcessEvent(
            IVssRequestContext requestContext,
            NotificationType notificationType,
            object notificationEventArgs,
            out int statusCode,
            out string statusMessage,
            out ExceptionPropertyCollection properties)
        {
            var logger  = new ServerEventLogger(GetDefaultLoggingLevel());
            var context = new RequestContextWrapper(requestContext, notificationType, notificationEventArgs);
            var runtime = RuntimeContext.GetContext(
                GetServerSettingsFullPath,
                context,
                logger,
                (runtimeContext) => new WorkItemRepository(runtimeContext),
                (runtimeContext) => new ScriptLibrary(runtimeContext));

            if (runtime.HasErrors)
            {
                statusCode    = 99;
                statusMessage = string.Join(". ", runtime.Errors);
                properties    = null;
                return(EventNotificationStatus.ActionPermitted);
            }

            var result = new ProcessingResult();

            try
            {
                // Check if we have a workitem changed event before proceeding
                if (notificationType == NotificationType.Notification && notificationEventArgs is WorkItemChangedEvent)
                {
                    using (EventProcessor eventProcessor = new EventProcessor(runtime))
                    {
                        logger.StartingProcessing(context, context.Notification);
                        result = eventProcessor.ProcessEvent(context, context.Notification);
                        logger.ProcessingCompleted(result);
                    }
                }
            }
            catch (Exception e)
            {
                logger.ProcessEventException(e);

                // notify failure
                result.StatusCode         = -1;
                result.StatusMessage      = "Unexpected error: " + e.Message;
                result.NotificationStatus = EventNotificationStatus.ActionPermitted;
            }

            statusCode    = result.StatusCode;
            statusMessage = result.StatusMessage;
            properties    = result.ExceptionProperties;
            return(result.NotificationStatus);
        }
コード例 #8
0
        /// <summary>
        /// This is the one where all the magic starts.  Main() so to speak.  I will load the settings, connect to TFS and apply the aggregation rules.
        /// </summary>
        public EventNotificationStatus ProcessEvent(
            IVssRequestContext requestContext,
            NotificationType notificationType,
            object notificationEventArgs,
            out int statusCode,
            out string statusMessage,
            out ExceptionPropertyCollection properties)
        {
            var logger = new ServerEventLogger(LogLevel.Normal);
            var context = new RequestContextWrapper(requestContext, notificationType, notificationEventArgs);
            var runtime = RuntimeContext.GetContext(
                GetServerSettingsFullPath,
                context,
                logger,
                (collectionUri, toImpersonate, logEvents) =>
                    new WorkItemRepository(collectionUri, toImpersonate, logEvents));

            if (runtime.HasErrors)
            {
                statusCode = 99;
                statusMessage = string.Join(". ", runtime.Errors);
                properties = null;
                return EventNotificationStatus.ActionPermitted;
            }

            var result = new ProcessingResult();
            try
            {
                // Check if we have a workitem changed event before proceeding
                if (notificationType == NotificationType.Notification && notificationEventArgs is WorkItemChangedEvent)
                {
                    using (EventProcessor eventProcessor = new EventProcessor(runtime))
                    {
                        logger.StartingProcessing(context, context.Notification);
                        result = eventProcessor.ProcessEvent(context, context.Notification);
                        logger.ProcessingCompleted(result);
                    }
                }
            }
            catch (Exception e)
            {
                logger.ProcessEventException(e);

                // notify failure
                result.StatusCode = -1;
                result.StatusMessage = "Unexpected error: " + e.Message;
                result.NotificationStatus = EventNotificationStatus.ActionPermitted;
            }

            statusCode = result.StatusCode;
            statusMessage = result.StatusMessage;
            properties = result.ExceptionProperties;
            return result.NotificationStatus;
        }
コード例 #9
0
        public EventNotificationStatus ProcessEvent(IVssRequestContext requestContext, NotificationType notificationType, object notificationEventArgs, out int statusCode, out string statusMessage, out ExceptionPropertyCollection properties)
        {
            statusCode = 0;
            statusMessage = string.Empty;
            properties = null;

            Logger.Log("notificationType: " + notificationType);
            Logger.Log("event: " + notificationEventArgs.GetType());
            Logger.Log("eventargs", notificationEventArgs);

            return EventNotificationStatus.ActionApproved;
        }
コード例 #10
0
        /// <summary>
        /// Processes the event.
        /// </summary>
        /// <param name="requestContext">The request context.</param>
        /// <param name="notificationType">Type of the notification.</param>
        /// <param name="notificationEventArgs">The notification event args.</param>
        /// <param name="statusCode">The status code.</param>
        /// <param name="statusMessage">The status message.</param>
        /// <param name="properties">The properties.</param>
        /// <returns></returns>
        public EventNotificationStatus ProcessEvent(
            TeamFoundationRequestContext requestContext,
            NotificationType notificationType,
            object notificationEventArgs,
            out int statusCode,
            out string statusMessage,
            out ExceptionPropertyCollection properties)
        {
            statusCode    = 0;
            statusMessage = "TFSEventWorkflow executed successfully";
            properties    = null;

            // we only handle notifications
            if (notificationType != NotificationType.Notification)
            {
                return(EventNotificationStatus.ActionPermitted);
            }

            string strConfigFile = this.workflowRunner.ExecutionPath.FullName + ".config";

            XmlConfigurator.Configure(new Uri(strConfigFile));

            if (notificationEventArgs.GetType() == typeof(WorkItemChangedEvent))
            {
                // run workflow asynchronously in a TFS job

                var workItemChangedEvent = (WorkItemChangedEvent)notificationEventArgs;

                var xmlData = WorkItemChangedEventSerializer.SerializeXml(workItemChangedEvent);

                this.LogInfo(string.Format("Queuing Job for WorkitemChangedEvent"));

                // Handle the notification by queueing the information we need for a job
                var jobService = requestContext.GetService <TeamFoundationJobService>();
                jobService.QueueOneTimeJob(
                    requestContext,
                    "TFSEventWorkflow Job",
                    "artiso.TFSEventWorkflows.TFSEventWorkflowsServerPlugin.WorkflowRunnerJob",
                    xmlData,
                    false);
            }
            else
            {
                // run workflow synchronously in the Server PLugin itself
                return(this.workflowRunner.ProcessEvent(requestContext, notificationEventArgs));
            }

            return(EventNotificationStatus.ActionPermitted);
        }
コード例 #11
0
        /// <summary>
        /// Processes the event.
        /// </summary>
        /// <param name="requestContext">The request context.</param>
        /// <param name="notificationType">Type of the notification.</param>
        /// <param name="notificationEventArgs">The notification event args.</param>
        /// <param name="statusCode">The status code.</param>
        /// <param name="statusMessage">The status message.</param>
        /// <param name="properties">The properties.</param>
        /// <returns></returns>
        public EventNotificationStatus ProcessEvent(
            TeamFoundationRequestContext requestContext,
            NotificationType notificationType,
            object notificationEventArgs,
            out int statusCode,
            out string statusMessage,
            out ExceptionPropertyCollection properties)
        {
            statusCode    = 0;
            statusMessage = "TFSEventWorkflow executed successfully";
            properties    = null;


            // run workflow synchronously in the Server Plugin itself
            return(this.workflowRunner.ProcessEvent(requestContext, notificationType, notificationEventArgs, PluginConfig.Config.InJobAgent, false));
        }
        public EventNotificationStatus ProcessEvent(
            IVssRequestContext requestContext,
            NotificationType notificationType,
            object notificationEventArgs,
            out int statusCode,
            out string statusMessage,
            out ExceptionPropertyCollection properties)
        {
            statusCode    = 0;
            statusMessage = string.Empty;
            properties    = null;

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

                var repositoryService = requestContext.GetService <ITeamFoundationGitRepositoryService>();

                using (var gitRepository = repositoryService.FindRepositoryById(
                           requestContext,
                           pushNotification.RepositoryId))
                {
                    // TODO: gitRepository.Name should probably equal "Estream". Company wide TFS instance!
                    // TODO: Also, this name should not be hard coded and should be a collection.

                    foreach (var item in pushNotification.IncludedCommits)
                    {
                        var gitCommit = (TfsGitCommit)gitRepository.LookupObject(item);

                        var comment = gitCommit.GetComment(requestContext);

                        if (!CommitRules.IsCommitAcceptable(comment))
                        {
                            statusMessage =
                                $"Non-merge commits must contain links to TFS (i.e. #12345) [Repository Name: {gitRepository.Name}].";
                            return(EventNotificationStatus.ActionDenied);
                        }
                    }
                }
            }

            return(EventNotificationStatus.ActionApproved);
        }
コード例 #13
0
        public EventNotificationStatus ProcessEvent(IVssRequestContext requestContext, NotificationType notificationType, object notificationEventArgs, out int statusCode, out string statusMessage, out ExceptionPropertyCollection properties)
        {
            requestContext.MapAndLoadCustomConfig();

            statusCode    = 0;
            properties    = null;
            statusMessage = String.Empty;
            var logMessage = "New Changeset was checked in by {0}. ID: {1}, comments: {2}";

            try
            {
                if (notificationType == NotificationType.Notification && notificationEventArgs is CheckinNotification)
                {
                    var checkinNotification = notificationEventArgs as CheckinNotification;

                    var checkinNotificationModel = checkinNotification.ToCheckinNotificationModel(requestContext);

                    if (checkinNotificationModel.ContainsValidJiraIssueId())
                    {
                        TeamFoundationApplicationCore.Log(
                            message: string.Format(logMessage, checkinNotificationModel.AuthorName, checkinNotificationModel.ChangesetId, checkinNotificationModel.Comment),
                            eventId: 123,
                            level: System.Diagnostics.EventLogEntryType.Information);

                        var jiraLinkRequests = checkinNotificationModel.CreateJiraIssueLinkRequests();

                        foreach (var request in jiraLinkRequests)
                        {
                            jiraIssueRemoteLinkService.CreateRemoteLinkToIssue(request);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                TeamFoundationApplicationCore.Log("Sample.SourceControl.Server.PlugIns.CodeCheckInEventHandler encountered an exception \n Exception:" + ex.ToString(), 123, System.Diagnostics.EventLogEntryType.Error);
            }
            return(EventNotificationStatus.ActionPermitted);
        }
コード例 #14
0
        /// <summary>
        /// This is the one where all the magic starts.  Main() so to speak.  I will load the settings, connect to TFS and apply the aggregation rules.
        /// </summary>
        public EventNotificationStatus ProcessEvent(
            TeamFoundationRequestContext requestContext,
            NotificationType notificationType,
            object notificationEventArgs,
            out int statusCode,
            out string statusMessage,
            out ExceptionPropertyCollection properties)
        {
            var runtime = RuntimeContext.GetContext(
                GetServerSettingsFullPath,
                new RequestContextWrapper(requestContext),
                new ServerEventLogger(LogLevel.Normal));

            if (runtime.HasErrors)
            {
                statusCode = 99;
                statusMessage = string.Join(". ", runtime.Errors);
                properties = null;
                return EventNotificationStatus.ActionPermitted;
            }

            // HACK: remove cast for ProcessEventException
            var logger = (ServerEventLogger)runtime.Logger;

            var result = new ProcessingResult();
            try
            {
                // Check if we have a workitem changed event before proceeding
                if (notificationType == NotificationType.Notification && notificationEventArgs is WorkItemChangedEvent)
                {
                    var uri = this.GetCollectionUriFromContext(requestContext);

                    IdentityDescriptor toImpersonate = null;
                    if (runtime.Settings.AutoImpersonate)
                    {
                        toImpersonate = this.GetIdentityToImpersonate(requestContext, notificationEventArgs as WorkItemChangedEvent);
                    }

                    using (EventProcessor eventProcessor = new EventProcessor(uri.AbsoluteUri, toImpersonate, runtime))
                    {
                        var context = runtime.RequestContext;
                        var notification = new NotificationWrapper(
                            notificationType,
                            notificationEventArgs as WorkItemChangedEvent);

                        logger.StartingProcessing(context, notification);
                        result = eventProcessor.ProcessEvent(context, notification);
                        logger.ProcessingCompleted(result);
                    }
                }
            }
            catch (Exception e)
            {
                logger.ProcessEventException(e);

                // notify failure
                result.StatusCode = -1;
                result.StatusMessage = "Unexpected error: " + e.Message;
                result.NotificationStatus = EventNotificationStatus.ActionPermitted;
            }

            statusCode = result.StatusCode;
            statusMessage = result.StatusMessage;
            properties = result.ExceptionProperties;
            return result.NotificationStatus;
        }
コード例 #15
0
        /// <summary>
        /// This is the one where all the magic starts.  Main() so to speak.  I will load the settings, connect to tfs and apply the aggregation rules.
        /// </summary>
        public EventNotificationStatus ProcessEvent(TeamFoundationRequestContext requestContext, NotificationType notificationType, object notificationEventArgs,
                                                    out int statusCode, out string statusMessage, out ExceptionPropertyCollection properties)
        {
            var result = new ProcessingResult();

            try
            {
                //Check if we have a workitem changed event before proceeding
                if (notificationType == NotificationType.Notification && notificationEventArgs is WorkItemChangedEvent)
                {
                    var context      = new RequestContextWrapper(requestContext);
                    var notification = new NotificationWrapper(notificationType, notificationEventArgs as WorkItemChangedEvent);
                    result = eventProcessor.ProcessEvent(context, notification);
                }
            }
            catch (Exception e)
            {
                string message = String.Format("Exception encountered processing notification: {0} \nStack Trace:{1}", e.Message, e.StackTrace);
                if (e.InnerException != null)
                {
                    message += String.Format("\n    Inner Exception: {0} \nStack Trace:{1}", e.InnerException.Message, e.InnerException.StackTrace);
                }
                MiscHelpers.LogMessage(message, true);
            }

            statusCode    = result.StatusCode;
            statusMessage = result.StatusMessage;
            properties    = result.ExceptionProperties;
            return(result.NotificationStatus);
        }
コード例 #16
0
        public EventNotificationStatus ProcessEvent(TeamFoundationRequestContext requestContext,
                                                    NotificationType notificationType,
                                                    object notificationEventArgs,
                                                    out int statusCode,
                                                    out string statusMessage,
                                                    out ExceptionPropertyCollection properties)
        {
            statusCode    = 0;
            properties    = null;
            statusMessage = String.Empty;

            // TODO: Make impact on performance minimal by optimize logic for understanding if we are interested
            // in this event or not. Also put longer running task in Jobs. For now - do basic checks.

            if (notificationType != NotificationType.Notification)
            {
                return(EventNotificationStatus.ActionPermitted);
            }
            var notification = notificationEventArgs as WorkItemChangedEvent;

            if (notification == null)
            {
                return(EventNotificationStatus.ActionPermitted);
            }

            // Should not thow exception - if so, the code will be disabled by TFS.
            try
            {
                // Init adapter - will only be done once per deployment of plugin
                if (!HandlerSettings.initFromFile())
                {
                    // Fatal error when trying to init - return
                    // TODO: How allow retry without server restart or re-deploy of plugin?
                    return(EventNotificationStatus.ActionPermitted);
                }

                // Handle case where event is fired because of Save we initiated.
                if (ignoreSaveEvent(notification))
                {
                    return(EventNotificationStatus.ActionPermitted);
                }

                int workItemId = notification.CoreFields.IntegerFields[0].NewValue;
                HandlerSettings.LogMessage(
                    String.Format(
                        "WorkItem with id {0} named '{1}' was saved.",
                        "" + workItemId,
                        notification.WorkItemTitle),
                    HandlerSettings.LoggingLevel.INFO);

                // TODO: In examples I have seen you get actual WI by process below, i.e. opening a new connection to TFS.
                // I would expect as we already are in the context of a TFS you somehow could use this. Note: There is a
                // WorkItem class in the namespace Microsoft.TeamFoundation.WorkItemTracking.Server - no documentation found.

                Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem workItem = getStore().GetWorkItem(workItemId);

                // If a new item is based on an existing (copied) we need to reset the connection to any existing TR.
                // Note exception if item is created by the functional user. This to allow test case where TR is set
                // by test case code.
                String user = HandlerSettings.GetSignumForChangeNotification(workItem, notification);
                if (notification.ChangeType == ChangeTypes.New)
                {
                    if (!user.Equals(HandlerSettings.TFSProviderUser, StringComparison.OrdinalIgnoreCase))
                    {
                        // Note: Will not save - done in event handling or at end.
                        ECRMapper.disconnectBug(workItem);
                    }
                }

                ProductMapper.EventType eventType =
                    ProductMapper.getInstance().GetEventType(workItem, notification, user);

                if (eventType == ProductMapper.EventType.CreateUpdate)
                {
                    // Handle the event as the release is for a maintenance product
                    RESTCallHandler.getHandler().handleEvent(workItem, user, notification);
                }
                else if (eventType == ProductMapper.EventType.Disconnect)
                {
                    // Handle the event as the release is for a maintenance product
                    RESTCallHandler.getHandler().handleDisconnectEvent(workItem, user, notification);
                }
                else
                {
                    HandlerSettings.LogMessage(
                        String.Format(
                            "WorkItem with id {0} save event was ignored by integration.",
                            "" + workItemId),
                        HandlerSettings.LoggingLevel.INFO);
                }

                // If updated but not saved, we need to explicitly call save. Very unusual case but will happen
                // e.g. if item is copied with a product value that before was in maintenance but now not. Then
                // code to disconnect bug is called, but event not handled or Bug saved, hence save here.
                if (workItem.IsDirty)
                {
                    RESTCallHandler.getHandler().saveBug(workItem);
                }
            }
            catch (Exception ex)
            {
                // Error when reading mapping file - assume fatal
                HandlerSettings.LogMessage(
                    "Error when handling the change of workitem." +
                    "\nError: " + ex.Message +
                    "\nStack: " + ex.StackTrace,
                    HandlerSettings.LoggingLevel.ERROR);
            }
            return(EventNotificationStatus.ActionPermitted);
        }
コード例 #17
0
        public EventNotificationStatus ProcessEvent(IVssRequestContext requestContext, NotificationType notificationType, object notificationEventArgs, out int statusCode, out string statusMessage, out ExceptionPropertyCollection properties)
        {
            statusCode    = 0;
            statusMessage = string.Empty;
            properties    = null;

            Logger.Log("notificationType: " + notificationType);
            Logger.Log("event: " + notificationEventArgs.GetType());
            Logger.Log("eventargs", notificationEventArgs);

            return(EventNotificationStatus.ActionApproved);
        }
コード例 #18
0
        /// <summary>
        /// This is the one where all the magic starts.  Main() so to speak.  I will load the settings, connect to tfs and apply the aggregation rules.
        /// </summary>
        public EventNotificationStatus ProcessEvent(TeamFoundationRequestContext requestContext, NotificationType notificationType, object notificationEventArgs,
                                                    out int statusCode, out string statusMessage, out ExceptionPropertyCollection properties)
        {
            statusCode    = 0;
            properties    = null;
            statusMessage = String.Empty;
            int    currentAggregationId   = 0;
            int    workItemId             = 0;
            string currentAggregationName = string.Empty;

            try
            {
                if (notificationType == NotificationType.Notification && notificationEventArgs is WorkItemChangedEvent)
                {
                    // Change this object to be a type we can easily get into
                    WorkItemChangedEvent ev = notificationEventArgs as WorkItemChangedEvent;
                    // Connect to the setting file and load the location of the TFS server
                    string tfsUri = TFSAggregatorSettings.TFSUri;
                    // Connect to TFS so we are ready to get and send data.
                    Store store = new Store(tfsUri);
                    // Get the id of the work item that was just changed by the user.
                    workItemId = ev.CoreFields.IntegerFields[0].NewValue;
                    // Download the work item so we can update it (if needed)
                    WorkItem        eventWorkItem    = store.Access.GetWorkItem(workItemId);
                    string          workItemTypeName = eventWorkItem.Type.Name;
                    List <WorkItem> workItemsToSave  = new List <WorkItem>();

                    if (TFSAggregatorSettings.LoggingIsEnabled)
                    {
                        MiscHelpers.LogMessage(String.Format("Change detected to {0} [{1}]", workItemTypeName, workItemId));
                        MiscHelpers.LogMessage(String.Format("{0}Processing {1} AggregationItems", "  ", TFSAggregatorSettings.ConfigAggregatorItems.Count.ToString()));
                    }

                    // Apply the aggregation rules to the work item
                    foreach (ConfigAggregatorItem configAggregatorItem in TFSAggregatorSettings.ConfigAggregatorItems)
                    {
                        IEnumerable <WorkItem> sourceWorkItems = null;
                        WorkItem targetWorkItem = null;
                        currentAggregationName = configAggregatorItem.Name;

                        // Check to make sure that the rule applies to the work item type we have
                        if (eventWorkItem.Type.Name == configAggregatorItem.WorkItemType)
                        {
                            if (TFSAggregatorSettings.LoggingIsEnabled)
                            {
                                MiscHelpers.LogMessage(String.Format("{0}[Entry {2}] Aggregation '{3}' applies to {1} work items", "    ", workItemTypeName, currentAggregationId, currentAggregationName));
                            }

                            // Use the link type to see what the work item we are updating is
                            if (configAggregatorItem.LinkType == ConfigLinkTypeEnum.Self)
                            {
                                // We are updating the same workitem that was sent in the event.
                                sourceWorkItems = new List <WorkItem> {
                                    eventWorkItem
                                };
                                targetWorkItem = eventWorkItem;

                                if (TFSAggregatorSettings.LoggingIsEnabled)
                                {
                                    MiscHelpers.LogMessage(String.Format("{0}{0}{0}Aggregation applies to SELF. ({1} {2})", "  ", workItemTypeName, workItemId));
                                }

                                // Make sure that all conditions are true before we do the aggregation
                                // If any fail then we don't do this aggregation.
                                if (!configAggregatorItem.Conditions.AreAllConditionsMet(targetWorkItem))
                                {
                                    if (TFSAggregatorSettings.LoggingIsEnabled)
                                    {
                                        MiscHelpers.LogMessage(String.Format("{0}{0}All conditions for aggregation are not met.", "    "));
                                    }
                                    currentAggregationId++;
                                    continue;
                                }

                                if (TFSAggregatorSettings.LoggingIsEnabled)
                                {
                                    MiscHelpers.LogMessage(String.Format("{0}{0}All conditions for aggregation are met.", "    "));
                                }
                            }
                            // We are aggregating to the parent
                            else if (configAggregatorItem.LinkType == ConfigLinkTypeEnum.Parent)
                            {
                                bool parentLevelFound = true;

                                // Go up the tree till we find the level of parent that we are looking for.
                                WorkItem iterateToParent = eventWorkItem;
                                for (int i = 0; i < configAggregatorItem.LinkLevel; i++)
                                {
                                    // Load the parent from the saved list (if we have it in there) or just load it from the store.
                                    WorkItem nullCheck = iterateToParent.GetParentFromListOrStore(workItemsToSave, store);
                                    //
                                    if (nullCheck != null)
                                    {
                                        iterateToParent = nullCheck;
                                    }
                                    else
                                    {
                                        parentLevelFound = false;
                                    }
                                }
                                // If we did not find the correct parent then we are done with this aggregation.
                                if (!parentLevelFound)
                                {
                                    if (TFSAggregatorSettings.LoggingIsEnabled)
                                    {
                                        MiscHelpers.LogMessage(String.Format("{0}{0}{0}Couldn't find a PARENT {2} {4} up from {3} [{1}]. This aggregation will not continue.", "  ", workItemId, configAggregatorItem.LinkLevel, workItemTypeName, configAggregatorItem.LinkLevel > 1 ? "levels" : "level"));
                                    }
                                    currentAggregationId++;
                                    continue;
                                }

                                if (TFSAggregatorSettings.LoggingIsEnabled)
                                {
                                    MiscHelpers.LogMessage(String.Format("{0}{0}{0}Found {1} [{2}] {3} {4} up from {5} [{6}].  Aggregation continues.", "  ", iterateToParent.Type.Name, iterateToParent.Id, configAggregatorItem.LinkLevel, configAggregatorItem.LinkLevel > 1 ? "levels" : "level", workItemTypeName, workItemId));
                                }

                                targetWorkItem = iterateToParent;

                                // Make sure that all conditions are true before we do the aggregation
                                // If any fail then we don't do this aggregation.
                                if (!configAggregatorItem.Conditions.AreAllConditionsMet(targetWorkItem))
                                {
                                    if (TFSAggregatorSettings.LoggingIsEnabled)
                                    {
                                        MiscHelpers.LogMessage(String.Format("{0}{0}All conditions for parent aggregation are not met", "    "));
                                    }
                                    currentAggregationId++;
                                    continue;
                                }

                                if (TFSAggregatorSettings.LoggingIsEnabled)
                                {
                                    MiscHelpers.LogMessage(String.Format("{0}{0}All conditions for parent aggregation are met", "    "));
                                }

                                // Get the children down how ever many link levels were specified.
                                List <WorkItem> iterateFromParents = new List <WorkItem> {
                                    targetWorkItem
                                };
                                for (int i = 0; i < configAggregatorItem.LinkLevel; i++)
                                {
                                    List <WorkItem> thisLevelOfKids = new List <WorkItem>();
                                    // Iterate all the parents to find the children of current set of parents
                                    foreach (WorkItem iterateFromParent in iterateFromParents)
                                    {
                                        thisLevelOfKids.AddRange(iterateFromParent.GetChildrenFromListOrStore(workItemsToSave, store));
                                    }

                                    iterateFromParents = thisLevelOfKids;
                                }

                                // remove the kids that are not the right type that we are working with
                                ConfigAggregatorItem configAggregatorItemClosure = configAggregatorItem;
                                iterateFromParents.RemoveAll(x => x.Type.Name != configAggregatorItemClosure.WorkItemType);

                                sourceWorkItems = iterateFromParents;
                            }

                            // Do the actual aggregation now
                            bool changeMade = Aggregator.Aggregate(sourceWorkItems, targetWorkItem, configAggregatorItem);

                            // If we made a change then add this work item to the list of items to save.
                            if (changeMade)
                            {
                                // Add the target work item to the list of work items to save.
                                workItemsToSave.AddIfUnique(targetWorkItem);
                            }
                        }
                        else
                        {
                            if (TFSAggregatorSettings.LoggingIsEnabled)
                            {
                                MiscHelpers.LogMessage(String.Format("{0}[Entry {2}] Aggregation '{3}' does not apply to {1} work items", "    ", workItemTypeName, currentAggregationId, currentAggregationName));
                            }
                        }

                        currentAggregationId++;
                    }

                    // Save any changes to the target work items.
                    workItemsToSave.ForEach(x =>
                    {
                        bool isValid = x.IsValid();

                        if (TFSAggregatorSettings.LoggingIsEnabled)
                        {
                            MiscHelpers.LogMessage(String.Format("{0}{0}{0}{1} [{2}] {3} valid to save. {4}",
                                                                 "    ",
                                                                 x.Type.Name,
                                                                 x.Id,
                                                                 isValid ? "IS" : "IS NOT",
                                                                 String.Format("\n{0}{0}{0}{0}Invalid fields: {1}", "    ", MiscHelpers.GetInvalidWorkItemFieldsList(x).ToString())));
                        }

                        if (isValid)
                        {
                            x.PartialOpen();
                            x.Save();
                        }
                    });

                    MiscHelpers.AddRunSeparatorToLog();
                }
            }
            catch (Exception e)
            {
                string message = String.Format("Exception encountered processing Work Item [{2}]: {0} \nStack Trace:{1}", e.Message, e.StackTrace, workItemId);
                if (e.InnerException != null)
                {
                    message += String.Format("\n    Inner Exception: {0} \nStack Trace:{1}", e.InnerException.Message, e.InnerException.StackTrace);
                }
                MiscHelpers.LogMessage(message, true);
            }

            return(EventNotificationStatus.ActionPermitted);
        }
コード例 #19
0
        public EventNotificationStatus ProcessEvent(TeamFoundationRequestContext requestContext, NotificationType notificationType, object notificationEventArgs,
                                                    out int statusCode, out string statusMessage, out ExceptionPropertyCollection properties)
        {
            statusCode    = 0;
            properties    = null;
            statusMessage = String.Empty;

            try
            {
                if (notificationType == NotificationType.DecisionPoint && notificationEventArgs is CheckinNotification)
                {
                    CheckinNotification ev = notificationEventArgs as CheckinNotification;
                    if (ev != null && ev.PolicyOverrideInfo != null)
                    {
                        if (ev.PolicyOverrideInfo.PolicyFailures != null)
                        {
                            // One or more of the checkin policies have been overridden
                            // If all the files being checked in are in the published folder, then allow overridding the policies since those are installation packages
                            foreach (string file in ev.GetSubmittedItems(null))
                            {
                                if (!Regex.IsMatch(file, @"/published", RegexOptions.IgnoreCase) &&
                                    !Regex.IsMatch(Path.GetDirectoryName(file), @"/published", RegexOptions.IgnoreCase))
                                {
                                    statusCode = -1;
                                    break;
                                }
                            }
                            if (statusCode != 0)
                            {
                                // One or more of the checkin policies have been overridden and not all files are installation files (in the published folder)
                                statusMessage = Resource.CheckinCancelledStatusMessage;
                                foreach (PolicyFailureInfo policy in ev.PolicyOverrideInfo.PolicyFailures)
                                {
                                    statusMessage = String.Concat(statusMessage, "\n    > ", policy.PolicyName, ": ", policy.Message);
                                }
                                return(EventNotificationStatus.ActionDenied);
                            }
                        }
                    }
                    return(EventNotificationStatus.ActionPermitted);
                }
            }
            catch (Exception exception)
            {
                // decide what you want to do, if exception occurs
            }
            return(EventNotificationStatus.ActionPermitted);
        }
コード例 #20
0
        /// <summary>
        /// This is the one where all the magic starts.  Main() so to speak.  I will load the settings, connect to TFS and apply the aggregation rules.
        /// </summary>
        public EventNotificationStatus ProcessEvent(
            TeamFoundationRequestContext requestContext,
            NotificationType notificationType,
            object notificationEventArgs,
            out int statusCode,
            out string statusMessage,
            out ExceptionPropertyCollection properties)
        {
            var runtime = RuntimeContext.GetContext(
                GetServerSettingsFullPath,
                new RequestContextWrapper(requestContext),
                new ServerEventLogger(LogLevel.Normal));

            if (runtime.HasErrors)
            {
                statusCode    = 99;
                statusMessage = string.Join(". ", runtime.Errors);
                properties    = null;
                return(EventNotificationStatus.ActionPermitted);
            }

            // HACK: remove cast for ProcessEventException
            var logger = (ServerEventLogger)runtime.Logger;

            var result = new ProcessingResult();

            try
            {
                // Check if we have a workitem changed event before proceeding
                if (notificationType == NotificationType.Notification && notificationEventArgs is WorkItemChangedEvent)
                {
                    var uri = this.GetCollectionUriFromContext(requestContext);

                    IdentityDescriptor toImpersonate = null;
                    if (runtime.Settings.AutoImpersonate)
                    {
                        toImpersonate = this.GetIdentityToImpersonate(requestContext, notificationEventArgs as WorkItemChangedEvent);
                    }

                    using (EventProcessor eventProcessor = new EventProcessor(uri.AbsoluteUri, toImpersonate, runtime))
                    {
                        var context      = runtime.RequestContext;
                        var notification = new NotificationWrapper(
                            notificationType,
                            notificationEventArgs as WorkItemChangedEvent);

                        logger.StartingProcessing(context, notification);
                        result = eventProcessor.ProcessEvent(context, notification);
                        logger.ProcessingCompleted(result);
                    }
                }
            }
            catch (Exception e)
            {
                logger.ProcessEventException(e);

                // notify failure
                result.StatusCode         = -1;
                result.StatusMessage      = "Unexpected error: " + e.Message;
                result.NotificationStatus = EventNotificationStatus.ActionPermitted;
            }

            statusCode    = result.StatusCode;
            statusMessage = result.StatusMessage;
            properties    = result.ExceptionProperties;
            return(result.NotificationStatus);
        }
コード例 #21
0
        public EventNotificationStatus ProcessEvent(IVssRequestContext requestContext,
                                                    NotificationType notificationType, object notificationEventArgs,
                                                    out int statusCode, out string statusMessage, out ExceptionPropertyCollection properties)
        {
            statusCode    = 0;
            statusMessage = string.Empty;
            properties    = null;

            if (notificationType == NotificationType.DecisionPoint)
            {
                try
                {
                    if (notificationEventArgs is CheckinNotification)
                    {
                        var  notification   = notificationEventArgs as CheckinNotification;
                        bool IsCheckInValid = true;
                        if (String.IsNullOrEmpty(notification.Comment))
                        {
                            statusMessage  = " Check in Comments Cannot Be empty";
                            IsCheckInValid = IsCheckInValid && false;
                        }
                        if (notification.NotificationInfo.WorkItemInfo.Length <= 0)
                        {
                            statusMessage  = "Associate Change set With a Work Item To Check In";
                            IsCheckInValid = IsCheckInValid && false;
                        }
                        if (!IsCheckInValid)
                        {
                            return(EventNotificationStatus.ActionDenied);
                        }
                    }
                }
                catch (Exception e)
                {
                    TeamFoundationApplicationCore.LogException("Check In Validation failed", e);
                }
            }
            return(EventNotificationStatus.ActionPermitted);
        }
コード例 #22
0
        public EventNotificationStatus ProcessEvent(TeamFoundationRequestContext requestContext, NotificationType notificationType, object notificationEventArgs, out int statusCode, out string statusMessage, out ExceptionPropertyCollection properties)
        {
            properties    = null;
            statusCode    = 0;
            statusMessage = null;

            if (notificationType != NotificationType.DecisionPoint)
            {
                return(EventNotificationStatus.ActionApproved);
            }

            var notification = notificationEventArgs as PullRequestNotification;

            if (notification != null)
            {
                var gitPullRequestService = requestContext.GetService <TeamFoundationGitPullRequestService>();
                var gitrepositoryService  = requestContext.GetService <TeamFoundationGitRepositoryService>();
                var pullRequest           = gitPullRequestService.GetPullRequestDetails(requestContext, notification.PullRequestId);
                var repository            = gitrepositoryService.FindRepositoryById(requestContext, pullRequest.RepositoryId);


                var reviews = pullRequest.Reviewers.ToList();
                reviews.Add(new TfsGitPullRequest.ReviewerWithVote(new Guid(), 4, ReviewerVoteStatus.Rejected));
                gitPullRequestService.UpdatePullRequest(requestContext, repository, pullRequest.PullRequestId, pullRequest.Status, pullRequest.Title, pullRequest.Description, reviews);

                var messageBuilder = new StringBuilder();
                messageBuilder.AppendFormat(DateTime.Now.ToShortTimeString());
                messageBuilder.Append(" : ");

                messageBuilder.AppendFormat(@"PullRequestId = {0}", pullRequest.PullRequestId);
                messageBuilder.AppendLine();

                messageBuilder.AppendFormat(@"MergeId = {0}", pullRequest.MergeId);
                messageBuilder.AppendLine();

                messageBuilder.AppendFormat(@"PullRequestId = {0}", pullRequest.SourceBranchName);
                messageBuilder.AppendLine();

                messageBuilder.AppendFormat(@"SourceBranchName = {0}", pullRequest.TargetBranchName);
                messageBuilder.AppendLine();

                messageBuilder.AppendFormat(@"LastMergeCommit = {0}", pullRequest.LastMergeCommit);
                messageBuilder.AppendLine();

                messageBuilder.AppendFormat(@"LastMergeSourceCommit = {0}", pullRequest.LastMergeSourceCommit);
                messageBuilder.AppendLine();

                messageBuilder.AppendFormat(@"LastMergeTargetCommit = {0}", pullRequest.LastMergeTargetCommit);
                messageBuilder.AppendLine();

                messageBuilder.AppendFormat(@"Status = {0}", pullRequest.Status);
                messageBuilder.AppendLine();

                messageBuilder.AppendFormat(@"Title = {0}", pullRequest.Title);
                messageBuilder.AppendLine();

                messageBuilder.AppendFormat(@"MergeStatus = {0}", pullRequest.MergeStatus);
                messageBuilder.AppendLine();

                messageBuilder.AppendFormat(@"CompleteWhenMergedAuthority = {0}", pullRequest.CompleteWhenMergedAuthority);
                messageBuilder.AppendLine();

                messageBuilder.AppendFormat(@"Description = {0}", pullRequest.Description);
                messageBuilder.AppendLine();

                messageBuilder.AppendFormat(@"Creator = {0}", pullRequest.Creator);
                messageBuilder.AppendLine();

                messageBuilder.AppendFormat(@"CreationDate = {0}", pullRequest.CreationDate);
                messageBuilder.AppendLine();
                messageBuilder.AppendLine("==========================================================");


                File.AppendAllText(@"C:\TMP\NPTV_TEST_LOG.txt", messageBuilder.ToString());
            }

            return(EventNotificationStatus.ActionApproved);
        }
        public EventNotificationStatus ProcessEvent(TeamFoundationRequestContext requestContext, NotificationType notificationType, object notificationEventArgs, out int statusCode, out string statusMessage, out ExceptionPropertyCollection properties)
        {
            statusCode    = 0;
            properties    = null;
            statusMessage = string.Empty;
            try
            {
                if (notificationType == NotificationType.Notification && notificationEventArgs is CheckinNotification)
                {
                    var checkinNotification = notificationEventArgs as CheckinNotification;
                    if (ShouldMergeItemsIfNecessary(requestContext, checkinNotification))
                    {
                        var changeset = requestContext.GetChangeset(checkinNotification.Changeset);
                        if (changeset != null)
                        {
                            TfsTeamProjectCollection impersonatedCollection = requestContext.GetImpersonatedCollection(changeset.Committer);
                            MergeWorkItems(impersonatedCollection, changeset.ChangesetId);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                TeamFoundationApplicationCore.LogException("Inmeta.TFS.MergeWorkItemEventHandler encountered an exception", ex);
            }

            return(EventNotificationStatus.ActionPermitted);
        }
コード例 #24
0
 /// <summary>
 /// Recupera as propriedades.
 /// </summary>
 /// <param name="properties"></param>
 protected virtual void GetExceptionProperties(ExceptionPropertyCollection properties)
 {
 }
コード例 #25
0
        /// <summary>
        /// This is the one where all the magic starts.  Main() so to speak.  I will load the settings, connect to tfs and apply the aggregation rules.
        /// </summary>
        public EventNotificationStatus ProcessEvent(TeamFoundationRequestContext requestContext, NotificationType notificationType, object notificationEventArgs,
                                                    out int statusCode, out string statusMessage, out ExceptionPropertyCollection properties)
        {
            statusCode = 0;
            properties = null;
            statusMessage = String.Empty;
            int currentAggregationId = 0;
            int workItemId = 0;
            string currentAggregationName = string.Empty;

            try
            {
                if (notificationType == NotificationType.Notification && notificationEventArgs is WorkItemChangedEvent)
                {
                    // Change this object to be a type we can easily get into
                    WorkItemChangedEvent ev = notificationEventArgs as WorkItemChangedEvent;
                    // Connect to the setting file and load the location of the TFS server
                    string tfsUri = TFSAggregatorSettings.TFSUri;
                    // Connect to TFS so we are ready to get and send data.
                    Store store = new Store(tfsUri);
                    // Get the id of the work item that was just changed by the user.
                    workItemId = ev.CoreFields.IntegerFields[0].NewValue;
                    // Download the work item so we can update it (if needed)
                    WorkItem eventWorkItem = store.Access.GetWorkItem(workItemId);
                    string workItemTypeName = eventWorkItem.Type.Name;
                    List<WorkItem> workItemsToSave = new List<WorkItem>();

                    if (TFSAggregatorSettings.LoggingIsEnabled)
                    {
                        MiscHelpers.LogMessage(String.Format("Change detected to {0} [{1}]", workItemTypeName, workItemId));
                        MiscHelpers.LogMessage(String.Format("{0}Processing {1} AggregationItems", "  ", TFSAggregatorSettings.ConfigAggregatorItems.Count.ToString()));
                    }

                    // Apply the aggregation rules to the work item
                    foreach (ConfigAggregatorItem configAggregatorItem in TFSAggregatorSettings.ConfigAggregatorItems)
                    {
                        IEnumerable<WorkItem> sourceWorkItems = null;
                        WorkItem targetWorkItem = null;
                        currentAggregationName = configAggregatorItem.Name;

                        // Check to make sure that the rule applies to the work item type we have
                        if (eventWorkItem.Type.Name == configAggregatorItem.WorkItemType)
                        {
                            if (TFSAggregatorSettings.LoggingIsEnabled) MiscHelpers.LogMessage(String.Format("{0}[Entry {2}] Aggregation '{3}' applies to {1} work items", "    ", workItemTypeName, currentAggregationId, currentAggregationName));

                            // Use the link type to see what the work item we are updating is
                            if (configAggregatorItem.LinkType == ConfigLinkTypeEnum.Self)
                            {
                                // We are updating the same workitem that was sent in the event.
                                sourceWorkItems = new List<WorkItem> {eventWorkItem};
                                targetWorkItem = eventWorkItem;

                                if (TFSAggregatorSettings.LoggingIsEnabled) MiscHelpers.LogMessage(String.Format("{0}{0}{0}Aggregation applies to SELF. ({1} {2})", "  ", workItemTypeName, workItemId));

                                // Make sure that all conditions are true before we do the aggregation
                                // If any fail then we don't do this aggregation.
                                if (!configAggregatorItem.Conditions.AreAllConditionsMet(targetWorkItem))
                                {
                                    if (TFSAggregatorSettings.LoggingIsEnabled) MiscHelpers.LogMessage(String.Format("{0}{0}All conditions for aggregation are not met.", "    "));
                                    currentAggregationId++;
                                    continue;
                                }

                                if (TFSAggregatorSettings.LoggingIsEnabled) MiscHelpers.LogMessage(String.Format("{0}{0}All conditions for aggregation are met.", "    "));

                            }
                                // We are aggregating to the parent
                            else if (configAggregatorItem.LinkType == ConfigLinkTypeEnum.Parent)
                            {
                                bool parentLevelFound = true;

                                // Go up the tree till we find the level of parent that we are looking for.
                                WorkItem iterateToParent = eventWorkItem;
                                for (int i = 0; i < configAggregatorItem.LinkLevel; i++)
                                {

                                    // Load the parent from the saved list (if we have it in there) or just load it from the store.
                                    WorkItem nullCheck = iterateToParent.GetParentFromListOrStore(workItemsToSave, store);
                                    //
                                    if (nullCheck != null)
                                    {
                                        iterateToParent = nullCheck;
                                    }
                                    else
                                        parentLevelFound = false;

                                }
                                // If we did not find the correct parent then we are done with this aggregation.
                                if (!parentLevelFound)
                                {
                                    if (TFSAggregatorSettings.LoggingIsEnabled) MiscHelpers.LogMessage(String.Format("{0}{0}{0}Couldn't find a PARENT {2} {4} up from {3} [{1}]. This aggregation will not continue.", "  ", workItemId, configAggregatorItem.LinkLevel, workItemTypeName, configAggregatorItem.LinkLevel > 1 ? "levels" : "level"));
                                    currentAggregationId++;
                                    continue;
                                }

                                if (TFSAggregatorSettings.LoggingIsEnabled) MiscHelpers.LogMessage(String.Format("{0}{0}{0}Found {1} [{2}] {3} {4} up from {5} [{6}].  Aggregation continues.", "  ", iterateToParent.Type.Name, iterateToParent.Id, configAggregatorItem.LinkLevel, configAggregatorItem.LinkLevel > 1 ? "levels" : "level", workItemTypeName, workItemId));

                                targetWorkItem = iterateToParent;

                                // Make sure that all conditions are true before we do the aggregation
                                // If any fail then we don't do this aggregation.
                                if (!configAggregatorItem.Conditions.AreAllConditionsMet(targetWorkItem))
                                {
                                    if (TFSAggregatorSettings.LoggingIsEnabled) MiscHelpers.LogMessage(String.Format("{0}{0}All conditions for parent aggregation are not met", "    "));
                                    currentAggregationId++;
                                    continue;
                                }

                                if (TFSAggregatorSettings.LoggingIsEnabled) MiscHelpers.LogMessage(String.Format("{0}{0}All conditions for parent aggregation are met", "    "));

                                // Get the children down how ever many link levels were specified.
                                List<WorkItem> iterateFromParents = new List<WorkItem> {targetWorkItem};
                                for (int i = 0; i < configAggregatorItem.LinkLevel; i++)
                                {
                                    List<WorkItem> thisLevelOfKids = new List<WorkItem>();
                                    // Iterate all the parents to find the children of current set of parents
                                    foreach (WorkItem iterateFromParent in iterateFromParents)
                                    {
                                        thisLevelOfKids.AddRange(iterateFromParent.GetChildrenFromListOrStore(workItemsToSave, store));
                                    }

                                    iterateFromParents = thisLevelOfKids;
                                }

                                // remove the kids that are not the right type that we are working with
                                ConfigAggregatorItem configAggregatorItemClosure = configAggregatorItem;
                                iterateFromParents.RemoveAll(x => x.Type.Name != configAggregatorItemClosure.WorkItemType);

                                sourceWorkItems = iterateFromParents;
                            }

                            // Do the actual aggregation now
                            bool changeMade = Aggregator.Aggregate(sourceWorkItems, targetWorkItem, configAggregatorItem);

                            // If we made a change then add this work item to the list of items to save.
                            if (changeMade)
                            {
                                // Add the target work item to the list of work items to save.
                                workItemsToSave.AddIfUnique(targetWorkItem);
                            }
                        }
                        else
                        {
                            if (TFSAggregatorSettings.LoggingIsEnabled) MiscHelpers.LogMessage(String.Format("{0}[Entry {2}] Aggregation '{3}' does not apply to {1} work items", "    ", workItemTypeName, currentAggregationId, currentAggregationName));
                        }

                        currentAggregationId++;
                    }

                    // Save any changes to the target work items.
                    workItemsToSave.ForEach(x =>
                    {
                        bool isValid = x.IsValid();

                        if (TFSAggregatorSettings.LoggingIsEnabled)
                        {
                            MiscHelpers.LogMessage(String.Format("{0}{0}{0}{1} [{2}] {3} valid to save. {4}",
                                                                "    ",
                                                                x.Type.Name,
                                                                x.Id,
                                                                isValid ? "IS" : "IS NOT",
                                                                String.Format("\n{0}{0}{0}{0}Invalid fields: {1}", "    ", MiscHelpers.GetInvalidWorkItemFieldsList(x).ToString())));
                        }

                        if (isValid)
                        {
                            x.PartialOpen();
                            x.Save();
                        }
                    });

                    MiscHelpers.AddRunSeparatorToLog();
                }

            }
            catch (Exception e)
            {
                string message = String.Format("Exception encountered processing Work Item [{2}]: {0} \nStack Trace:{1}", e.Message, e.StackTrace, workItemId);
                if (e.InnerException != null)
                {
                    message += String.Format("\n    Inner Exception: {0} \nStack Trace:{1}", e.InnerException.Message, e.InnerException.StackTrace);
                }
                MiscHelpers.LogMessage(message, true);
            }

            return EventNotificationStatus.ActionPermitted;
        }
コード例 #26
0
        public EventNotificationStatus ProcessEvent(IVssRequestContext requestContext,
                                                    NotificationType notificationType, object notificationEventArgs,
                                                    out int statusCode, out string statusMessage, out ExceptionPropertyCollection properties)
        {
            statusCode    = 0;
            statusMessage = string.Empty;
            properties    = null;

            if (notificationType == NotificationType.Notification)
            {
                try
                {
                    if (notificationEventArgs is CheckinNotification)
                    {
                        var           notification = notificationEventArgs as CheckinNotification;
                        StringBuilder logMessage   = new StringBuilder();
                        logMessage.Append("\n***************************************\r\n");
                        logMessage.Append("New Check-in Done, Change set Details:-\r\n");
                        logMessage.AppendFormat("ChangeSet Id:{0}\r\n", notification.Changeset);
                        logMessage.AppendFormat("ChangeSet Description:{0}\r\n", notification.Comment);
                        logMessage.AppendFormat("Checked-in User:{0}\r\n", notification.ChangesetOwner.DistinctDisplayName);
                        logMessage.AppendFormat("Machine Name:{0}\r\n", notification.ComputerName);
                        logMessage.AppendFormat("Associated Work Items:{0}\r\n", notification.NotificationInfo.WorkItemInfo.Length);
                        StringBuilder workitems = new StringBuilder();
                        if (notification.NotificationInfo.WorkItemInfo.Length > 0)
                        {
                            for (int workitemindex = 0; workitemindex < notification.NotificationInfo.WorkItemInfo.Length; workitemindex++)
                            {
                                workitems.AppendFormat("{0},", notification.NotificationInfo.WorkItemInfo[0].Id);
                            }
                        }
                        logMessage.Append("\n***************************************");
                        VersionControlLogger.LogToFile(logMessage.ToString());
                    }
                }
                catch (Exception e)
                {
                    TeamFoundationApplicationCore.LogException("logger failed", e);
                }
            }
            return(EventNotificationStatus.ActionPermitted);
        }