Datos sobre la escalabilidad de Team System

Interesante post, aunque ya tiene un tiempecito, sobre la escalabilidad de Team Foundation Server durante el «dogfood» del equipo de desarrollo. Se conoce como «dogfood» la practica de utilizar los productos que estas desarrollando para tu propio trabajo.


Sin duda los datos calman a cualquiera que este involucrado en un gran proyecto y quiera utilizar Team Foundation Server. Pongo aquí algunos de los que más me han llamado la atención:


Usuarios recientes: 587
Work Items: 67004
Vesiones: 574365
Archivos en el control de versiones: 1507247


Si estaís preocupados por la escalabilidad de Team Foundation Server, los resultados que muestra el post deberian calmaros, son bastante espectaculares.

El servicio de notificaciones de Team Foundation Server

Una característica de extensibilidad de Team Foundation Server que puede resultar sumamente útil es la posibilidad de subscribirse a eventos que puedan resultar de nuestro interés, y actuar en respuesta a ellos. El API de Team Foundation Server que nos proporciona esta funcionalidad se llama “Team Foundation Eventing Service”  y podéis encontrar más información sobre ella dentro del SDK de Visual Studio 2005, en un documento llamado “Team Foundation Eventing Service.doc”


Básicamente este API nos permite recibir notificaciones, bien mediante un correo electrónico (End-user delivery) o bien mediante la implementación de un callback SOAP (Web service listening). En este post voy ha hablar de esta segunda posibilidad. Otras posibilidades que permite el servicio de eventos, es registrar nuestros propios eventos y nuestras propias plantillas de correo, temas que no cubro en este post.


Bajo las palabras callback SOAP o “Web service listening” lo único que se oculta es que debemos implementar un servicio web que será invocado por el Team Foundation Eventing Service cuando tenga algún evento para el que hayamos mostrado nuestro interés estableciendo una subscripción al mismo.


La primera parte, implementar el callback SOAP pasa por implementar un servicio que con la siguiente firma:


[SoapDocumentMethod(Action = «http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/02/Notify«,  RequestNamespace=»http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/02«
)]
[WebMethod]
public void Notify(string eventXml, string tfsIdentityXml)
{
  …
}


Cuando se produzca un evento, se invocará a este servicio web, y recibiremos la información sobre el evento y sobre el causante del mismo en sus parámetros. Lo que hagamos con esa información depende de nuestras necesidades, el ejemplo más típico es realizar integración continua.


La segunda parte del problema es subscribirnos a los eventos. Para ello lo primero es conocer a que eventos nos podemos subscribir:

AclChangedEvent
BranchMovedEvent 
BuildCompletionEvent
BuildStatusChangedEvent 
CheckinEvent 
CommonStructureChangedEvent 
DataChangedEvent
IdentityChangedEvent 
IdentityCreatedEvent
IdentityDeletedEvent
MembershipChangedEvent 
NodeCreatedEvent 
NodePropertiesChangedEvent 
NodeRenamedEvent 
NodesDeletedEvent 
ProjectCreatedEvent
ProjectDeletedEvent 
WorkItemChangedEvent


Los nombres son toda la información que ahora mismo hay disponible sobre estos eventos. Además conviene saber que el uso de algunos de ellos no está recomendado.

Para subscribirnos a estos eventos tenemos que utilizar la herramienta BisSuscribe, que se encuentra en %ProgramFiles% Visual Studio 2005 SDK2006.03VisualStudioTeamSystemIntegrationUtilitiesEvent Subscription Tool



O utilizar el modelo de objetos de Team Foundation Server para realizar la subscripcion:


using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Server;


// …


// Conectar a TFS
TeamFoundationServer tfsServer = TeamFoundationServerFactory.GetServer(“http://tfsserver:8080”)


// Obtener el servicio de eventos
IEventService eventService = (IEventService)tfsServer.GetService(typeof(IEventService));


// Establcer la opciones de entrega
DeliveryPreference pref = new DeliveryPreference();
pref.Schedule = DeliverySchedule.Immediate;
pref.Address = “url_del_callback_SOAP”
pref.Type = DeliveryType.Soap;


// Subcribirnos al evento
string user = “usuario”
string filter = String.Empty;
eventService.SubscribeEvent(userId, «nombre_de_evento», filter, pref).ToString();

Si decidís utilizar la posibilidad de extensión de Team Foundation Server comentada en este post, un recurso que os será de gran utilidad es la plantilla de proyecto que facilita la vida a la hora de crear los callback SOAP.

¿Cómo crear una dll que exporte funciones tipo "API de Windows"?

Si queremos aseguranos que un API pueda se llamada desde cualquier lenguaje, la mejor opción es crear una dll que exporte funciones al estilo del API de Windows, es decir al estilo C. Casí cualquier lenguaje de programación cuenta con un mecanismo para llamar a esta clase de funciones, porque es el tipo de funciones que exporta el API de windows. Quiza la única excepción es Visual Basic Script, si quieres construir una API que pueda ser llamada desde VBS y desde cualquier lenguaje que soporte COM lee este post anterior.

 

En Visual Studio debes optar por crear un proyecto Win32 de tipo dll.

 

A partir de aquí solo necesitas crear funciones y exportarlas. El truco esta en exportarlas como hace el API de Windows.

 

Realmente no tiene ninguna complicación. Lo unico que tienes que elegir es la convención de llamada adecuada para las funciones que exportes, __stdcall o su alias WINAPI.

 

Además debes declarar estas funciones como extern «C» y ponerlas en el archivo .def (si no exite en la solución añadelo), para evitar que los nombres de función se exporten decorados.

 

Debes declarar las funciones de este modo, en el archivo .h
extern «C»
{
   void WINAPI TuFuncion(…);
   int WINAPI TuFuncion2(…);
}

 

Y tener en el archivo .def (si no exite añadelo) algo similar a esto:

LIBRARY yourLibraryName

EXPORTS

TuFuncion @1
TuFuncion2 @2

 

Además se que en el cd de instalación de VB 6.0 hay un documento word que describe este mismo asunto en detalle, no dudeis en buscarlo (no recuerdo el nombre) y leerlo.

 

Tambien es interesante este articulo de la KB

Enumerar contenido en el gestor de fuentes de Team Foundation

Un pequeño ejemplo sobre como enumerar las carpetas de servidor del gestor de fuentes de Team Foundation.


Los aspectos clave de este ejemplo:


 Cómo establecer una conexión con el servidor TFS
 Cómo solicitar un servicio, en este caso el servicio de gestión de versiones. Para conocer otros servicios existentes ver el documento ‘Team Foundation Server Object Model’ del SDK de Visual Studio 2005.
 Cómo enumerar y filtar los elementos que se encuentrar en el gestor de fuentes.


Para compilar el código basta crear una aplicación de consola, pegar el código y establecer una referencia a los esamblados necesarios de Team System (Microsoft.TeamFoundation.Client.dll, Microsoft.TeamFoundation.Common, Microsoft.TeamFoundation.VersionControl.Common, Microsoft.TeamFoundation.VersionControl.Client) que tipicamente se encuentran en %ProgramFiles%Microsoft Visual Studio 8Common7IDEPrivateAssemblies


Aquí va el código:


using System;
using System.Globalization;
using System.IO;
using Microsoft.TeamFoundation;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.TeamFoundation.VersionControl.Common;


namespace TFSProjFoldersEnum
{
 class Program
 {
  static void Main(string[] args)
  {
            //Establecer la conexión son el servidor Team Foundation
   TeamFoundationServer server = TeamFoundationServerFactory.GetServer(«http://localhost:8080«);
            //Establecer la conexión servicio de control de versiones de servidor
   VersionControlServer vcserver = (VersionControlServer)server.GetService(typeof(VersionControlServer));


            //Obtenemos los items
            //La función GetItems permite establecer:
            //Desde que punto del arbol de fuentes queremos comenzar la enumeración ($/ es la raiz, podriamos establecer un directorio $/dir/dir1)
            //Que versión deseamos
            //Si queremos recursividad o no
            //Si queremos que aparezcan los elementos que han sido eliminados
            ItemSet itemSet = vcserver.GetItems(«$/», VersionSpec.Latest, RecursionType.Full, DeletedState.NonDeleted, ItemType.Folder);
            for (int i = 0; i < itemSet.Items.Length; ++i)
            {
                //Simplmente mostramos el nombre pero la clase item tiene métodos y
                //propiedades que permiten optener su tamaño, su tipo, descargarlos, etc…
                Console.WriteLine(itemSet.Items[i].ServerItem, itemSet.Items[i]);
            }


            Console.ReadLine();
  }
 }
}

¿Como mostrar imagenes en una ventana en VC++ nativo?

Conozco 2 maneras de realizar esto:

1) Utilizar la clase CPiture (que encapsula la interfaz IPicture), escrita
por Paul Dilascia,  que permite usar JPG, GIFF y BITMAP y sobre la que
puedes encontrar información en los siguientes vinculos:

Displaying a JPG in your MFC Application

2) Utilizar el nuevo API GDI+ que permite trabajar con BMP, JPEG, PNG, GIF y
TIFF y estas disponible como un runtime de aproximadamente 1 Mb de tamaño.
Esta libreria es propocionada sin ningún royalti como distribuible por
Microsoft. Mira el siguiente vinculo:

GDI+

Para cargar una imagen y mostarla en una ventana conocido el handle de
su DC en puedes usar la siguiente función:

 void ShowJPG(HANDLE hDC)
 {
     Graphics graphics(hDC);
     Image image(«photo.jpg»);
     graphics.DrawImage(&image, 10, 10);
 }

Controles Windows Forms en paginas HTML (o ASPX)

Cada vez más gente me pregunta cúal es el sutituto en .NET de los controls ActiveX empotrados en páginas Web. Pues bien la respuesta en definitiva como podemos correr controles de Windows Forms en el cliente, desde una página web.

Pues bien al igual que haciamos con los ActiveX, simplificando mucho, el problema se reduce a crear el control, poner una etiqueta <OBJECT> en la página y establecer la seguridad (probablemente el asunto que nos va a dar muchos quebraderos de cabeza a nada que necesitemos ir más allá del "hola mundo!")

El proceso esta explicado en este articulo perfectamente y en este ejemplo, así que no me voy a explayar mucho más.

Desarollo web con Visual C++

últimamente, mucha gente me está preguntando como puede llevar código escrito en Visual C++ a la web. Aunque en principio C++ no parece el lenguaje ideal para programar «para internet», existen varias motivaciones:


 Aprovechar código o librerias existentes.
 Obtener un mejor rendimiento.
 Utilizar servicios web para interoperar.
 Aprovechar el know-how exitente en C++.


Con idependencia de la motivación, que seguro existen algunas otras, el problema habitual es que la gente desconoce que opciones tiene en Visual C++, y que realmente son variadas, potentes y naturales para el programador de C++. Si no estas familiarizado con las diferentes librerias de Visual C++ lee este post anterior.


En Visual C++ 2005 contamos con variadas posibilidades:


Desarrollar componentes COM en C++ usando ATL, o wrappers .Net manejados usando C++/CLI  y llamarlos desde una aplicación construida en Asp o Asp.net. De manera que el proceso lo hace el componente y la aplicación ASP(.net), solo se encarga de mostrar los resultados y la interfaz de usuario. Pero esta no es una solución 100% C++.


Los clasicos cgi, que podemos programar en cualquier lenguaje que sea capaz de devolver texto a una salida estandar. Se han avandonado por su baja escalabilidad, puesto que cada petición es atendida por un proceso y, especialmente en Windows, crear nuevos proceso es una operación costosa.


Los filtros y las extensiones ISAPI (Internet Server Application Programming Interface) es un API que expone IIS y que permite programar modulos y filtros. ISAPI es una API programable en C, de bajo nivel, y que nos aporta poca ayuda, pero que se encuentra en la base de la programación para IIS y por lo tanto bajo todas las librerias que permiten el desarrollo web, ASP.net incluido. Generalmente, en Visual C++, el camino a seguir no es usar ISAPI directamente sino a través de alguna libreria, MFC  tiene soporte para construir filtros y modulos ISAPI. MFC es una libreria que ya tiene sus añitos y por tanto en ciertos aspectos a sido superada. Es interesante además esta entrada en MSDN que explica las diferencias entre CGI e ISAPI


Pero sin duda, cuando hablamos de programación para web con Visual C++ 200x la opción clara es usar ATL Server.




 ATL Server, es un conjunto de plantillas que permiten escribir aplicaciones web (usando el tipo de proyecto ATL Server Project) y servicios web (usando el tipo de proyecto ATL Server Web Service) extremadamente eficientes de una manera sencilla, pues nos proporciona una serie de clases y atributos y un sistema de plantillas para generar contenido HTML (Server Response Files). Sin duda es el camino a seguir en este tema que nos ocupa. Si estas interesado en ATL Server, debes leer estos articulos.


ATL Server and Visual Studio .NET: Developing High-Performance Web Applications Gets Easier
Use ATL Server Classes to Expose Your Unmanaged C++ Code as an XML Web Service
ATL Server Versus ASP.NET


Otra opción con la que poca gente cuenta es la posibilidad de utilizar C++/CLI, la implementación de C++ para .Net, para construir sevicios web. Esta opción no es 100% nativa, pero nos permite con poco esfuerzo y aprovechando las excelentes caracteristicas de interoperabilidad de C++/CLI exponer liberias nativas como servicios web con gran sencillez.

Best Practices Analyzer for ASP.NET

Siguiendo la linea marcada con su anteriores Best Practices Analizer(s) (existen herramientas de este tipo, que yo sepa, para Biztalk 2006 , Sql Server 2000 , ISA 2004  y Exchange ), Microsoft ha liberado una versión alpha de Best Practices Analyzer for ASP.NET.



Es una herramienta que analiza la configuración de nuestras aplicaciones ASP.net 2.0, permitiendonos especificar el escenario: hosting, desarrollo o producción y que nos informa de los problemas que puedan presentar los parametros de configuración que hayamos establecido en machine.config o web.config.


Esta herramienta está basada en reglas al estilo de FxCop, de manera que cualquiera puede añadir comprobaciones que puedan ser de su interés. De hecho, el equipo de desarrollo esta interesado en recopilar las reglas que se nos puedan ocurrir.


Las reglas incluidas en esta versión alpha nos son muchas, pero aún así resultan de interés

El testeo unitario llega a las bases de datos

Sin duda Microsoft Visual Studio 2005 for Database Professionals es un gran añadido a la familia de productos de Visual Studio. Aporta un montón de caracterisiticas espectaculares:


 Crear e importar esquemas de base de datos
 Desplegar bases de datos, ejecutando scripts antes y depues del despliegue
 Validar cambios y diseño en las bases de datos y realizar refactoring
 Generar autómaticamente juegos de datos
 Permite comparar la estructura y el contenido de datos y actualizar la estructura
 Se integra perfectamente con la gestión de fuentes de Team Foundation Server
 
Pero si hay una caracteristica que me ha llamado la atención por novedosa, es la posibilidad de diseñar y correr test unitarios contra la base de datos, ya sea mediante scripts SQL o mediante la ejecución de procedimientos almacenados.


El primer paso siempre que queremos trabajar en VS for DB Professionals con una base de datos es crear o importar su esquema, no me voy a explayar mucho con este proceso, pues es bastante intuitivo. Basta utilizar el menu contextual del proyecto para importar la base de datos o para ir añadiendo los elementos de nuestra base de datos (tablas, vistas, procedimientos almacenados, etc…).


Para generar los unit test el proceso es muy simple tambien, desde el menu Test->New test… podemos crear un nuevo unit test de tipo Database Unit Test. Este proceso creará un nuevo proyecto en el que se alojarán nuestros test. Debemos seleccionar la base de datos contra la que se correrán nuestros test y el lenguaje en el que se implementran, VB, C# o C++.



A partir de este momento, tendremos un nuevo diseñador a nuestra disposición que nos premite escribir las sentencias Transact-SQL que implementan nuestro test. Este diseñador se encarga de, en la sombra, generar todo el codigo necesario para ejecutar el test. Podemos verlo yendo a la vista de código fuente del diseñador de test para bases de datos. En la parte inferior del diseñador definimos las condiciones.


Si lo que queremos probar es un procedimiento almacenado, el proceso de creación del test es aun mucho más simple, puedo podemos generar el test que invoque al procedimiento solo con hacer click sobre el menu contextual del procedimiento la ventana Solution Explorer.


Una vez realizados los pasos anteriores, los test se ejecutarán y devolverán sus resultados como cualquier otro test unitario de Visual Studio.