780 likes | 923 Views
XML, Distribución y Componentes Tema 3 – Aplicaciones Distribuidas: Servicios Web http://paginaspersonales.deusto.es/dipina/MasterISW/. Dr. Diego Lz. de Ipiña Gz. de Artaza http://paginaspersonales.deusto.es/dipina (Personal) http://www.morelab.deusto.es (Research Group)
E N D
XML, Distribución y ComponentesTema 3 – Aplicaciones Distribuidas: Servicios Webhttp://paginaspersonales.deusto.es/dipina/MasterISW/ Dr. Diego Lz. de Ipiña Gz. de Artaza http://paginaspersonales.deusto.es/dipina (Personal) http://www.morelab.deusto.es (Research Group) http://www.smartlab.deusto.es (Research Lab) http://www.ctme.deusto.es (Cátedra de Telefónica Móviles) http://www.tecnologico.deusto.es (Tecnológico-Fundación Deusto)
Temario • Procesamiento XML en .NET (21 y 22 Febrero) • Estándar .NET [XML.NET] • Soporte XML [XML-SAX, XML-DOM, Validación] • XSL [XPath, XSLT, Scripts, Objetos de extensión] • Aplicaciones distribuidas (23 Febrero, 5 Marzo) • XML/SOAP • .NET Remoting • Mensajería • Componentes .NET (6 y 7 Marzo) • Metadatos y Reflexion • Componentes .NET y Enterprise Services • Complementos • Interoperabilidad COM y P/Invoke • COM+ y MTS • MSMQ (colas de mensajes) • Microsoft Communication Foundation (Indigo)
Contenidos Parte Aplicaciones Distribuidas • WebServices y SOAP • .NET Remoting • Mensajería
Introducción I • Los Servicios Web son la piedra angular de la iniciativa .NET • Los ordenadores hablan unos a otros a través de la web usando HTTP y otros protocolos. • Un servicio web no tiene interfaz gráfica • Provee una API de métodos que pueden ser invocados en la web • Diseñados para proveer “servicios” • .NET hace muy sencillo poder crear servicios web
Introducción II • Futuro en el que los negocios exponen aplicaciones a clientes como Servicios Web en los cuales se paga por su uso • Los sistemas de diferentes empresas cooperan unos con otros a través de la Web • Mientras que DCOM está basado en estándares propietarios, los Servicios Web lo están en XML y HTTP • Son independientes de la plataforma y del lenguaje como CORBA, pero más aceptados • En .NET, IIS y la infraestructura ASP.NET compilan las fuentes, construyen contratos WSDL y manejan las peticiones y respuestas de los servicios web.
SOA • Los servicios web han dado lugar a un nuevo modo de diseñar sistemas distribuídos: • Arquitecturas SOA (Service Oriented Arquitecture) • SOA = colección de servicios • Más información en http://www.service-architecture.com/ • http://msdn.microsoft.com/Longhorn/understanding/pillars/Indigo/default.aspx?pull=/library/en-us/dnbda/html/srorientwp.asp
Servicios Web • Son un estándar basado en protocolos abiertos como HTTP y SOAP • SOAP es un vocabulario XML que representa RPCs • http://www.w3.org/TR/SOAP • No necesitas ni Windows ni .NET para escribir servicios web • Servicio web = aplicación que: • se ejecuta en un servidor web • expone métodos a clientes • escucha peticiones HTTP representando comandos que invocan a métodos Web • ejecuta métodos web y devuelve resultados
Servicio Web Hola Mundo I • Creamos el directorio virtual ws: • Hacemos doble click en Herramientas Administrativas • Doble click en Internet Information Services
Servicio Web Hola Mundo II • Creamos el directorio virtual ws: • Hacemos clic con el botón derecho del ratón en Default Web Site y luego seleccionamos NewVirtual Directory • Seleccionamos el directorio donde vamos a dejar los fichero accesibles por el contexto ‘ws’
Servicio Web Hola Mundo III <%@ WebService Language="C#" Class="HelloService1" %> // file: helloservice1.asmx // description: hello web service - basic version using System.Web.Services; [WebService( Description="A greeting Web service", Namespace="http://tempuri.org/ws" )] public class HelloService1 : WebService { [WebMethod(Description="Greet by name.")] public string Greet(string name) { if (name == "") name = "Stranger"; return "Hello, " + name + "!"; } }
Servicio Web Hola Mundo IV • La primera línea indica que el fichero helloservice1.asmx es un servicio web programado en C#, contenido en una clase llamada HelloService1 • El atributo WebService te permite añadir: • Una descripción para el servicio web (description) • El espacio de nombres evita colisiones con otros servicios web creados por otras personas y con el mismo nombre (Namespace) • Para definir un método web es necesario etiquetar un método público con el atributo WebMethod • El parámetro Description describe el método • HelloService1 es derivado de System.Web.Services.WebService • Esto le da acceso a la propiedad Context de ASP.NET y hace disponible al servicio web los objetos Request, Response y Session.
Servicio Web Hola Mundo V • Para instalar el servicio cópialo al directorio Inetpub\wwwroot\ws • Lanza tu navegador e introduce la url: http://localhost/ws/helloservice1.asmx • La página visualizada es generada por DefaultWsdlHelpGenerator.aspx • Si quieres que la apariencia de tus servicios web varíe modifica • C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\CONFIG\DefaultWsdlHelpGenerator.aspx • Y la entrada helpgenerator en C:\WINDOWS\Microsoft.NET\Framework\<version>\CONFIG\machine.config
Servicio Web Hola Mundo VI • Propiedades de los servicios web en .NET: • Los servicios web se implementan en ficheros asmx • Todo servicio web comienza con la directiva @WebService • Debe contener al menos el atributo Class identificando a la clase que representa al servicio • Otros atributos opcionales que se pueden utilizar son ‘name’ y ‘description’, que aparecerán en la página web producida al invocar calc.asmx • HTTP, XML y SOAP están escondidos • Se pueden invocar usando HTTP GET y POST, aparte de SOAP
Servicio Web Hola Mundo VII • Un mensaje SOAP es como un sobre moviéndose de un lugar a otro • HelloService1 define un método Greet que cuando es llamado devuelve un resultado • Tanto la petición como la respuesta son mensajes SOAP • El WSDL generado soporta tres protocolos: • HttpGet usa HTTP GET para invocar el servicio • HttpPost usa HTTP POST • SOAP • Sólo SOAP puede representar tipos de datos complejos y lo usaremos de ahora en adelante.
Servicio Web Suma y Resta I <%@ WebService Language="C#" Class="CalcService" %> using System; using System.Web.Services; [WebService (Name=“Servicio Web Calculadora", Description=“Ejecuta sumas y restas simples sobre la web")] class CalcService { [WebMethod (Description=“Calcula la suma de dos enteros")] public int Add (int a, int b) { return a + b; } [WebMethod (Description=“Calcula la diferencia de dos enteros")] public int Subtract (int a, int b) { return a - b; } }
Servicio Web Suma y Resta II • Para desplegar la aplicación copia calc.asmx a C:\Inetpub\wwwroot\ws • La invocación de http://localhost/ws/calc.asmx, para sumar 2 y 2, produce: POST /calc.asmx HTTP/1.1 Host: localhost Content-Type: text/xml; charset=utf-8 Content-Length: 338 SOAPAction: http://tempuri.org/Add <?xml version=“1.0” encoding=“utf-8”?> <soap:Envelope xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance xmlns:xsd=http://www.w3.org/2001/XMLSchema xmlns:soap=http://schemas.xmlsoap.org/soap/envelope/> <soap:Body> <Add xmlns=http://tempuri.org/> <a>2</a> <b>2</b> </Add> </soap:Body> <soap:Envelope>
Servicio Web Suma y Resta III • La respuesta del servicio web es: HTTP/1.1 200 OK Content-Type: text/xml; charset=utf-8 Content-Length: 353 <?xml version=“1.0” encoding=“utf-8”?> <soap:Envelope xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance xmlns:xsd=http://www.w3.org/2001/XMLSchema xmlns:soap=http://schemas.xmlsoap.org/soap/envelope/> <soap:Body> <AddResponse xmlns=http://tempuri.org/> <AddResult>4</AddResult> </AddResponse> </soap:Body> <soap:Envelope>
Implementación de servicios web • La parte más complicada para escribir servicios web es procesar las peticiones XML que llegan vía HTTP y generar las respuestas HTTP • .NET refugia al programador de los detalles de bajo nivel de HTTP, SOAP y XML
Creando Servicios webs: calc.asmx IV • Si invocamos el formulario que aparece al ir a http://localhost/ws/calc.asmx, haciendo clic en el enlace Add, generado por ASP.NET obtenemos:
Creando Servicios webs: calc.asmx V • Los formularios que genera ASP.NET de los ficheros ASMX permiten probar los servicios web que escribes, sin desarrollar un cliente web.
Code-Behind I • Sirve para mover las clases de un ASMX a una DLL separada. • El ASMX (wwwroot\wscodebehingwebservice.asmx) contendría sólo una sentencia: • <%@ WebService Class=“CalcService” %> • Para compilar la clase utilizaríamos: • csc /t:library calc.cs • Moveríamos el DLL a: wwwroot\ws\bin
Code-Behind II // fichero: calc.cs using System; using System.Web.Services; [WebService (Name=“Servicio Web Calculadora", Description=“Ejecuta sumas y restas simples sobre la web")] class CalcService { [WebMethod (Description=“Calcula la suma de dos enteros")] public int Add (int a, int b) { return a + b; } [WebMethod (Description=“Calcula la diferencia de dos enteros")] public int Subtract (int a, int b) { return a - b; } }
La clase base WebService • Opcionalmente hacemos que los servicios web deriven de System.Web.Services.WebService • Provee objetos como Application, Session, Context, Server y User a la clase derivada, permitiendo al servicio web acceder a los objetos ASP.NET class CalcService: WebService { … }
El atributo WebMethod • Etiqueta a un método como método Web • Soporta los siguientes parámetros: • BufferResponse permite bufear repuestas • CacheDuration cachea respuestas generadas por este método • Description añade una descripción textual a un método • EnableSession permitir añadir estado de sesión a un método • MessageName le da un nombre al método • TransactionOption especifica el comportamiento de transacción del método web
Ejemplos parámetros WebMethod I • Cachea la salida por 10 segundos [WebMethod (CacheDuration=“10”)] public string GetCurrentTime () { return DateTime.Now.ToShortTimeString(); } • Guarda estado a través de las invocaciones en una sesión: class CalcService: WebService { [WebMethod (EnableSession=“true”, Description=“Añade un elemento a la cesta” public void AddToCart(Item item) { ShoppingCart cart = (ShoppingCart)Session[“MyShoppingCart”]; cart.Add(item); } }
Ejemplos parámetros WebMethod II • No se pueden sobreescribir métodos en servicios web • Solución: usar el parámetro MessageName, que da un nombre al método diferente al método que implementa [WebMethod (MessageName=“AddInts”)] public int Add (int a, int b) { return a+b; } • Los métodos web podrían ahora llamarse AddInts y AddFloats
Web Services Description Language (WSDL) I • Para exportar la interfaz y metadatos ofrecidos por un servicio web (su CONTRATO) usamos WSDL. • Métodos web exportados • Protocolos soportados • Las firmas de los métodos • Localización del servicio (URL) • WSDL es un vocabulario XML estándar documentado en http://www.w3.org/TR/wsdl. • Estas descripciones pueden guardarse en un repositorio UDDI • No entraremos en detalles ya que WSDL es para máquinas, no humanos, y .NET genera los ficheros WSDL de un servicio web muy sencillamente: • http://localhost/calc.asmx?wsdl
Web Services Description Language (WSDL) III • Si miramos al fichero WSDL encontraremos: • Elemento service que describe el servicio web • Elementos operation que documentan las operaciones • Elementos binding que documentan los protocolos soportados por el servicio web • Etc. • Para publicar un servicio web deberemos publicar su contrato, WSDL. • Otros desarrolladores pueden utilizar el contrato para desarrollar clientes web • Nomalmente procesan el fichero WSDL a través de una herramienta que genera clases wrapper • En .NET se llama wsdl.exe
Tipos de datos complejos en Servicios Web • ¿Cómo se pasan estructuras de datos e instancias de objetos en servicios web? • Son soportados porque cualquier tipo de dato puede representarse en XML • El siguiente fragmento de código ilustra la utilización del tipo de dato complejo Bookstore • El WSDL del servicio web proveerá el schema de este tipo de dato. • Dos dificultades en la utilización de servicios web con tipos complejos: • No se pueden invocar estos servicios web usando HTTP GET y POST todavía podemos usar SOAP • Todos los campos o propiedades de una clase a serializar deben ser públicas
Locator.asmx I <%@ WebService Language="C#" Class="LocatorService" %> using System; using System.Web.Services; using System.Data; using System.Data.SqlClient; [WebService (Name="Bookstore Locator Service", Description="Retrieves bookstore information from the Pubs database")] class LocatorService { [WebMethod (Description="Finds bookstores in a specified state")] public Bookstore[] FindStores (string state) { return FindByState (state); }
Locator.asmx II Bookstore[] FindByState (string state) { SqlDataAdapter adapter = new SqlDataAdapter ("select * from stores where state = \'" + state + "\'", "server=DIPINA;database=pubs;uid=sa;pwd=ingeborg"); DataSet ds = new DataSet (); adapter.Fill (ds); DataTable table = ds.Tables[0]; Bookstore[] stores = new Bookstore[table.Rows.Count]; for (int i=0; i<table.Rows.Count; i++) { stores[i] = new Bookstore ( table.Rows[i]["stor_name"].ToString ().TrimEnd (new char[] { ' ' }), table.Rows[i]["stor_address"].ToString ().TrimEnd (new char[] { ' ' }), table.Rows[i]["city"].ToString ().TrimEnd (new char[] { ' ' }), table.Rows[i]["state"].ToString ().TrimEnd (new char[] { ' ' }) ); } return stores; } }
Locator.asmx III public class Bookstore { public string Name; public string Address; public string City; public string State; public Bookstore () {} public Bookstore (string name, string address, string city, string state) { Name = name; Address = address; City = city; State = state; } }
Web Service Discovery – DISCO • ¿Cómo encontrar un servicio web? • Dos soluciones: • DISCO • Mecanismo basado en ficheros para el descubrimiento de servicios locales • Universal Description, Discovery and Integration (UDDI) • Directorio global de servicios web implementado como un servicio web • Un fichero DISCO en tu servidor web describe los servicios web disponibles en él. • Fichero XML que tiene un enlace a un contrato WSDL • Los clientes pueden interrogar el fichero DISCO para encontrar servicios y sus contratos en forma de WSDL. • Para procesar un fichero DISCO se necesita saber la URL donde se encuentra definido • Para generar un fichero DISCO: http://<url-servicio-web.asmx>?DISCO • También se pueden generar los documentos DISCO usando la utilidad disco.exe
Ejemplo DISCO • El documento DISCO contiene un enlace al contrato WSDL y un enlace a la documentación del mismo (docRef) • También provee la dirección e información binding del servicio
Creando un fichero default.disco • Apunta a otros documentos DISCO construyendo una jerarquía de búsqueda • Podríamos colgar este fichero de “http://<url-mi-empresa>/default.disco” • El contenido de este fichero sería: <?xml version=“1.0” encoding=“uft-8”?> <discovery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/disco/"> <discoveryRef ref="http://localhost/ws/helloservice1.asmx?DISCO/"> <discoveryRef ref="http://localhost/ws/helloservice2.asmx?DISCO/"> </discovery>
UDDI • UDDI es una especificación para construir bases de datos distribuidas que permiten a las partes interesadas “descubrir” los servicios web de las otras • Similar a las páginas amarillas • Un portal UDDI es en si mismo un servicio web. • UDDI define un par de APIs SOAP: • Una API para consultas (enquiry) para realizar consultas sobre compañías y sus servicios web • Una API para publicar los servicios web de una empresa. • Cualquiera lo puede consultar, pero el acceso a la API de publicación está normalmente restringido a miembros registrados. • https://uddi.ibm.com/testregistry/registry.html • http://uddi.microsoft.com
Clientes de Servicios Web I • Aplicaciones que usan o consumen servicios web • Herramienta Wsdl.exe de .NET facilita esta tarea • Web Service Proxy • Objeto local que provee una representación local de un Servicio Web • Wsdl.exe genera clases proxy de Servicios Web • Invocar métodos en el servicio web es tan sencillo como invocar métodos en el proxy CalculatorWebService calc = new CalculatorWebService (); int sum = calc.Add (2, 2);
Clientes de Servicios Web II • Los métodos en el proxy tienen el mismo nombre que los nombres en el servicio web • El proxy encapsula los detalles de bajo nivel de invocación del servicio web • Invoca al servicio web traduciendo las invocaciones en SOAP y las respuestas en XML a los tipos de datos del proxy • Generar el proxy es tan sencillo como pasarle la URL de un WSDL al programa wsdl: wsdl http://tempuri.org/ws/calc.asmx?wsdl • Si el servicio web no fue realizado con .NET se puede bajar el WSDL y pasarle el path local al fichero • Para dar un nombre al proxy usar el parámetro /out:NombreProxy.cs • Si deseas generar el proxy en VB, usa /language:vb • Para encapsular en un namespace, usa /namespace:Calc • Se puede incluso cambiar el protocolo de invocación por defecto (SOAP) • /protocol:httpget • /protocol:httppost • Con Visual Studio.NET sólamente hay que añadir una referencia web a tu proyecto y los proxies generados son añadidos a tu proyecto
Cliente Web Sencillo • Pasos para escribir un cliente para Calc.asmx: • wsdl http://localhost/ws/calc.asmx • Crear una nueva clase ClienteCalculadora.cs • Compilar esa clase: csc CalcClient.cs CalculatorWebService.cs • Ejecutar ClienteCalculadora.exe
ClienteCalculadora.cs using System; class MyApp { public static void Main () { CalculatorWebService calc = new CalculatorWebService (); int sum = calc.Add (2, 2); Console.WriteLine ("2 + 2 = " + sum); } }
Invocaciones asíncronas • Si abres el fichero CalculatorWebService.cs observarás que wsdl genera wrappers tanto síncronos como asíncronos por cada método del servicio web • Las invocaciones asíncronas son útiles cuando la ejecución de un método puede tardar un largo periodo • Para el método Add del servicio web encontraríamos los siguientes métodos: • BeginAdd inicia la petición asíncrona y devuelve control • IAsyncResult res = calc.BeginAdd (2, 2, null, null); • EndAdd se bloquea hasta que la invocación finaliza • int sum = calc.EndAdd (res); • res.IsCompleted esta propiedad indica si la invocación ha finalizado • Lo mejor es usar un AsyncCallback delegate que te avise a través de un método de callback cuando la invocación ha finalizado
Ejemplo Invocación Asíncrona I using System; using System.Threading; class MyAsyncApp { private bool waitingOnReply = true; public MyAsyncApp() { CalculatorWebService calc = new CalculatorWebService (); AsyncCallback ac = new AsyncCallback (this.AddCompletedCallback); IAsyncResult res = calc.BeginAdd (2, 2, ac, calc); // Se bloquea esperando entrada de consola while (this.waitingOnReply) Thread.Sleep(500); Console.WriteLine("Done!"); }
Ejemplo Invocación Asíncrona II private void AddCompletedCallback (IAsyncResult res) { CalculatorWebService calc = (CalculatorWebService)res.AsyncState; int sum = calc.EndAdd (res); Console.WriteLine ("Callback 2 + 2 = " + sum); this.waitingOnReply = false; } public static void Main () { new MyAsyncApp(); } }
Invocando Servicios Web a través de Servidores Web Proxy • Dos opciones: • wsdl /proxy:http://myproxy http://localhost/ws/calc.asmx • El segundo modo es inicializar la propiedad Proxy del Servicio Web: • El parámetro ‘true’ de WebProxy indica que las invocaciones a direcciones locales no deben pasar por el servidor proxy CalculatorWebService calc = new CalculatorWebService (); calc.Proxy = new WebProxy (http://myproxy, true); int sum = calc.Add (2, 2);
Autenticación de Clientes de Servicios Web • ¿Quién invoca mi servicio web? ¿A quién tengo que cobrar? • Tres soluciones: • Cada invocador autorizado debe pasar una clave como parámetro en sus invocaciones • Trasmitir nombres de usuario y contraseñas en cabeceras de autenticación HTTP • Transmitir credenciales en cabeceras SOAP