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; } }
/// <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; }
/// <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) { } } }
public ProcessingResult() { StatusCode = 0; ExceptionProperties = new ExceptionPropertyCollection(); StatusMessage = String.Empty; NotificationStatus = EventNotificationStatus.ActionPermitted; }
/// <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)); }
/// <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); }
/// <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; }
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; }
/// <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); }
/// <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); }
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); }
/// <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; }
/// <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); }
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); }
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); }
/// <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); }
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); }
/// <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); }
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); }
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); }
/// <summary> /// Recupera as propriedades. /// </summary> /// <param name="properties"></param> protected virtual void GetExceptionProperties(ExceptionPropertyCollection properties) { }
/// <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; }
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); }