Team Foundation Server 2010 – Eventing Service - Subscribing to events

Posted by: Subodh Sohoni , on 6/10/2009, in Category Visual Studio, VSTS & TFS
Views: 52984
Abstract: Visual Studio Team System exposes number of opportunities to extend its features and functionality. Responding to events published by the Team Foundation Server (TFS) is one of the extensibility opportunities which may be used most extensively. In this two part series, we will take an overview of the events raised by TFS and how to subscribe to those events. This article is an update on my earlier article which I had written for TFS 2008. This article will cover the specifics required for TFS 2010 (at this moment Beta 1) as compared to TFS 2008.
Team Foundation Server 2010 – Eventing Service - Subscribing to events
Visual Studio Team System exposes number of opportunities to extend its features and functionality. Responding to events published by the Team Foundation Server (TFS) is one of the extensibility opportunities which may be used most extensively. TFS is a hive of activities related to configuration management, source control, work item tracking, builds etc. These activities can be treated as events and it is possible to write event handlers for many of these events. By handling such events we will be able to automate the tasks related to management of the project. For example, we can subscribe to Checkin event where the subscribing webservice will set the status of associated workitems to a custom value. Another example can be of creating a installer for output of build once the build completion event fires. A very interesting case could be to spawn workitems say of the type tasks in response to event of creation of other type of workitem like a scenario and link the spawned workitems to the scenario like workitem.
This article discusses:
-          The events raised by TFS
-          Using BisSubscribe.exe
-          Filtering the events
-          How a subscription can be created for an email
-          How to create a subscription for a webservice
-          Creating a subscription programmatically
This article is an update on my earlier article which I had written for TFS 2008 Team Foundation Server – Eventing Service - Part 1 (Subscribing to events). This article will cover the specifics required for TFS 2010 (at this moment Beta 1) as compared to TFS 2008.
Subscribing to events
 TFS uses implementation of publisher – subscriber paradigm in which certain registered events are published when they are raised. Notification of those events, as and when they are raised, is made to the subscribers. TFS registers the subscription in its database. The process of registering a subscription for an event can be done either using a command line tool named BisSubscribe.exe or it can be done programmatically using the Team Foundation Object Model that is published by Microsoft. Subscriptions can be of two types. First type of subscription is an email subscription in which a preconfigured email is sent to the email address mentioned in the subscription. The second type of subscription is of a webservice which has a method named Notify. A parameter of Notify method provides the event specific data.
List of published events
When TFS is installed, numbers of events are registered for publishing. The list of them is as follows:

Build Completion Event
NodesDeletedEvent
Build Status Changed Event
ProjectCreatedEvent
BranchMovedEvent
ProjectDeletedEvent
NodeCreatedEvent
CheckinEvent
NodePropertiesChangedEvent
WorkItemChanged
NodeRenamedEvent
 

Note: Node related events refer to iterations and areas in the team project.
Table 1
Using BisSubscribe.exe
BisSubscribe.exe is a command line tool available with the installation of TFS. On TFS 2010 it is available at <System Drive>\Program Files\Microsoft Team Foundation Server 2010\Application Tier\Web Services\bin folder. While executing it takes following arguments:
eventType – Type of the event for which the subscription is being made. E.g. CheckinEvent, WorkItemChangedEvent. These names are case sensitive and are as mentioned in the Table 1.
address – Either the email address to which the notification email should be sent E.g. user@domain.com or the URL of the webservice to be called e.g. http://TFS_Name/SubscribingWebService/Service.asmx
deliveryType – This can be either of EmailHtml, EmailPlaintext if the subscription is for email or Soap is the subscription is for webservice method. Soap is taken as the default delivery method.
server  / domain – Name of TFS or http address of the TFS with port number (typically 8080). In TFS 2010, the only acceptable value is complete Uri of TFS, e.g. http://TfsName:8080/Tfs or http://TfsName:8080/Tfs/ProjectCollectionName . By providing the name of the project collection, events can be scoped for that collection only. If any project collection name is not provided then it automatically sets it to Default Project Collection.
filter – Optional filter expression which allows TFS to notify only events which match that filter
 
Filtering the events
Events can be filtered using some criterion in such a way that the events which fulfill that criterion only are notified to the subscriber. TFS uses a special language for setting the filter expressions. This filtering language may contain Event subtypes containing any number of simple fields. For example, E-mail me for Defect events when the ‘Defect Owner field = “user1” AND the Status field <> “Resolved”’”. It may contain normal equality checking operators, =, <>, <,>,<=,>=. It also additionally contains operators for matching with regular expression (Match) or for simple match (Like). An expression can be simple with only one operator or complex with multiple operators and sub expressions. Complex expression is formed with operators like AND, OR e.g. “Team Project = ‘Project 1’ AND PolicyOverrideComment <> ‘’ ”
Creating a email type of subscription
Example of creating an email type of subscription using BisSubscribe.exe tool where email needs to be in plain text would be
 >C:\Program Files\Microsoft Visual Studio 2008 Team Foundation Server\TF Setup\BisSubscribe.exe /eventType BuildCompletionEvent /address tfsservice@vsts.local /deliveryType EmailPlaintext /domain http://tfsrtm:8080
 
>C:\Program Files\Microsoft Team Foundation Server 2010\Application Tier\Web Services\Bin\BisSubscribe.exe /eventType BuildCompletionEvent /address tfsservice@vsts.local /deliveryType EmailPlaintext /server http://tfs2010:8080/Tfs
 
If the email can be in html format with a filter for the Team Project named SEED_Automation then the same command would be
>C:\Program Files\Microsoft Visual Studio 2008 Team Foundation Server\TF Setup\BisSubscribe.exe /eventType BuildCompletionEvent /filter “Team Project=’SEED_Automation’” /address tfsservice@vsts.local /deliveryType EmailHtml /domain http://tfsrtm:8080
 
>C:\Program Files\Microsoft Team Foundation Server 2010\Application Tier\Web Services\Bin\BisSubscribe.exe /eventType BuildCompletionEvent /address tfsservice@vsts.local /deliveryType EmailHtml /server http://tfs2010:8080/Tfs
 
The template which will be used to create the email may look like this:
<html>
 <head><title>TFS Security Subsystem Notification</title></head>
 <body style="font-family:courier new; font-size:12px;">
 <div>An access control list has been changed.</div>
 <br />
 <div>&nbsp;&nbsp;&nbsp;&nbsp;Object ID: <variable name="ObjectId" /></div>
 <div>&nbsp;&nbsp;&nbsp;&nbsp;Action ID: <variable name="ActionId" /></div>
 <div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SID: <variable name="Sid" /></div>
 <div>&nbsp;&nbsp;&nbsp;Entry type: <variable name="EntryType" /></div>
 <div>&nbsp;&nbsp;Change type: <variable name="ChangeType" /></div>
 </body>
</html>
 
It may also be given in the .xsl format. If both are present then the precedence will be given to template.
Creating a subscription for webservice
A webservice which subscribes to an event needs to have a method with following signature:
 C# 
[SoapDocumentMethod(Action="http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03/Notify", RequestNamespace = " http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03")]
      [WebMethod(MessageName=”Notify”)]
      public void Notify(string eventXml)
      {
              //Write your custom code here
              //Use eventXml to extract event related fields and their values
}
 
VB.NET 
<SoapDocumentMethod(Action:=
"http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03/Notify", RequestNamespace := " http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03"), WebMethod(MessageName:=”Notify”)> _
Public Sub Notify(ByVal eventXml As String)
            'Write your custom code here
            'Use eventXml to extract event related fields and their values
End Sub
 Once such a webservice is ready, the subscription can be created with the command
>C:\Program Files\Microsoft Visual Studio 2005 Team Foundation Server\TF Setup\BisSubscribe.exe /eventType BuildCompletionEvent /filter “Team Project=’SEED_Automation’” /address http://TFS_Name/MyWebService/Service.asmx /deliveryType Soap /domain http://tfsrtm:8080
 
>C:\Program Files\Microsoft Team Foundation Server 2010\Application Tier\Web Services\Bin\BisSubscribe.exe /eventType BuildCompletionEvent /address http://SiteName/SubscribingWebServiceName/Service.asmx /deliveryType Soap /server http://tfs2010:8080/Tfs
 
Creating the subscription programmatically
We may create the subscription of all types programmatically instead of using the BisSubscribe tool. The code of the method which adds the subscription may look like this:
 C# 
{
                IEventService eventEndpoint = (IEventService)server.GetService(typeof(IEventService));
                DeliveryPreference delPrev = new DeliveryPreference();
                delPrev.Type = DeliveryType.EmailHtml;
                delPrev.Schedule = DeliverySchedule.Immediate;
                delPrev.Address = txtDeliveryAddress.Text;
                string userId = txtDomain.Text + @"\" + txtUsername.Text;
                eventEndpoint.SubscribeEvent(userId, "CheckinEvent", "TeamProject = '" + cboProject.SelectedItem + "' AND PolicyOverrideComment <> '' ", delPrev);
 }
 
VB.NET
 
     Dim eventEndpoint As IEventService = CType(server.GetService(GetType(IEventService)), IEventService)
     Dim delPrev As New DeliveryPreference()
     delPrev.Type = DeliveryType.EmailHtml
     delPrev.Schedule = DeliverySchedule.Immediate
     delPrev.Address = txtDeliveryAddress.Text
     Dim userId As String = txtDomain.Text & "\" & txtUsername.Text
     eventEndpoint.SubscribeEvent(userId, "CheckinEvent", "TeamProject = '" & cboProject.SelectedItem & "' AND PolicyOverrideComment <> '' ", delPrev)
 
The object model for this code is provided through the components Microsoft.TeamFoundation.dll, Microsoft.TeamFoundation.Client.dll and Microsoft.TeamFoundation.Common.dll.
 
This article provided an overview of how to achieve automation in project management when working with TFS. It described the process for subscribing to the published events using a tool BisSubscribe.exe as well as to do it programmatically. It also shows differences between command syntax for TFS 2008 and TFS 2010.
 
If you liked the article,  Subscribe to the RSS Feed or Subscribe Via Email

Subodh Sohoni is MCTS - Microsoft Team Foundation Server - Configuration and Development and also is a Microsoft Certified Trainer(MCT) since 2004. Subodh works as VP, Technology with SEED Infotech Ltd 
 
Give a +1 to this article if you think it was well written. Thanks!
Recommended Articles
Subodh Sohoni, Team System MVP, is an MCTS – Microsoft Team Foundation Server – Configuration and Development and also is a Microsoft Certified Trainer(MCT) since 2004. Subodh has his own company and conducts a lot of corporate trainings. He is an M.Tech. in Aircraft Production from IIT Madras. He has over 20 years of experience working in sectors like Production, Marketing, Software development and now Software Training. Follow him on twitter @subodhsohoni


Page copy protected against web site content infringement by Copyscape


User Feedback
Comment posted by Gupta on Sunday, March 27, 2011 10:12 AM
I am getting this error when subscribing to WorkItemChangedEvent.

Failed to subscribe event:
Exception Message: Event type WorkItemChanged does not exist. (type TeamFoundationServiceException)

Any idea what I am missing ?
Comment posted by Rottie on Monday, May 9, 2011 4:59 PM
Thank you for an excellent article.  You commented on an HTML template in your article, and I wondered if that was something that can be customized?  Also, could it be called in the command line (to allow a different HTML message based upon user)?  Thanks, again!
Comment posted by Rottie on Tuesday, May 10, 2011 8:21 AM
Thank you for an excellent article.  You commented on an HTML template in your article, and I wondered if that was something that can be customized?  Also, could it be called in the command line (to allow a different HTML message based upon user)?  Thanks, again!
Comment posted by Gordon Doherty on Friday, May 13, 2011 3:10 AM
Hi,

Same as Gupta, I'm getting:

"Failed to subscribe event:
Exception Message: Event type WorkItemChanged does not exist. (type TeamFoundationServiceException)"

Any ideas?

Comment posted by Gilles on Monday, June 6, 2011 4:51 PM
Hi,

To @Gupta and @Gordon Doherty :
did you use "WorkItemChanged" or "WorkItemChangedEvent" in the FilterExpression ?
=> I think, in the "List of published events" table above, the "Event" sufix is missing for WorkItemChangedEvent.

Thank you for this helpful article ;)
Comment posted by Vinod on Wednesday, June 22, 2011 10:11 PM
Hello Subodh,

Is it possible to send email notifications in SOAP formats using TFS 2008 API's, could you provide resolution of how to configure alerts using SOAP etc..

Thanks in advance for info.
Comment posted by Vinod on Wednesday, June 22, 2011 10:20 PM
Hello Subodh,

Is it possible to send email notifications in SOAP formats using TFS 2008 API's, could you provide resolution of how to configure alerts using SOAP etc..

Thanks in advance for info.
Comment posted by Chandan Das on Tuesday, November 8, 2011 2:11 AM
Reading this article is waste of time as it does not work. It says event does not exist form CheckinEvent. Also the author does not reply to comment!
Comment posted by Jay on Monday, February 13, 2012 7:48 AM
Awesome Thing i am so clear and i just want some more from you.
<a href="www.mindscripts.com">Software Testing Institute in pune</a>
Comment posted by Len on Wednesday, August 8, 2012 1:53 PM
I have a question. I am subscribing to an event with my DLL in the PlugIns folder. It is my understanding that anytime you put a file in this folder, TFS restarts... fine. However I wanted to created a LOGS subfolder in this folder where my DLL can create log files of what it is doing. Will these files created in the subfolder cause TFS to restart? Or, am I safe because they are in a sub-folder?
Comment posted by JJN on Friday, April 5, 2013 3:45 AM
In my case the WorkItemChangedEventHandler gets called multiple times for a single action.

I want to spawn multiple child items when a work item of type "Requirement" gets created. However, even when I create a single work item of type Requirement the code exexutes the Notify method multiple times !!!
Any thoughts?

Post your comment
Name:  
E-mail: (Will not be displayed)
Comment:
Insert Cancel