jueves, 13 de febrero de 2014

Conclusiones Generales del Curso Desarrollo de Sistema Distribuidos EPE 2014-0

El desarrollo de la tecnología informática ha conducido a la interconexión de los computadores individuales en redes que permiten el acceso mutuo a recursos compartidos. El siguiente paso es la integración de recursos y servicios en sistemas distribuidos, que proporcionan al usuario y a las aplicaciones interoperaby acceso transparente. Este curso está orientado a presentar algunos de los modelos y arquitecturas más relevantes de los sistemas distribuidos de hoy en día y los conceptos que los sustentan. En particular, el curso se centra en  los sistemas replicados y tolerantes a fallos.

A lo largo del cursos hemos aprendido grandes pilares de las tecnologías como lo que es
SOAP y REST los cuales nos brindan un esquema diferente de programación  de una manera ágil y dinámica .

Ello también dio un esquema diferente a el entorno de trabajo en el cual nos desenvolvemos y gracias este curso podemos brindar mayores soluciones en  nuestros proyectos .








Manejo de Excepciones con SOAP Services .NET

Cuando normalmente nos comunicamos con servicios Web SOAP, estos se encargan de enviarnos mensajes de advertencias o de errores cuando algún dato o información no permite avanzar mas en un proceso.

Por esto en el siguiente manual se mostrará como trabajar con una exception en un servicio SOAP y como capturarlo desde una llamada de algún controlador Web.

1. Luego de haber creado la Aplicacion de servicio y los métodos en el services, procedemos a crear una clase Exception como se muestra en la siguiente imagen


2. Luego, declaramos un FaultContract en el método de la clase Interface que se encarga de manejar la exception.


3. Continuando dentro del servicio, validamos nuestra información declarando la Exception creada y su vez realizamos un Throw new FaultException.


4. Después, ya en el proyecto Web, referenciamos a nuestro servicio SOAP y manejamos nuestro algoritmo con un Try {} Catch {}, donde en el catch se declarará otra vez un Fault Exception del Tipo Exception creado en un principio.

5. Finalmente el controlador retornará vía JSON el mensaje con el error que se mostrará en la Vista.



Mensajes a travez de SOAP

Estructura de un mensaje

Un mensaje SOAP es un documento XML que consta de los siguientes elementos:
  • envoltorio (envelope) que define el contenido del mensaje
  • cabecera (header) que es opcional y que contiene información referente a la cabecera del mensaje
  • cuerpo (body) que contiene la información de la llamada y de la respuesta

Ejemplo de comunicación (sin cabeceras HTTP):

Supongamos que tenemos una sencilla aplicación en la que hay una clase HelloServer que tiene un método llamado sayHello() que recibe como parámetro una cadena de caracteres que será el nombre de la persona a quien saludaremos: el mensaje generado por el cliente sería:
<SOAP-ENV:Envelope>
  <SOAP-ENV:Body>
    <sayHello>
      <name>Pepe</name>
    </sayHello>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
el mensaje devuelto por el servidor sería:
<SOAP-ENV:Envelope>
  <SOAP-ENV:Body>
    <sayHelloResponse>
      <return>Hello, Pepe</return>
    </sayHelloResponse>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Como vemos, la principal diferencia entre ambos mensajes (XML) es que la respuesta se encuentra en una etiqueta que se llama como el método invocado más la palabra Response (indicando que es la respuesta).

Ejemplo de comunicación (completo, con cabeceras HTTP):

el mensaje generado por el cliente sería:
POST /InStock HTTP/1.1
Host: www.stock.org
Content-Type: appliation/soap; charset=utf-8

<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encondingStyle="http://www.w3.org/2001/12/soap-encoding">
  <soap:Body xmlns:m="http://www.stock.org/stock">
    <m:GetStockPrice>
      <m:StockName>IBM</m:StockName>
    </m:GetStockPrice>
  </soap:Body>
</soap:Envelope>
el mensaje devuelto por el servidor sería:
HTTP/1.1 200 OK
Connection: close
Content-Type: appliation/soap; charset=utf-8
Date: Sat, 12 May 2002 08:09:04 GMT

<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encondingStyle="http://www.w3.org/2001/12/soap-encoding">
  <soap:Body xmlns:m="http://www.stock.org/stock">
    <m:GetStockPriceResponse>
      <m:Price>34.5</m:Price>
    </m:GetStockPriceResponse>
  </soap:Body>
</soap:Envelope>

Gestión de errores

Cuando ocurre un error en una comunicación con SOAP, dicho error se transmite en forma de elemento de fallo (Fault Element). Sólo puede aparecer un elemento de fallo, y de aparecer, debe hacerlo en el cuerpo del mensaje.
El contenido de un elemento de información de error es el siguiente:
  • <faultcode> : código que identifica el error
  • <faultstring> : error representado en forma de cadena de caracteres
  • <faultactor> : causante del error
  • <detail> : información específica del error
Por ejemplo, si se hubiera producido una división por cero, obtendríamos el siguiente documento XML:
<SOAP-ENV:Envelope>
  <SOAP-ENV:Body>
    <SOAP-ENV:Fault>
      <faultcode>SOAP-ENV:Server</faultcode>
      <faultstring> / by zero </faultstring>
      <faultactor>/soap/servlet/rpcrouter</faultactor>
    </SOAP-ENV:Fault>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

¿Cómo crear un simple servicio WCF Rest?

He aquí una manera sencilla de hacerlo es como lo hicimos en clase, solo hay que seguir los siguientes pasos:
Paso 1: Crear una biblioteca de C#

Inicia Visual Studio 2010, creamos una solución en blanco y agregamos una biblioteca en C# llamada 'Services'.

Paso 2: Definamos ahora un servicio Restful y Dto.

Para crear un servicio WCF que gestiona una petición GET, debemos definir la siguiente interfaz y la implementación que muestro a continuación.

IInvoiceService.cs
using System.ServiceModel;
using System.ServiceModel.Web;

namespace Services
{
    [ServiceContract]
    public interface IInvoiceService
    {
        [WebGet(UriTemplate = "/invoices")]
        [OperationContract]
        InvoiceDto[] GetAllInvoices();
    }
}

InvoiceService.cs
namespace Services
{
    public class InvoiceService : IInvoiceService
    {
        public InvoiceDto[] GetAllInvoices()
        {
            return new[] { new InvoiceDto(1, "receiver1"), new InvoiceDto(2, "receiver2") };           
        }
    }
}

Para importar estos atributos tendremos que agregar referencias System.ServiceModel y System.ServiceModel.Web

Luego agregamos los Dto. Los Dto's necesitan estar marcados con los atributos DataContract y DataMember para que puedan ser serializado por WCF.

InvoiceDto.cs
using System.Runtime.Serialization;

namespace Services
{
    [DataContract(Namespace = "")]
    public class InvoiceDto
    {
        public InvoiceDto(int id, string receiver)
        {
            Id = id;
            Receiver = receiver;
        }

        [DataMember]
        public int Id { get; set; }
        [DataMember]
        public string Receiver { get; set; }
    }
}

Paso 3: Alojamiento

Hay un montón de maneras para hostear un servicio WCF restful. Se podría crear una aplicación de consola y alojarlo ahí. Se podría crear un nuevo sitio web ASP.NET (con WCF habilitado) y hostearlo ahí.

Sin embargo, por simplicidad (y porque así es como lo estamos tratando en nuestro proyecto) creemos un "WCF Service Application' de la siguiente manera.


Nuestro nuevo proyecto Host se crea con un archivo svc. Ahora el proyecto tiene un archivo svc por servicio.

En nuestro caso, no es necesario el Service1 que se crea por defecto y que viene con la aplicación (de aquí en adelante eliminaremos o modificaremos aquellos archivos que se crean con el proyecto).

Ahora, modificaremos el archivo Service1.svc y  demás referencias.


Service.svc

<%@ ServiceHost Service="Services.InvoiceService" Factory="System.ServiceModel.Activation.WebServiceHostFactory"  %>

Esta WebServiceHostFactory es una nueva clase introducida en WCF 3,5 para hacer servicios WCF Restful. Mediante su uso, no se necesita ninguna configuración WCF en nuestro archivo WebConfig.

De hecho, para el propósito de esta demostración completamente puede deja vacío el web.config, como se muestra a continuación.


Host del WCF / web.config

<?xml version="1.0"?>
 <configuration>
</configuration>

Paso 4: Poner a prueba nuestro servicio en el navegador.

Ahora bien, si todo funciona, deberíamos ser capaces de hacer clic derecho en Service1.svc de nuestro proyecto creado y seleccionar la opción 'Ver en el explorador'.
Esto lanzará nuestro servicio y mostrará una página en blanco con el mensaje "End point not found'. Eso está bien.
La verdadera prueba para nosotros es cuando añadimos la extensión GET '/ invoices' a la URL. Cuando hacemos eso, deberíamos obtener algo como esto:



Algo a tener en cuenta ...

Ahora bien, vemos que es fácil crear un servicio en WCF.

Pero no podemos autogenerar proxies del lado del cliente utilizando WCF.
Rest (HTTP) no es lo mismo que WSDL (SOAP contract es utilizado por Visual Studio para crear los proxies).
No se puede crear automáticamente servidores proxy. Pero esto puede cambiar en futuras versiones de WCF (y que Microsoft ha indicado que va a ser mucho más fácil trabajar con Resftul). Pero por ahora, para llamar a este servicio desde una prueba unitaria, tenemos que crear nuestro propio proxy o trabajar con uno básico de .NET Http Constructos como WebHttpRequest y WebHttpResponse, como se muestra a continuación.

using System.Net;
using NUnit.Framework;

namespace Test
{
    [TestFixture]
    public class When_calling_a_restful_service
    {
        [Test]
        public void Should_get_proper_HTTP_codes_and_headers()
        {

            var url = "http://localhost:49619/Service1.svc/invoices";
            var request = (HttpWebRequest)WebRequest.Create(url);
            var response = (HttpWebResponse)request.GetResponse();

            Assert.AreEqual(200, (int)response.StatusCode);
        }

    }
}


Estas son algunas de las cosas que estamos aprendiendo a medida que repunte algunas cosas de implementación como Restful con WCF, SOAP, etc. Espero les haya gustado.

Lo Aprendido REST VS SOAP

Aunque REST y SOAP son arquitecturas muy similares de intercambio de información entre aplicaciones web y de escritorio con servidores, antes de decidirse por uno de ambas es importante tener en cuenta las siguientes consideraciones. Trataré de ser objetivo en este artículo ya que hasta hace poco empecé a utilizar REST (4 meses), todo lo que aprendí sobre websvices esta basado en SOAP.
Primeramente hay que entender que REST esta basado en una arquitectura donde se identifican los recursos claves a consumirse.. veámoslo como una forma semántica de escritura ante la web donde hay métodos que al ser interpretados nos retornan información… Algo como por ejemplo utilizando el método GET del protocolo HTTP (digo GET porque también se puede utilizar POST, PUT, HEAD, DELETE, etc.. ) haría una petición de la siguiente manera: “http://servidor.com/api/proyecto/1/tarea/5″  .. donde api es el contenedor de mi webservice y lo que sigue sería equivalente a decir.. Del proyecto con identificador no. 1 seleccionar la tarea con identificador no. 5 y mostrar el resultado en formato json o xml.
Así de fácil es REST, mientras que SOAP es un poco más complicado por que lo que se consumen son métodos o funciones almacenadas igualmente en un servidor.. entonces si quisiera hacer lo mismo.. en SOAP tendría que escribir algo como lo siguiente: “http://miservidor.com/api/calcula” donde calcula contiene una definición de funciones (sumar y restar) que se pueden implementar mediante la creación de un objeto, un concepto de la programación orientada a objetos .. del uso de alguno de los métodos listados en el servicio calcula como respuesta obtendría una salida en xml con una definición del tipo de datos que respondió el servidor..
Si se fijan ambos tipos de conexión ya sea REST o SOAP se parecen mucho, ya que sirven para solicitar información a un servidor, pero distan de implementarse de una manera similar.. verán que REST es mucho más fácil y SOAP conlleva escribir un poco más de código..
En la actualidad muchos de los servicios que utilizamos a diario como twitter, facebook, fourquare, delicious, flickr, etc.. estan basados en REST por la facilidad de imlementación y la simplesa que se obtiene en los resultados.
SOAP ya que tiene una arquitectura de respuesta más compleja, es utilizado comunmente en corporaciones, hasta me atrevería a decir que la mayoría de empresas que utilizan sistemas basados en .NET o Java tienen sus servicios de comunicación basados en SOAP .. porque ha decir verdad es muy fácil implementar esos objetos y consumir esos métodos.. porque claro!! hay personas que ya hicieron todo el trabajo pesado de crear librerías que se usan casi con un par de líneas. Además que en estos lenguajes se tienen componentes visuales que se conectan casi de manera transparente a webservices basados en SOAP por lo que como dije.. ya todo lo interesante ya se hizo.
Entonces ya que tenemos una mejor idea de que hace REST vs SOAP podemos hacer comparaciones y obtener una conclusión..
REST
En lo que es genial
  • Es muy ligero, sus respuestas contienen exactamente la información que necesitamos.
  • Para los nosotros los humanos es muy fácil y simple de interpretar.
  • Es sencillo de desarrollar y no se necesita mucho código extra.
  • Es flexible en cuanto al tipo de respuesta que se necesita, ya que puede ser xml o json.
En lo que falla
  • Creo que la seguridad es un problema y puede llegar a ser una tarea muy difícil implementarla correctamente.
  • No hay un estándar en sus respuestas por lo que no se definen tipos de datos.
SOAP
En lo que es genial
  • Si trabajas con componentes y utilizas .NET o Java es muy sencillo de consumir.
  • El resultado que siempre es XML contiene una definición específica del tipo de dato, lo que hace del protocolo algo muy estricto.
  • Se dice que es más seguro porque su implementación siempre o la mayoría de las veces se hace del lado del servidor.
En lo que falla
  • Una vez implementado, si se desea cambiar algo en el servidor impacta de forma negativa en los clientes ya que estos tienen que hacer muchas modificaciones al código.
  • Las respuestas son demasiado complejas y difíciles de interpretar si no se tienen las herramientas correctas para hacerlo.
Ejemplo de Vista de Ejecución.

REST


SOAP



Conclusión
Creo que ambas arquitecturas de intercambio de información tienen sus nichos bien definidos, cuando se trata de aplicaciones públicas refiriéndome a servicios de uso masivo es mucho mejor utilizar REST por la sencillez en su implementación y respuestas, inclusive en clientes móviles es mucho más fácil utilizar REST. Por otro lado si se esta pensando en webservices para corporaciones donde se manejan datos complejos y se necesita una presición detallada en las respuestas se debe de utilizar SOAP, entornos de desarrollo como Visual Studio hacen que el desarrollo e implementación de SOAP sea sumamente sencillo sin tener que escribir código de más para interpretar respuestas.