5.25.2012

Autenticando Servicios WCF – Certificados Digitales–Parte 1

Crear e Instalar el Certificado

Cuando se crea un servicio que se debe autenticar utilizando certificados digitales para brindar seguridad a nivel de mensaje debemos crear un certificado temporal. Para esta tarea procederemos con la herramienta makecert.exe. Esta herramienta genera certificados del tipo x.509 para propósitos de prueba. En realidad esta herramienta crea una pareja de llaves –> una pública y otra privada – que servirán para las firmas digitales las cuales se van a almacenar en un archivo.

Para desarrollar un servicio que use certificados x.509 para brindar seguridad a nivel de mensaje –> la seguridad se puede aplicar a nivel de mensaje o a nivel de transporte dependiendo del protocolo utilizado –> los certificados tienen que tener un nivel de confianza los cuales tienen que tener un nivel de confianza especificado. Las opciones disponibles son:

  • Peer Trust: el certificado se valida de forma directa
  • Chain Trust: el certificado se valida contra el emisor del mensaje conocido como “root authority”.

En este tutorial vamos a utilizar Chain Trust. El primer paso es crear un certificado auto firmado que será la autoridad raíz; este certificado será almacenado en el almacén de autoridades raíz de certificación de confianza. En WCF se utilizará posteriormente para crear un certificado desde el certificado autofirmado raíz y que se instalará en el almacén de la máquina local.

Crear el Certificado Raíz

El primer paso para crear un certificado raíz que se va a utilizar para firmar los certificados que se van a intercambiar entre el servicio WCF y el cliente. Para esto utilizamos el “command prompt” de Visual Studio y procedemos con la siguiente instrucción:

image

En este caso el parámetro –n indica el nombre del CA, –r indica que el certificado va a ser autofirmado y por último –sv nos indica que el archivo contiene la llave privada del certificado.

Cuando ejecutamos este comando aparece la pantalla para crear el password de la llave privada.

image

Luego nos va a pedir el password de nuevo con el fin de poder acceder la llave privada del archivo pvk para generar el .cer que es el que contiene la llave pública.

image

Podemos verificar que los certificados están creados en el directorio donde nos ubicamos para crearlos utilizando el Windows Explorer

image

Instalar el certificado

Ahora procedemos a instalar el certificado en la locación “Trusted Root Certification Authorities” lo cual nos indica que todos los certificados firmados por esta autoridad serán de confianza tanto para el cliente como para el servidor. [ Este ejemplo corre en una sola máquina, si se desea tener un cliente en una máquina virtual o vía red, se debe instalar el certificado también en la máquina cliente.

Para levar a cabo esta tarea procedemos a correr la consola de administración utilizando el comando ejecutar – Windows + R – y procedemos a escribir mmc y le damos enter.

image

Tenemos que agregar el complemento – snap – para poder agregar el certificado, para esto seleccionamos archivo y agregar o quitar complemento…

image

Seguidamente agregamos el complemento de certificados tal y como se ve en la siguiente pantalla.

image

Cuando arranca el wizard, seleccionamos cuenta de equipo para que el certificado este disponible para todos los usuarios.

image

Seleccionamos el equipo local como administrador del complemento y luego finalizamos el wizard..

image

Y finalizamos el wizard. La pantalla del MMC debe verse ahora así:

image

Expandir el folder de Certificados y seleccionar el folder de Entidades de certificación raíz de confianza –> vaya traducción.

image

Ahí le damos botón derecho y procedemos a seleccionar la opción “todas las tareas/importar”.

image

El wizard inicia con la siguiente pantalla en la cual seleccionamos siguiente

image

Buscamos el archivo .cert que acabamos de generar y lo agregamos

image

En el siguiente paso aceptamos los valores por defecto.

image

En la última pantalla revisamos los valores del wizard y lo finalizamos

image

El certificado esta instalado en el almacén de certificados de confianza de la raíz. Para verlo procedemos a expandir el folder de certificados en la consola y los buscamos por el nombre.

image

Crear e instalar el certificado temporal para el uso del servicio WCF

Ahora procedemos a crear e instalar el certificado en la máquina del servidor. Para esto procedemos a movernos a la ubicación del  certificado raíz en la máquina del servidor.  Una vez en la ubicación procedemos con el siguiente comando desde el “prompt de Visual Studio”.

image

Este comando nos permite crear el certificado e instalarlo en el store My. El certificado se llama DRMCert.cer y esta creado a partir del certificado emitido en el paso anterior RootDRM. Al estar utilizando la misma máquina tanto para el servidor como para el cliente el mismo store y el mismo proceso nos sirve para interactuar con el certificado. Si estuviéramos trabajando con máquinas separadas, habría que copiar el certificado y aplicar el mismo comando del lado del cliente de prueba.

Si vamos a la consola consola de administración, el certificado recién creado deberá aparecer en el almacén de equipo local, dentro del folder certificados de los certificados personales.

image

En el siguiente post iniciaremos el trabajo con el servicio WCF y su respectivo cliente.

Etiquetas de Technorati: ,,

5.06.2012

Métricas en Visual Studio: Cobertura de las pruebas unitarias

En lo que respecta a las pruebas unitarias, siempre existirá el factor humano a la hora de garantizar la calidad estructural del software a partir de estas pruebas, y normalmente cuando se trata de enseñar el tema a los desarrolladores de software surgen las mismas preguntas:

  • ¿Cómo saber si las pruebas están bien hechas?
  • ¿Qué debo probar y que no debo probar?
  • ¿Cómo se cuanto código es verificado con nuestros unit test?

Esta y muchas otras preguntas pueden responderse de muchas formas; sin embargo, con la ayuda de las métricas de visual studio podemos obtener información para responder estas y muchas otras preguntas. En este post nos vamos a enfocar en como determinar la cantidad de código cubierto por nuestras pruebas unitarias utilizando Visual Studio 2010.

Proyecto Ejemplo

Nuestro proyecto será una simple aplicación de consola con dos clases con diferentes propósitos. Una que nos permitirá manipular colecciones de objetos y otra que nos permita manipular arreglos de enteros.

La clase que nos permite manipular colecciones de objetos es la siguiente:

public class AdministradorDeColecciones
{
public T PrimerElemento<T>(IEnumerable<T> pColeccion )
{
return pColeccion.FirstOrDefault();
}

public T UltimoElemento<T>(IEnumerable<T> pColeccion)
{
return pColeccion.LastOrDefault();
}

public IEnumerable<T> ObtenerDelTipo<T>( IEnumerable<T> pColeccion, Type pType)
{
return pColeccion.Where(p => p.GetType() == pType);
}

public IEnumerable<T> ObtenerTodosMenosDelTipo<T>( IEnumerable<T> pColeccion, Type pType )
{
return pColeccion.Where(p => p.GetType() != pType);
}
}

La clase que nos permite manipular arreglos de enteros es la siguiente:

public class AdministradorDeArreglosNumericos
{
public decimal ObtenerPromedio( int[] pArreglo)
{
return (pArreglo.Sum() / pArreglo.Count());
}

public int ObtenerElMayor( int[] pArreglo)
{
return
(from _i in pArreglo orderby _i descending select _i).FirstOrDefault();
}
}

Ahora procedemos a crear un proyecto para realizar nuestras pruebas unitarias a la clase anterior. Para esto creamos en la misma solución un proyecto de Test en WCF. La solución se ve ahora de la siguiente forma:


image


En la figura anterior se pueden ver dos cosas relevantes: 1. se agregó una referencia al proyecto donde están las clases a probar. 2. Se creó un archivo del tipo “unit test” básico. Ahora vamos a crear un test para probar el método ObtenerElMayor de la clase AdministradorDeArreglosNumericos.

[TestClass]
public class PruebasEjemploMetricas
{
[TestMethod]
public void ObtenerElMayorDeLaLista_RetornaTreinta()
{
int[] _lista = {11, 4, 8, 6, 30, 7};
var _administrador = new AdministradorDeArreglosNumericos();

int _resultado = _administrador.ObtenerElMayor(_lista);

Assert.AreEqual(30, _resultado, "Retorno del mayor de la lista incorrecto");
}
}

Esta prueba al ser ejecutada pasa sin ningún problema.


image


Ahora, queremos ver cuanto código esta cubierto por nuestras pruebas unitarias –> en este caso, un método con una prueba. Este dato es relevante sobre todo cuando la cantidad de código escrito es abundante y las pruebas unitarias aparentan tener todo cubierto.


Test Coverage en Visual Studio


En Visual Studio 2010 podemos calcular la cantidad de código que está cubierta por las pruebas unitarias cambiando la configuración en el archivo Local.testsettings.


image


Al darle doble click al archivo nos aparecerá un diálogo de configuración. En esta pantalla procedemos seleccionar “Data and Diagnostics” y marcamos la opción “Code Coverge” tal y como se muestra en la figura.


image


El siguiente paso es configurar el “Code Coverage” por lo que procedemos a dar click sobre el botón “configure” justo arriba de la lista de roles. Ahí nos aparecerá la siguiente pantalla.


image Aquí procedemos a seleccionar el assembly sobre el cual queremos aplicar la métrica. Ahora procedemos a ejecutar la prueba unitaria de nuevo y seleccionamos la opción de ver los resultados de la cobertura de las pruebas.


image


En esta pantalla si expandimos los resultados podemos ver el código cubierto por nuestra prueba unitaria. Como podemos ver en los resultados todos los métodos tienen 0% de cobertura excepto el método ObtenerElMayor.


image



Por último, en Visual Studio todos los métodos que no estén cubiertos por las pruebas unitarias estarán marcados por un fondo rojo, y los que si estén cubiertos por al menos una prueba unitaria estarán con el fondo celeste. Esto se puede ver en la siguiente figura.


image


Igualmente, la clase AdministradorDeColecciones al no tener una prueba unitaria tendrá todos sus métodos marcados con fondo rojo.


image



Etiquetas de Technorati: ,,

4.19.2012

Visual Studio Tips: Break points condicionales

Cuando se trabaja desarrollando software con alguna empresa, es sencillo identificar quién tiene un amplio dominio de Visual Studio como Herramienta y quién no. Hago la diferenciación acerca de del uso de Visual Studio como Herramienta ya que no es lo mismo dominar .NET que dominar Visual Studio.

Uno de los puntos más importantes a la hora del desarrollo del software es la depuración, y por lo tanto poder “debuguear” de la mejor forma el código se convierte en una herramienta fundamental para producir software de calidad. La mayoría de los desarrolladores saben como “debuguear” el código pero: ¿Saben cómo sacarle el máximo provecho al “debuguer”?

Un casi típico es ver a un desarrollador “debugueando” el recorrido de una lista ítem por ítem cuando en realidad quiere ver solo los ítems que tengan alguna condición en común. En este caso Visual Studio nos permite ponerle condiciones a los “break points” para que estos solamente se detengan cuando esta condición se cumple. Para entender esta característica veamos un ejemplo.

Break points condicionales

Supongamos que tenemos una clase Cliente con las siguientes características:

public class Cliente
{
public Int64 Id { get; set; }
public string Nombre { get; set; }
public string Pais { get; set; }
public DateTime FechaNacimiento { get; set; }
public string Email { get; set; }
public string Telefono { get; set; }
}

Supongamos que un método va a una base de datos y obtiene una cantidad muy grande de clientes; para nuestro ejemplo vamos a retornar una lista con cuatro clientes.

static IEnumerable<Cliente> ObtenerClientes()
{
var _lista = new List<Cliente>
{
new Cliente
{
Id = 1, Nombre = "Ana Cruz",
Email = "ana@yahoo.com",
FechaNacimiento = DateTime.Now.AddYears(-25),
Pais = "Panamá"
},
new Cliente
{
Id = 2,
Nombre = "Yorleny Prendas",
Email = "Yorleny@ymsn.com",
FechaNacimiento = DateTime.Now.AddYears(-35),
Pais = "Costa Rica"
},
new Cliente
{
Id = 3,
Nombre = "Carlos Porras",
Email = "cporras@ymsn.com",
FechaNacimiento = DateTime.Now.AddYears(-45),
Pais = "Costa Rica"
},
new Cliente
{
Id = 4,
Nombre = "Israel Arias",
Email = "iarias@gmail.com",
FechaNacimiento = DateTime.Now.AddYears(-23),
Pais = "Perú"
}
};
return _lista;
}

Supongamos que al recorrer la lista notamos un comportamiento inusual pero solamente los clientes con el Pais = “Costa Rica” lo producen. Si la lista no devuelve los registros ordenados y la cantidad de estos es muy alta, esta tarea depuración puede ser muy tortuosa y lenta. Sin embargo, el “debuguer” de Visual Studio nos permite poner condiciones a los “break points”; para lograrlo simplemente ponemos el break point y damos botón derecho sobre el mismo y seleccionamos la opción “condition”


image


Seguidamente nos aparecerá el diálogo para agregar el filtro que queremos que detenga el proceso de depuración. En nuestro caso queremos que se detenga cada vez que el cliente tenga como país “Costa Rica”.


image


Ahora cuando “debugueamos” el código { con F5 } el “debuguer” solo parará si se cumple esta condición.


image


Etiquetas de Technorati: ,

4.12.2012

Invitación al Expert Day 2012

El próximo martes 17 de abril estaré impartiendo la charla: Arquitectura de Software –> de donde venimos y hacia donde vamos. La charla es parte del evento Expert Day el cual se llevará a cabo en la Universidad de Costa Rica en la sede de Occidente. Les adjunto la agenda con todas las charlas que se van a impartir. Los espero.

image

Etiquetas de Technorati: ,

4.07.2012

¿Qué es un Unit Test?

Existen muchas definiciones acerca de lo que realmente es una prueba unitaria – unit test – sin embargo algunas son ambiguas y otras tienen un enfoque determinado de acuerdo a la situación en que se utilizan o se desarrollan. En este post vamos a tratar de caracterizar más que definir que es una prueba unitaria.

Identificar un Unit Test

Un unit test es un método que prueba una unidad de código. Al hablar de una unidad de código nos referimos a un requerimiento. Muchos desarrolladores tienen su propio concepto de lo que es una prueba unitaria; sin embargo, la gran mayoría coincide en que una prueba unitaria tiene las siguientes características:

  • Prueba solamente pequeñas cantidades de código: Solamente prueba el código del requerimiento específico.
  • Se aísla de otro código y de otros desarrolladores: El unit test prueba exclusivamente el código relacionado con el requerimiento y no interfiere con el trabajo hecho por otros desarrolladores.
  • Solamente se prueban los endpoints públicos: Esto principalmente porque los disparadores de los métodos privados son métodos públicos por lo tanto se abarca el código de los métodos privados dentro de las pruebas.
  • Los resultados son automatizados: Cuando ejecutamos las pruebas lo podemos hacer de forma individual o de forma grupal. Estas pruebas las hace el motor de prueba y los resultados de los mismos deben de ser precisos con respecto a cada prueba unitaria desarrollada
  • Repetible y predecible: No importa el orden y las veces que se repita la prueba, el resultado siempre debe de ser el mismo.
  • Son rápidos de desarrollar: Contrariamente a lo que piensan los desarrolladores –> que el desarrollo de pruebas unitarias quita tiempo – los unit test por lo general deben de ser simples y rápidos de desarrollar. Difícilmente una prueba unitaria deba de tomar más de cinco minutos en su desarrollo.

Ejemplo

Para entender mejor que es una prueba unitaria vamos a proceder a hacer un ejemplo. Supongamos que tenemos un método que nos indica si en un arreglo de strings existe al menos un string que sea igual a la palabra que estamos pasando por parámetro. El código del método es el siguiente:

public class AdministradorDeArreglos
{
public bool ExisteEnArreglo(string[] pArreglo, string pPalabra)
{
return pArreglo.Any(p => p.ToUpper() == pPalabra.ToUpper());
}
}

Para probar el Código escribimos lo siguiente

static void Main(string[] args)
{
var _administradorDeArreglos = new AdministradorDeArreglos();
string[] _arreglo = {"Manaza", "Papaya", "Melón", "Sandía", "Piña", "Banano"};
Console.WriteLine( _administradorDeArreglos.ExisteEnArreglo(_arreglo, "Banano") );
}

Y el resultado final será:


image


Ahora vamos a proceder a probar el código creando una prueba unitaria. El primer paso es agregar un proyecto a la solución del tipo Test –> vamos a utilizar MSTest para hacer las pruebas unitarias en este ejemplo [Observación: Yo utilizo Visual Studio Ultimate por lo tanto algunas opciones de testing pueden no aparecer en otras versiones menores o pueden estar en otro orden].


image


Como vemos en la siguiente figura, se va a crear un proyecto de testing que tiene una referencia directa al componente – dll – en donde están todas las librerías para hacer pruebas unitarias con el MSTest. Además, se crea un archivo inicial de testing y un grupo de tres “Solution Items” desde donde vamos a poder configurar y administrar las funcionalidades de nuestros tests.


image


Ahora procedemos a borrar el archivo UnitTest1.cs y vamos a crear uno desde cero. Luego de borrar el archivo, procedemos a agregar una referencia al proyecto que queremos probar. Luego damos botón derecho sobre el proyecto de testing y seleccionamos agregar nuevo test.


image


Ahora procedemos a seleccionar el tipo de prueba de unidad que vamos a crear, en nuestro caso una prueba de unidad básica.


image


Este paso nos va a generar un archivo de pruebas básico con un método de pruebas de ejemplo que cual vamos a proceder a eliminar.

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Pruebas
{
[TestClass]
public class Pruebas_SeriePruebasUnitarias
{
[TestMethod]
public void TestMethod1()
{
}
}
}

En el código anterior vemos que la clase generada esta marcada con el atributo TestClass, esto le indica al motor de pruebas de visual studio que dentro de esta clase existen pruebas de unidad que debe ejecutar. Los métodos de prueba son métodos públicos de tipo void que están marcados por el atributo [TestMethod] como se ve en la figura anterior.


Ahora procedemos a crear nuestra primera prueba unitaria. El código de la prueba unitaria es el siguiente:

[TestClass]
public class Pruebas_SeriePruebasUnitarias
{
[TestMethod]
public void ExisteArreglo_RetornaTrue()
{

var _administradorDeArreglos = new AdministradorDeArreglos();

var _resultado =
_administradorDeArreglos.ExisteEnArreglo(new[] { "Argentina", "Brasil", "Perú" }, "Brasil");

Assert.IsTrue(_resultado);
}
}

La prueba unitaria anterior prueba específicamente la unidad de código “ExisteEnArreglo” de la clase AdministradorDeArreglos.


Al Ejecutar el unit test el resultado será el siguiente:


image


Como podemos ver, el test pasó y el panel de resultados de VS así me lo hace saber.


Estructura del Unit Test


Para terminar, es importante notar que los unit test tienen por lo general una estructura compuesta de tres partes:




  1. Arrange: Es la parte del unit test en donde se configura todo el código para ejecutar la prueba unitaria. En nuestro caso, el “arrange” es la creación de la instancia de la clase AdministradorDeArreglos.


  2. Act: Esta es la fase del unit test en donde se ejecuta el código a probar. En nuestro caso es la invocación del método de instancia ExisteEnArreglo.


  3. Assert: Es la sección de la prueba unitaria en donde se prueba el resultado del mismo. En este caso y por lo general, lo hacemos con la clase Assert –> en MSTest –> y es donde verificamos que la variable _resultado == true;


Etiquetas de Technorati: ,

3.24.2012

Temas Olvidados de la Arquitectura: Manejo de Errores

Normalmente cuando hablamos de arquitectura de software pensamos en muchísimas cosas relacionadas con el tema y que normalmente son parte de un lenguaje “común” que prácticamente todos los desarrolladores de software manejamos y conocemos. Sin embargo, existen varios temas que por distintas razones no trabajamos o no nos gusta trabajar con el mismo ahínco con el que trabajamos tareas tales como la lógica de negocio, la capa de acceso a datos, las entidades y los servicios. Uno de estos temas es el manejo de errores.

El Error –> un asunto de perspectiva

Contrariamente a lo que uno ve en temas de arquitectura; donde cada empresa tiene su propio “sabor” de lo que debería ser una arquitectura, hay algo que por lo general es muy estándar: la forma de presentar el error al usuario final –> a través de un MessageBox. Esto es algo casi endémico e incluso vemos desarrolladores tratando de implementar algún tipo de MessageBox en una aplicación Web para presentar un error, sin embargo; el tema central –> el como manejo el error –> se controla a un nivel muy básico e incluso en muchas casos no se trabaja.

Esto se da por varias razones, pero la principal es la falta de interés del desarrollador por hacer algo con la excepción –> normalmente esta enfocado en que el software haga lo que tiene que hacer lo antes posible. A la mayoría de los desarrolladores les parece suficiente con presentar un message box y con loguear el error en el EventViewer –> en el mejor de los casos. Esta falta de esfuerzo a la hora de manejar errores de forma adecuada crea una falsa sensación de inseguridad en el usuario final del sistema, porque normalmente termina pensando que el sistema es más malo de lo que realmente es –> Así devs, aunque no nos guste, muchos usuario finales consideran que mucho del software que ellos usan no sirve y está mal hecho. Esto quiere decir, que nosotros mismos le estamos facilitando esta percepción al usuario final, ya que podríamos decir que por nuestra falta de esfuerzo a la hora de manejar los errores el usuario final, termina pensando que nuestro sistema no funciona.

¿Qué debo hacer?

Sin duda alguna darle la importancia que merece el tema. Personalmente considero que no se deben retornar excepciones de sistema al usuario final, ya que esto lo confunde en una situación en donde normalmente deberíamos hacerle la vida más simple. La idea es más bien crear un framework de excepciones de negocio donde existan excepciones creadas por nosotros con un perfil de negocio y las cuales puedan ser mapeadas o convertidas a partir de una excepción de sistema.

image

Este módulo de manejo de excepciones recibirá y convertirá excepciones de sistemas en excepciones de negocios. Estos mapeos se pueden guardar en diferentes tipos de repositorios, ya sea un documento XML, una base de datos, un archivo de texto con un formato CSV, etc. La idea es que este mapeo sea tan granular como se pueda, ojala por módulo y por operación. Por ejemplo, no debería devolver la misma excepción de negocios un error de InvalidOperationException provocado en el módulo de pago del POS a recibir esta excepción en el módulo de manejo de oportunidades de venta en el CRM.

El Logging

Otro punto importante es que hacer con esta excepción cuando algo ocurre. ¿ La pongo en el event viewer? la guardo en un documento XML. De acuerdo a mi experiencia, la búsqueda de errores es un verdadero dolor de cabeza para las empresas y por lo general, se tarda más encontrando el error que reparando el mismo. Es por esto que se tiene que buscar una forma centralizada de loguear los errores. Normalmente en una arquitectura distribuida esto se logra utilizando el visor de eventos del servidor y las características de seguimiento de estos servidores de aplicaciones como por ejemplo el Windows AppFabric. Cuando se tiene la posibilidad de tener un servidor EAI o ESB como Biztalk Server podemos utilizar este servidor como repositorio de errores para poder tener todos los errores centralizados y así poder tener una mejor administración de los mismos.

A nivel local se debe de usar una forma de logging sencilla que permite llevar el control del lado del cliente. Para esta tarea se puede utilizar NLog, o el Logging application block del grupo de patterns and practices. Ambos pueden ser utilizados a nivel de cualquier capa e incluso en combinacion con los motores de seguimiento mencionados anteriormente.

Etiquetas de Technorati:

2.12.2012

¿Qué es un micro ORM?

Muchos de nosotros hemos utilizado herramientas para mapear del mundo relacional al mundo orientado a objetos tales como el Entity Framework y NHibernate. Sin duda el uso de estas herramientas esta motivado por la facilidad que se logra para trabajar con el acceso a datos. Sin embargo, a muchos de nosotros siempre nos queda una espinita acerca del uso de estas herramientas ya que a ratos quedan sensaciones un poco diferentes respecto a la eficiencia de las mismas. En mi caso personal, hasta antes del modelo Code First del Entity Framework no estaba del todo convencido de utilizar este ORM –> aunque Microsoft le quiera llamar de otra forma –> en un proyecto enterprise, ya que considero que los POCOS son parte fundamental en cualquier arquitectura que vayamos a utilizar por su eficiencia y porque podemos utilizarlos como “transportador” de objetos neutral, ya que al final estos objetos se serializan en tipos SOAP estándar que nos van a permitir que sean consumidos de forma simple desde otras tecnologías tales como Java y PHP –> claro, siempre y cuando usemos tipos estándar.

Definición

Sin embargo, desde hace un tiempo atrás me di a la tarea de buscar algo intermedio, que me permitiera tener algunas de las abstracciones de lo ORM, pero que no me castigara en desempeño y me encontré el término Micro ORM. Un micro ORM es por lo general una librería pequeña que abstrae la funcionalidad principal de ADO.NET a través de un uso extensivo de los tipos dinámicos. Esto permite tener la misma funcionalidad que con ADO.NET tradicional, pero con mucho menos código; todo esto sin perder desempeño.

Ejemplo

Para ilustrar el concepto vamos a crear un ejemplo sencillo en el cual vamos a agregar, buscar y eliminar un registro desde una tabla en una base de datos SQL Server, este ejemplo lo vamos a desarrollar con Dapper.NET. La tabla que vamos a utilizar es la siguiente:

image

Como comenté anteriormente, los Micro ORM basan su funcionalidad en los POCOS, por lo tanto vamos a crear una librería que será nuestra capa de entidades –> siempre importante separar el estado del comportamiento. EL POCO para la tabla empresa es el siguiente:

image

Ahora procedemos con la capa de acceso a datos. En esta capa vamos a crear métodos estáticos para Agregar, Obtener y Eliminar empresas. Recuerden que en esta capa utilizamos métodos estáticos porque no existe razón alguna para mantener estado en estas invocaciones. Nótese que la hilera de conexión está en el archivo, algo que no es una recomendación pero un “abuso” propio para poder desarrollar el ejemplo de una manera más sencilla.

image

En el código anterior se puede ver que para hacer un select sobre una tabla utilizamos el método de extensión genérico Query, el cual recibe un arreglo de parámetros –> aunque esta sobre cargado para recibir más parámetros tales como transacciones –> y retorna un conjunto de datos tipificado en base al tipo enviado por parámetro en el método query –> en el generic.

image

Igualmente para ejecutar sentencias SQL que no retornan conjuntos de datos pero que llevan a cabo acciones sobre las tablas como el eliminar o el agregar vamos a utilizar el método Execute. Este método al igual que el Query, es un método de extensión que para este ejemplo, recibe una colección de parámetros los cuales por orden son asignados a los parametros definidos con @ dentro de la sentencia SQL; por ejemplo @Nombre –> Nombre = pEmpresa.Nombre.

image

Ahora procedemos a crear una capa de negocios que simplemente tiene las llamadas respectivas a la capa de acceso a datos.

image

Si queremos exponer estos métodos de lógica de negocio, vamos a tener que marcar como serializables los campos del POCO y el POCO utilizando el serializador de WCF.

image

Luego procedemos a crear el servicio. El primer paso es crear una librería WCF y definir el contrato del servicios

image

Después procedemos a implementar el contrato del servicio

image

Si queremos consumir el servicio desde cualquier interface, simplemente agregamos la referencia al servicio recién creado y a través del proxy se generarán los tipos necesarios para ejecutar nuestra aplicación.

Etiquetas de Technorati: ,,,

2.04.2012

La importancia de las pruebas unitarias –> Unit Tests

Los desarrolladores de software hablamos constantemente de como desarrollar software, como crear una arquitectura nueva para nuestra aplicación, que tipo de tecnología utilizaremos en el “front end”, el tipo de la base de datos a utilizar, etc. Sin embargo, es muy extraño encontrarse un desarrollador de software y más extraño aún encontrarse un arquitecto de software hablando de las pruebas que se le van a aplicar al software. En general probar software es un tema que siempre se ha dejado para el final en donde por falta de tiempo termina siendo una tarea hecha a la carrera y sin mucho empeño. Además, los desarrolladores tienden a pensar que esa tarea es de otros compañeros los cuales en el mejor de los casos son los “testers” y en el peor de los casos son los clientes del sistema.

Sin embargo, desde el punto de vista de la arquitectura de software, garantizar el funcionamiento correcto tanto desde el punto de vista estructural como funcional es una tarea tan importante como diseñar el software. Las pruebas funcionales están relacionadas con que el software desarrollado haga las cosas como el usuario espera y las pruebas estructurales son los unit test o pruebas unitarias. Las pruebas funcionales por lo general las llevan a cabo “testers” o usuarios finales que prueban y garantizan el buen funcionamiento del software. Por otro lado, las pruebas estructurales o pruebas unitarias buscan garantizar que el sistema no se quiebra cuando recibe cambios o nuevas características; estas pruebas la realizan los desarrolladores de software.

Los desarrolladores y las pruebas unitarias

Aunque para nosotros los desarrolladores las dos formas de hacer pruebas deberían ser igual de importantes, debemos estar más involucrados en las pruebas unitarias ya que es algo que debemos de programar nosotros mismos. Estas pruebas nos van a permitir validar aspectos tales como:

  • Si hago un cambio en el módulo A no voy a quebrar algo en el módulo B –> esto se da porque las pruebas unitarias se ejecutan cada vez que voy a subir el código como listo a mi repositorio de código, y si mi cambio en A va a quebrar B, las pruebas unitarias de B no serían exitosas.
  • Cuando trabajo en equipo evita que yo modifique con un error un código que ya esta probado y funcionando, ya que para que yo pueda subir el código al repositorio compartido tengo que ejecutar todas las pruebas unitarias –> tanto las mías como las de mis compañeros –> y si alguna falla no debo subir el código.
  • Las pruebas unitarias me permiten hace refactorización del código para permitir que mi código pueda ser más legible y más reutilizable, ya que cuando se desarrollan se observan oportunidades de mejora que no se distinguen cuando estamos desarrollando –> por ejemplo el uso amplio del polimorfismo.

Al hablar de pruebas unitarias e involucrar a los desarrolladores en este tema, surgen muchos mitos y resistencia de parte de estos últimos ya que por lo general a el desarrollador no le gusta probar. Los mitos más comunes son:

  • Las pruebas no las hago yo, le tocan al tester: FALSO. Desde todo punto de vista esta afirmación no tiene sentido ya que nadie más que le propio desarrollador conoce la estructura de su programa y nadie más que el sabe que se debe de probar para mantener al sistema estable y sin caídas inesperadas. Es tan importante que el desarrollador haga sus pruebas ya que con esto eliminamos en un porcentaje muy alto – depende del porcentaje de cobertura – la posibilidad de que nuestro sistema tenga caídas inesperadas no controladas. Además el construir estas pruebas le permite al desarrollador encontrar vacíos de diseño y oportunidades de mejora utilizando el refactoring –> algo de lo que hablaremos en otro post.
  • Si tengo que programar los unit test necesito más tiempo de desarrollo: FALSO. Esta más que demostrado que cuando uno utiliza pruebas unitarias reduce el tiempo de desarrollo de los proyectos, esto por cuanto se disminuye la mayoría del re trabajo en los proyectos de desarrollo. Por lo general el re trabajo es algo que no se toma en cuenta a la hora de hacer los planes de proyecto y al final es el rubro que se termina comiendo el cronograma y el presupuesto.
  • Los unit test son difíciles de programar y llevan mucho código: FALSO. Al contrario, las pruebas unitarias para que estén bien hechas deben de ser sencillas, rápidas, y fáciles de programar. De acuerdo a Roy Osherove en su libro “El arte de las pruebas unitarias” –> muy muy recomendado –> una prueba unitaria debe de ser escrita de forma tal que en 10 minutos tengamos algo para probar; y es totalmente cierto, en muy raras ocasiones toma más de 10 minutos el pensar y programar una prueba unitaria –> aunque al principio cuando se está aprendiendo puede que tome más.

En próximos post voy a enfocarme en cómo trabajar con pruebas unitarias en .NET y en Visual Studio.

Etiquetas de Technorati:

1.22.2012

WCF: ¿Qué es el metadata exchange - MEX?

Para los que trabajamos a diario con WCF este tema nos puede parecer simple y sencillo de comprender; sin embargo, en ocasiones me encuentro con desarrolladores que pese a que utilizan WCF muy seguido no saben el porque de este endpoint en el archivo de configuración. En este post vamos a aclarar el término y su importancia.

¿Qué es el metadata exchange - MEX?

El endopoint MEX es la manera en que se publica el metadata del servicio. ¿ Y que es este metadata? El metadata del servicio es la información que consumen los clientes para crear el proxy del servicio y así poder llamar el servicio. En otras palabras, cuando accedemos un servicio desde un cliente lo hacemos a través de un proxy – una clase – que se genera a partir del metadata del servicio – más acerca del proxy en el próximo post.

image

¿Es el MEX lo mismo que el WSDL?

Ahora, si hemos usado servicios web desde antes de que WCF entrara a escena nos va a surgir la pregunta ¿Es el MEX lo mismo que el WSDL del servicio? La respuesta es si y no. En realidad el WSDL y el MEX cumplen la misma función pero el MEX es la nueva versión de lo que antes era el WSDL – más al respecto en este link. En otras palabras, el MEX endpoint no es algo definido por Microsoft, si no más bien un estándar establecido por la W3C para exponer la metadata del servicio. El “no”, esta relacionado con el hecho de que aunque los dos hacen lo mismo lo hacen de diferente forma; siendo la principal diferencia el hecho de que el metadata expuesto a través del MEX se obtiene en menos viajes al servidor que si se hace utilizando el WSDL – en realidad para el MEX solo se requiere un viaje en cambio para el WSDL requiere de varios request para obtener todas las partes de la descripción del mensaje. Además el metadata con el MEX se puede exponer a través de más protocolos que el WSDL el cual solo soportaba HTTP(S).

¿Cuáles tipos de MEX tengo disponibles en WCF?

Existen muchos tipos de MEX en WCF, entre los que podemos mencionar MexHttpBinding, MexHttpsBinding, MexTcpbinding. Como podemos ver, la variación que existe esta relacionada a través del protocolo sobre el cual queremos exponer la metadata del servicio.

Etiquetas de Technorati: ,

1.03.2012

Windows AppFabric p2–> Configurando los servicios de WCF y WF

En el post anterior conversamos acerca de la instalación del Windows AppFabric en Windows 7. En este post vamos a configurar el AppFabric para que estén disponibles las funcionalidades de seguimiento, persistencia y caché distribuido.

Configurar el AppFabric

Para configurar el AppFabric tenemos que buscar la aplicación que nos permite llevar a cabo esta tarea, la cual se puede encontrar en el folder del Windows Server AppFabric en el menú de programas.

image

Cuando se ejecuta esta aplicación aparece el wizard para iniciar la configuración del Windows AppFabric.

image

El primer paso es configurar el monitoreo de los servicios y los workflows y luego establecer la configuración de la persistencia. Primero procedemos a configurar el monitoreo de los servicios y lo hacemos seleccionando la opción establecer la configuración de seguimiento o en inglés “Set monitoring configuration”. Luego seleccionamos el proveedor que vamos a utilizar para guardar la información de configuración – SQL Server en este caso - y luego seleccionamos Configurar.

image

En la pantalla de configuración para el seguimiento procedemos a seleccionar las opciones “registrar almacén de seguimiento en web.config” e “inicializar almacén de seguimiento”. En ambos casos estamos diciéndole al wizard que registre o cree la base de datos en SQLExpress y que ponga la configuración en el archivo config raíz para que todos los servicios puedan verla. Además vamos a crear la información para la cadena de conexión y le vamos a indicar como queremos que se llame la base de datos de seguimiento para que el wizard la construya si no existe. Por último, podemos verificamos los usuarios a los que les quedamos dar los permisos de administradores, lectores de la información generada y los editores de esta información.

image

Una vez finalizado le damos aceptar y se procederá con el procedimiento de configuración. Cuando la etapa esté lista nos aparece el siguiente mensaje:

image

En la pantalla inicial del wizard podemos ver que la configuración de este componente esta correcta. Ahora procedemos con la configuración de la persistencia de los workflows la cual es muy similar a la del seguimiento; aquí seleccionamos el proveedor de persistencia que queremos usar – sql server en este caso – y seleccionamos configurar.

image

Al igual que en el caso anterior procedemos a seleccionar las opciones marcadas en la siguiente pantalla para crear la configuración del servicio, la base de datos y el string de conexión general para las aplicaciones.

image

El resultado de la operación se verá a través del mensaje lanzado desde el wizard.

image

El siguiente ítem a configurar es el manejo del caché distribuido. Este es muy importante si las aplicaciones van a estar en un clúster y queremos crear un caché que nos permita reutilizar toda la información que deseamos tener de forma mucho más rápida que ir al repositorio. En este caso seleccionamos el proveedor de XML, ya que el proveedor de SQL Server solo funciona en una máquina que pertenezca a un dominio. También debemos seleccionar el tamaño del clúster con el que vamos a utilizar el caché. Luego de esto seleccionamos la opción configurar en el proveedor de configuración del caché.

image

Es importante indicar que el UNC del archivo XML debe de ser un directorio compartido. Ahora seleccionamos siguiente y nos aparece la opción de configurar el caché. Este paso lo dejamos así ya que es una característica que no vamos a utilizar inicialmente con el AppFabric.

image

La última pantalla nos permite iniciar el IIS para verificar que las opciones del IIS están configuradas y funcionando.

image

Ya en el IIS podemos verificar que tenemos las opciones de persistencia y seguimiento como válidas y disponibles.

image

Etiquetas de Technorati: