Quisiera abordar en esta oportunidad algún ejemplo de cómo se puede extender, de una manera relativamente sencilla, la funcionalidad de TFS para adaptarlo a necesidades concretas y reales que aparecen diariamente.
Hay varias maneras de extender TFS, pero en esta ocasión, me voy a centrar en el manejo de eventos y sus particularidades y como dije que se puede hacer de manera “relativamente” sencilla, voy a intentar hacerlo en sólo dos pasos:
- Escribiendo un servicio web que actualice una base de datos propia con información proveniente de un Work Item modificado.
- Eligiendo un evento al que nos vamos a suscribir y vinculándolo con el servicio web.
Veamos cómo sale.
Paso 1: El servicio web
El subsistema de eventos de TFS soporta notificaciones basadas en mensajes SOAP, por lo que sólo tendremos que crear un proyecto de tipo Web Service ASP.NET que contenga un método llamado “Notify” y que reciba dos parámetros:
- eventXml: Es el Work Item serializado. Contiene información acerca de aquellos campos que han cambiado, manteniendo el viejo valor y el nuevo luego de la modificación.
- tfsIdentityXml: Podemos obtener a través de este parámetro, la URL del servidor TFS que ha realizado la llamada
Aquí debajo encontrarán el código del esqueleto del servicio. Sólo restará parsear el work item para obtener la información que nos interese y utilizar ADO.NET o la técnica que prefieran para actualizar la base de datos.
1: namespace VEMN.ExtendiendoTFS.WebService
2: {
3: [WebService(Namespace = "http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/Extensibility", Description = "")]
4: [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
5: public class MiServicio : EndpointBase
6: {
7: [WebMethod]
8: [SoapDocumentMethod("http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03/Notify", RequestNamespace = "http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03")]
9: public void Notify(string eventXml, string tfsIdentityXml)
10: {
11:
12: // Parsing del work item serializado
13:
14: // Actualización de la Base de Datos
15:
16: }
17: }
18: }
1: namespace VEMN.ExtendiendoTFS.WebService
2: {
3: public class EndpointBase : WebService
4: {
5: /// <summary>
6: /// Deserializes a Type
7: /// </summary>
8: /// <typeparam name="T">Type to deserialize</typeparam>
9: /// <param name="serializedType">serialized version of the type</param>
10: /// <returns>DeSerialized version of the type</returns>
11: protected T CreateInstance<T>(string serializedType) where T : new()
12: {
13: T customType = new T();
14:
15: XmlSerializer serializer = new XmlSerializer(typeof(T));
16:
17: XmlDocument xmlDocument = new XmlDocument();
18: xmlDocument.LoadXml(serializedType);
19: XmlNodeReader xmlNodeReader = new XmlNodeReader(xmlDocument);
20:
21: customType = (T)serializer.Deserialize(xmlNodeReader);
22:
23: return customType;
24: }
25: }
26: }
Paso 2: El evento y la suscripción
El subsistema de eventos de TFS nos permite suscribir a los siguientes sucesos:
|
Build Completion Event
|
NodesDeletedEvent
|
|
Build Status Changed Event
|
ProjectCreatedEvent
|
|
BranchMovedEvent
|
ProjectDeletedEvent
|
|
NodeCreatedEvent
|
CheckinEvent
|
|
NodePropertiesChangedEvent
|
WorkItemChanged
|
|
NodeRenamedEvent
|
|
La manera de asociar un evento de TFS al servicio que escribimos en el paso 1, es utilizando el comando “BisSubscribe”. Obviamente nos vamos a “colgar” del evento WorkItemChanged.
La manera de hacerlo es la siguiente:
1: BisSubscribe.exe /eventType WorkItemChangedEvent /deliveryType Soap /address http://tfsserver/WebService/MiServicio.asmx /collection http://tfsserver:8080/tfs/defaultcollection
Algo a tener en cuenta es que, con la aparición de las Project Collections en TFS 2010, debemos utilizar el parámetro “/collection” del commando BisSubscribe en lugar del parámetro “/server” que se usaba en TFS 2008
Sintonía fina
Habiendo publicado el servicio web y estando suscriptos al evento, sólo restará probar toda la maquinaria actualizando algún Work Item y grabando los cambios. No deberá sorprendernos que la llamada al web service no se haga de manera inmediata. Transcurrirán al menos 2 minutos desde la actualización del Work Item hasta que el método “Notify” sea invocado.
Esto es porque a partir de la versión 2010 de TFS se han optimizado muchos procesos, y en esta línea de mejoras, algunas tareas que antes se hacían de manera sincrónica ahora se realizan asincrónicamente.
Este valor de delay fue establecido pensando en servidores que tienen una alta carga de procesamiento y que atienden gran cantidad de usuarios simultáneamente. Con equipos de trabajo más chicos (unos 10 usuarios simultáneos) tranquilamente se puede bajar ese tiempo a 30 segundos sin notar pérdida de performance. Inclusive es posible llevarlo a cero con el mismo resultado.
Para realizar este cambio, tendremos que utilizar la consola de Power Shell con el siguiente script:
1: [Reflection.Assembly]::Load("Microsoft.TeamFoundation.Client, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
2:
3:
4:
5: # Modify the TFS configuration server URL as necessary.
6:
7: $configServer = new-object Microsoft.TeamFoundation.Client.TfsConfigurationServer "http://tfsserver:8080/tfs/"
8:
9:
10:
11: # Get the TF registry service.
12:
13: $tfsRegService = $configServer.GetService([Microsoft.TeamFoundation.Framework.Client.ITeamFoundationRegistry])
14:
15:
16:
17: # Set the notification delay to 30 seconds. All collections will use this delay unless they override this value in the collection hive.
18:
19: $tfsRegService.SetValue("/Service/Integration/Settings/NotificationJobDelay", 30)
20:
En este ejemplo se baja el tiempo a 30 segundos. Encontrarán que es muy sencillo modificarlo por el valor que consideren más apropiado.
Haciendo la vida un poco más fácil (todavía)
El comando “BisSubscribe” es bastante críptico. Si cometemos algún error de tipeo al utilizar el comando y el web service no es invocado por culpa de ese error, no será sencillo hallar la solución sin ayuda adicional.
Para no perecer en esa tarea, podemos valernos del plug-in denominado “Alerts Explorer” para Visual Studio que viene con las Team Foundation Server Power Tools, que nos permitirá administrar esas suscripciones utilizando una GUI muy amigable e intuitiva.
Hasta la próxima !