viernes, 23 de mayo de 2014

Utilizando Self-hosting Windows Communication Foundation y PostgreSQL.

Windows Communication Foundation es la parte del .NET Framework que define un modelo de programación común y una API unificada basada en estándares industriales de comunicación para construir aplicaciones distribuidas interoperables que se comunican entre sí mediante el intercambio de mensajes y así cubrir la mayor parte de los requerimientos en computación distribuida.

WCF incluye todas las tecnologías de comunicación abiertas como XML, SOAP y JSON y propietarias de Microsoft como MSMQ, COM+ y .NET Remoting.

Aunque en teoría se pueden construir servicios sin WCF, en la práctica utilizar WCF para construir servicios es mucho más práctico que hacerlo desde cero (start from scratch).

En resumen WCF consiste de un número de bibliotecas .NET que se utilizan para aplicaciones orientadas a servicios.

Antes de empezar con el ejemplo es importante tener claras algunas definiciones que son necesarias para entender el funcionamiento de WCF:

  1. Endpoint: En los sistemas orientados a servicios, es el lugar en donde los mensajes van y vienen cada endpoint requiere de tres elementos: Address, Binding y Contract. Pueden ser especificados de forma imperativa o declarativa.
  2. Address: En donde el servicio se encuentra disponible. Es un URL que se puede formar de 4 partes: Schema, machine, port y path.
  3. Binding: Como se puede acceder al servicio.
  4. Contract: Que operaciones ofrece el servicio.
  5. Servicios: Son procesos independientes definidos por su interfaz.
  6. Componentes: son los bloques de construcción a nivel plataforma tales como las bibliotecas (.dll) que se ensamblan en tiempo de diseño o en tiempo de ejecución.
  7. Objetos: Son los bloques de construcción del nivel más bajo que se encuentran dentro de los componentes y los servicios.

Hay que tener en cuenta que no importa que protocolo se use para el intercambio de mensajes desde las aplicaciones hasta el servicio, WCF siempre representará el mensaje como un objeto Message.

En resumen los servicios WCF son solo objetos que exponen una serie de operaciones que las aplicaciones clientes necesitan invocar. Cuando se construye un servicio se describen estas operaciones mediante un contrato (una interfaz) que debe tener una implementación (clase).

Para que el servicio esté disponible a los clientes se debe de instalar en un entorno de ejecución que hospede el servicio. Hay varias formas en las que puedes hospedar el servicio, puedes usar Internet Information Services (IIS), Windows Activation Services (WAS) y self-host managed applications como una consola de windows o un servicio de Windows.

En el siguiente ejemplo mostraré como utilizar los plantillas de Visual Studio para construir una aplicación con la técnica de self-hosting en la cual el desarrollador es responsable de implementar y administrar el ciclo de vida del proceso de alojamiento.

Este ejemplo utiliza un servicio WCF que realiza la búsqueda del nombre de un producto en una tabla de productos dentro base de datos postgreSQL.

Aquí el script de la tabla de productos

1-.Abrimos Visual Studio y en el explorador de soluciones agregamos un proyecto del tipo WCF Service Library.

2-. Nombramos este proyecto como: Test.WCF.Services

3-.A este proyecto le agregamos dos archivos: la interfaz IProductsContract y la clase ProductsImplementation.

Aquí el código de IProductsContract

Aquí el código de ProductsImplementation.

En este código utilizamos unos ensamblados llamados Tests.WCF.Services.Objects y Tests.WCF.Services.Data que contienen el código de datos y un DTO, este código lo omito en la explicación para centrarme en la construcción del WCF, sin embargo el proyecto completo lo incluyo en el código fuente de la solución.

4-. Agregamos un proyecto del tipo aplicación de consola a nuestra solución, con el nombre: ConsoleHostingService

5-. Tecleamos el siguiente código en la clase Program:

Este código muestra la construcción de un Self-Hosted Service , en la línea siguiente creo el Uniform Resource identifier representado por la clase URI.

 Uri baseAddress = new Uri("http://localhost:8004/");

Después asigno el tipo de objeto de la implementación a una variable.

 Type service = typeof(Tests.WCF.Services.ProductsImplementation);

Ahora hago una instancia de la clase ServiceHost que es la clase que proporciona WCF para alojar endpoints de WCF en las aplicaciones .NET, una vez teniendo la instancia hay que decirle el tipo del servicio que debe inicializarse para recibir las peticiones así como establecerle el endpoint para que los cliente sepan donde enviar las peticiones.

ServiceHost host = new ServiceHost(service, baseAddress);

Bien ahora hay que invocar el método host.Open(); para cargar el runtime de WCF y empezar a escuchar las peticiones.

using (host)
      {
        Type contract = typeof(Tests.WCF.Services.IProductsContract);
        host.AddServiceEndpoint(contract, new WSHttpBinding(), "Products");
        host.Open();
        Console.WriteLine("Products service running.Press  to quit.");
        Console.ReadLine();
        host.Close();
     }

La flexibilidad de self-hosting aplica cuando las aplicaciones son (in-proc), esto es que las aplicaciones están en el mismo proceso que el cliente.

Aquí el código del programa cliente.

Es importante que antes de ejecutar el programa cliente, se ejecute primero el programa que contiene el proceso ServiceHost esto lo podemos configurar en VS, en el submenú Set Startup Projects debajo del menú Debug en VS.

Aquí la búsqueda en la tabla utilizando el Query Management de PgAdmin

Ahora ejecutamos la misma búsqueda, solo que remotamente con la solución de VS, primero ejecutamos el proyecto ConsoleHostingService.

Inmediatamente después ejecutamos el proyecto ConsoleHostingClient.

Iniciamos con la búsqueda de productos, tecleamos la coincidencia a buscar y pulsamos ENTER, esto hará que se mande la petición al servicio WCF.

lunes, 19 de mayo de 2014

Deshabilitar el modo autocommit de transacciones en SQL Server

Hay 3 modos básicos de transacciones con los cuales trabaja SQL Server. Estos modos son:

  1. AutoCommit: Cada comando SQL/T-SQL tiene su propio espacio de transacción y automáticamente se hace la confirmación (COMMIT) cuando el comando termina.
  2. Explicit: En este modo se indica el inicio y el final de una transacción de manera programática. Utilizando los comandos: BEGIN TRAN , COMMIT TRAN y ROLLBACK TRAN. Este modo es comúnmente utilizado en store procedures o scripts.
  3. Implicit: En este modo, cuando emites ciertos comandos SQL Server automáticamente empieza una transacción. Entonces debes de confirmar o deshacer la transacción explícitamente utilizando los comandos COMMIT/ROLLBACK.

Autocommit es el modo predeterminado en SQL Server para las transacciones. Aunque este modo puede ser cómodo para el programador ya que no se tienen que escribir los comandos implicitos para abrir y cerrar una transacción, esto resulta peligro en ciertas ocasiones sobre todo si los datos con los que estamos trabajando se encuentran en un ambiente productivo.

Una manera de disminuir ese riego es deshabilitar el modo autocommit.

Esto se logra habilitando el modo de transacciones implícitas con el comando:

SET IMPLICIT TRANSACTIONS ON

Mostraré un ejemplo, habilitaré el modo de transacciones implícitas en SQL Server 2012 y agregaré un registro nuevo a la tabla HumanResources.Department de la base de datos AdventureWorks2012.
Ejecuto los siguientes comandos para agregar un registro.

SET IMPLICIT TRANSACTIONS ON
go
Insert into HumanResources.Deparment(Name,GroupName,ModifiedDate)
values('Software Developer','Research and Development',getdate())
go

Consulto la tabla para ver que se agregó el registro a la tabla.

SELECT * FROM HumanResources.Department ORDER BY DepartmentID DESC

Hasta este punto, si ejecuto ROLLBACK puedo deshacer la modificación a la tabla, si vuelvo a consultar la tabla los datos son los mismos que estaban almacenados antes del INSERT.

ROLLBACK

Vuelvo a ejecutar el INSERT si ahora deseo que la modificación sea permanente, tengo que ejecutar un COMMIT.

Vuelvo a consultar los datos de la tabla y comprobamos que el registro se guardo de forma permanente.

En este modo, si hay comandos que no han sido confirmados (COMMIT) o rechazados (ROLLBACK), SQL Management nos avisa al momento de cerrar la aplicación.

miércoles, 7 de mayo de 2014

Utilizando Message Queue con C# en .NET Parte II

Continuando con el tema de Microsoft Message Queue, mostraré como recibir un mensaje almacenado en la cola de espera. En la primera parte de este tutorial enviamos un mensaje a una cola de espera por lo que ahora hare un programa que utilice el método Receive() de la clase MessageQueueHelper que puse de ejemplo en la primera parte de este tutorial para obtener ese mensaje y mostrarlo.

Hay que recordar que MSMQ trabaja con un principio FIFO (First In, First Out) lo que significa que el primer mensaje en la cola es el mensaje que recuperarás utilizando los métodos Receive() o Peek() de la clase MessageQueue.

Aquí el código fuente del programa:

Al ejecutar el programa se verá la siguiente salida:

Ahora voy a explicar cómo funcionan los métodos de la clase MessageQueueHelper. El método CreateQueue() recibe tres parámetros que indican las siguientes propiedades:

  1. Path: Indica la ubicación de la cola de espera.
  2. Transactional: Especifica si la cola puede aceptar transacciones de mensajes.
  3. Label: El título que describe de la cola de espera.
Para el valor del Path, el “.” Indica que estamos creando la cola de espera en la maquina local y utilizamos el prefijo Private$ para indicar que es una cola de espera privada, si omites este prefijo indica que la cola de mensajes es pública.

 queue = MessageQueue.Create(queuePath,isTransactional);
 queue.Label = label;

En el método SendMessage() utilizamos le asignamos la clase XmlMessageFormatter para dar un tipo de formato al mensaje. Los MessageFormatters implementan la interfaz IMessageFormatter, la cual puede ser aplicada a un mensaje o a toda la cola de espera. Es indispensable que utilices el mismo MessageFormatter tanto para enviar o para recibir el mensaje. Aquí una lista de los Formatters:

  1. ActiveXMessageFormatter: Se utiliza para trabajar con componentes COM.
  2. BinaryMessageFormatter: Utilizado para serializar o deserializar un mensaje en un formato binario.
  3. XMLMessageFormatter: El formatter predeterminado, serializa y deserializa en formato XML.
Aquí está el código donde se utiliza:

 queue = new MessageQueue(queuePath);
 queue.Formatter = new XmlMessageFormatter();

Por último en el método GetMessage() igual que para enviar el mensaje utilizo una clase MessageFormatter para deserializar el mensaje, también utilizo el método Receive() de la clase MessageQueue para obtener el primer mensaje de la cola de forma síncrona, como argumento recibe un TimeSpan que representa el intervalo de tiempo de espera para recibir el mensaje, este argumento es importante o de lo contario si no se recibe el programa se bloqueara hasta que no haya recibido el mensaje.

 queue = new MessageQueue(queuePath);
 queue.Formatter = new XmlMessageFormatter(new Type[]{
 Type.GetType("System.String")
 });
 queueMessage = queue.Receive(new TimeSpan(0,0,2));
 message = queueMessage.Body.ToString();

lunes, 5 de mayo de 2014

Utilizando Message Queue con C# en .NET

Microsoft Message Queue (MSMQ) es un servicio de Windows que permite la comunicación interproceso entre diferentes computadoras de forma asíncrona, entender cómo funciona puede resultar útil en cualquier momento que los clientes y los servidores no tengan una conexión disponible, ya que los mensajes entre ellos son encolados para su transmisión hasta que ambos estén conectados.

El funcionamiento básico de MSMQ es parecido al de una mensajería entre aplicaciones de software, una aplicación prepara un mensaje y lo escribe hacia una línea de espera o cola de mensajes MSMQ. En este contexto una cola de mensajes es un área de almacenamiento temporal que guarda los mensajes hasta que sean transmitidos. El administrador de colas actúa como un intermediario que transmite el mensaje desde su aplicación origen hasta su destino. El propósito de la cola de mensajes MSMQ es el enrutamiento y garantizar la entrega del mensaje, en caso de que el destinatario del mensaje no esté disponible la cola de mensajes mantendrá el mensaje hasta que pueda ser entregado con éxito.

Este mecanismo de transporte proporciona los siguientes beneficios:

  1. Robustez: Los mensajes son almacenados en la línea de espera hasta que son procesados. Si se cae la conexión entre un cliente y un server los mensajes se guardan hasta que una conexión este presente.
  2. Mensajería basada en prioridad:Los mensajes más importantes son los primeros en ser recibidos, después los mensajes que le siguen y así sucesivamente, hasta que los últimos son los de prioridad más baja.
  3. Garantía de entrega:Cuando se llaman los mensajes a través de la red, MSMQ utiliza una transacción para entregar los mensajes, si se lee un mensaje de la línea de espera y ocurre un error se hace un rollback y el mensaje regresa a la línea de espera.
  4. Seguridad: La tecnología de MSMQ utiliza la seguridad de Windows para proporcionar el control de acceso, la auditoría, encriptación y autenticación de mensajes, de hecho el ensamblado System.Messaging es un wrapper para una API nativa.

Hay tres tipos de líneas de espera en MSMQ:

  1. Públicas: están registradas en el Active Directory y permiten a todas las maquinas enviar y recibir mensajes a través de la red.
  2. Privadas: solo se crean en la máquina local y pueden ser únicamente accedidas desde otra máquina si se conocen los nombres exactos de la máquina y de la línea de espera.
  3. Sistema: son principalmente utilizadas para propósitos administrativos o para aplicaciones que necesitan una línea de espera que guarde copias de los mensajes que son procesados, por ejemplo las aplicaciones de auditoría.

Como ejemplo de la utilización de MS Message Queue con C#, hice el siguiente programa que consta de dos clases: MessageQueueHelper y TestMessageQueue, la primera clase tiene los métodos para crear la cola (CreateQueue), enviar mensaje (SendMessage) y recibir mensaje (GetMessage), la segunda clase es un programa que muestra el uso de los métodos (CreateQueue) y (SendMessage).

Aquí el código de la clase MessageQueueHelper

using System;
using System.Messaging;

namespace Samples{
 public class MessageQueueHelper{
static MessageQueue queue = null;
public static Guid CreateQueue(string queuePath,
  bool isTransactional,
  string label)
{
 if(MessageQueue.Exists(queuePath))
  queue = new MessageQueue(queuePath);
 else
 {
  queue = MessageQueue.Create(queuePath,isTransactional);
  queue.Label = label;
 }
 return queue.Id;

}

public static void SendMessage(string queuePath,
  string message,string subject)
{
 message += "\nCreated on " + DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss");
 MessageQueueTransaction trans = null;
 if(MessageQueue.Exists(queuePath))
 {
  queue = new MessageQueue(queuePath);
  queue.Formatter = new XmlMessageFormatter();
  if(queue.Transactional)
  {
  trans = new MessageQueueTransaction();
  trans.Begin();
  }
  queue.Send(message,subject);

  if(queue.Transactional)
   trans.Commit();
  Console.WriteLine("Message sent.");
 }else
  Console.WriteLine("The queue doesn't exist");
}

public static string GetMessage(string queuePath)
{
 string message = null;
 Message queueMessage = null;
 if(MessageQueue.Exists(queuePath))
 {
  queue = new MessageQueue(queuePath);
  queue.Formatter = new XmlMessageFormatter(new Type[]{
    Type.GetType("System.String")
    });
  queueMessage = queue.Receive(new TimeSpan(0,0,2));
  message = queueMessage.Body.ToString();
 }
 else
  message = "That queue doesn't exist";
 return message;
}

 }
}

Bien ahora el código de la clase TestMessageQueue que prueba los métodos de la clase anterior.

using System;

namespace Samples{
public class TestMessageQueue{
public static void Main(string[] args){
bool isTransactional = false;
Console.WriteLine("\nTest MSMQ\n");
try
{
 Console.Write("\nEnter path > ");
 string path = Console.ReadLine();
 Console.Write("\nIs transactional? (1=true/0=false) > ");
 string sTransactional = Console.ReadLine();
 if(sTransactional.Equals("1"))
  isTransactional = true;
 Console.Write("\nEnter a label > ");
 string label = Console.ReadLine();
 Guid guid = MessageQueueHelper.CreateQueue(path,isTransactional,label);
 Console.WriteLine("\nMessageQueue created with guid {0}\n",guid);
 Console.Write("\nMessage subject > ");
 string subject = Console.ReadLine();
 Console.Write("\nMessage to send > ");
 string message = Console.ReadLine();
 Console.WriteLine();
 MessageQueueHelper.SendMessage(path,message,subject);
}
catch(Exception ex){
 Console.WriteLine(ex.Message);
}
}

}
}

Al ejecutar el programa solicitará los siguientes parámetros:

  • Path: Es el nombre de la cola de espera.
  • Is transactional: 1 si la cola es transaccional, 0 si no lo es.
  • Label: Identificador de la cola.

Al crearse la cola de mensajes el programa regresará el identificador: 00000000−0000−0000−0000−000000000000 por tratarse de una cola de mensajes privadas (private MSMQ).

Ahora el programa solicitará el título y el cuerpo del mensaje, después lo enviará hacia la cola de mensajes creada.

Para ver la cola de mensajes creada con el programa y el mensaje enviado, ejecutamos Computer Management de Windows que se encuentra en la ruta Control Panel\System and Security\Administrative Tools y debajo del nodo de Services and Applications veremos el nodo Private Queues debajo del nodo Message Queuing donde se encuentra la línea de espera creada con el programa de ejemplo.

Debajo de la cola de espera myfirstqueue, se encuentra la carpeta Queue messages en donde se puede ver la etiqueta del mensaje.

Si hacemos doble click en el mensaje aparecerá una ventana con cuatro pestañas en donde podemos ver las propiedades del mensaje, en la pestaña body podemos ver el contenido del mensaje.