Download Seminario Spring Remoting 9 de Octubre de 2008 9 de Octubre de
Document related concepts
no text concepts found
Transcript
Seminario Spring Remoting 9 de Octubre de 2008 Spring Remoting 1 ¿Qué es Spring Framework? Nace con el objeto de reducir la complejidad en el desarrollo de aplicaciones empresariales. Spring es definido como un framework que se comporta a la vez como un contenedor orientado a aspectos y con una base de inyección de dependencias ligero. Ligero: Es ligero tanto en términos de tamaño como de sencillez en el desarrollo. Dependency Injection. Los objetos declaran las dependencias con el resto de componentes del sistema/arquitectura y es el contenedor el encargado de resolver éstas. Orientación a aspectos: Permite separar la lógica de negocio de los servicios de middleware: transaccionalidad, seguridad, logging, etc… Contenedor: Contiene y gestiona el ciclo de vida de los objetos que contiene. Framework: Es posible configurar y componer componentes complejos a partir de componentes más simples. Spring incorpora mucha funcionalidad de infraestructura, permitiendo que el desarrollador se centre en la lógica de negocio. NO PRETENDE REINVENTAR LA RUEDA. Asume que hay buenas soluciones para la capa de persistencia (Hibernate, Ibatis, etc..) y para la capa Web (Struts, JSF, etc…). Se integra hasta con la tecnología motivo de su génesis (EJB’s). Spring Remoting 2 Módulos Spring Framework Spring MVC: Implementación alternativa a Struts. Nace como alternativa menos intrusiva facilitando la reutilización de componentes y la independencia tecnológica Integración con Hibernate(ORM): Implementa el patrón DAO y aisla al desarrollador de la obtención de la conexión con la BBDD y simplifica la etapa de configuración. Los componentes DAO únicamente presentan el código de persistencia mínimo (no es responsable de la obtención y el cierre de la conexión). La transaccionalidad es gestionada mediante aspectos de un modo standalone. No hay necesidad de disponer de un contenedor que de los servicios de infraestructura de un modo intrusivo. (Módulo AOP). Remoting: Los componentes pueden ser invocados remotamente mediante la incorporación de componentes “Exporter”. Es decir, cualquier componente desarrollado de la capa de servicio puede ser expuesto como un servicio remoto sin que fuese desarrollado para tal fin. Posibilidad de invocación mediante HTTP/RMI/SOAP/REST (XML + HTTP)/Hessian and Burlap (RMI binario y optimizado). Aíslas al desarrollador de la complejidad tecnológica subyacente. Posibilidad de ejecutarse todo el código fuera de contenedores específicos para la capa de negocio. En caso de aplicación web, únicamente es necesario un contenedor de servlets. Spring Remoting 3 Módulos Spring Framework (II) Spring Remoting 4 Spring Framework – Servicios enterprise Presenta API’s que facilita de servicios enterprise: JavaMail. Permite de una manera sencilla el envío de un correo, con todas las alternativas de configuración: SMTP seguro/no seguro. Quartz Scheduler. Permite la planificación de tareas con la potencia de las expresiones Cron. Infraestructura de monitorización y gestión JMX (equivalente a SNMP). Permite disponer de una infraestructura para la monitorización y gestión de los servicios/sistemas de las aplicaciones desarrolladas. Todos los fabricantes de contenedores J2EE, se han visto en la tesitura de publicar que son compatibles con Spring, incluso elaborar herramientas de apoyo al desarrollo. Ejemplos: BEA: http://e-docs.bea.com/platform/suppconfigs/configs/spring/ Oracle: http://www.oracle.com/corporate/press/2007_may/SpringDevKit.html IBM: http://www.ibm.com/developerworks/websphere/library/techarticles/0706_johnsonbuck/0706_johnsonbuck.html Spring Remoting 5 Dependency Injection En un principio es conocido como el patrón Inversion Of Control (IoC). ¿Qué es lo que se está invirtiendo?. Martin Fowler 2004. Concluyó que lo que se estaba invirtiendo era la obtención de dependencias. A partir de ese momento, el patrón paso a conocerse como “Dependency Injection”. Tradicionalmente, cada objeto es responsable de obtener las referencias de los objetos con los que trabaja. Esto puede conducir a un fuerte acoplo entre componentes, así como un código difícil de probar. Con DI las dependencias son inyectadas a los objetos por una entidad externa, con lo que los componentes únicamente “declaran” su dependencia con otros objetos, sin ser responsables de obtener las referencias de los mismos. La principal ventaja de DI es el desacoplo de componentes. Se aconseja el uso de interfaces con el objeto de ocultar la implementación de los componentes asociados, mejorando aún más el desacoplo. Dentro de Spring existe un componente llamado BeanFactory (contenedor) encargado de contener e instanciar los objetos de la aplicación, así como resolver las dependencias entre los mismos. XmlBeanFactory es una implementación que define los mismos, en un fichero XML. El proceso de ir definiendo las asociaciones entre componentes siguiendo el patrón DI, es conocido como wiring. Spring Remoting 6 Exposición de servicios remotos basados en POJOS 7 Spring Remoting 7 Introducción Gracias al poder de DI y al desacoplo de componentes, es posible exponer declarativamente lógica de negocio como un servicio con invocación remota. El desarrollador no tiene por qué conocer las particularidades del protocolo subyacente. Los distintos protocolos soportados son: Servicios RMI Servicios Hessian and Burlap (Caucho) Innovaciones HTTP de servicios Spring Spring Web Services (Xfire) Spring Remoting 8 Exposición servicio mediante RMI. Parte cliente Desde el punto de vista del cliente, la programación tradicional de un consumidor de servicios RMI presentaba dos potenciales problemas: Excepciones que deben ser capturadas o relanzadas: RemoteException, NotBoundException, MalformedURLException. Ejemplo: En el caso que se indique mal la localización del servicio, la única manera de resolverlo es recompilando el código involucrado en definir la URL (o reconfigurando las propiedades del servicio). ¿Por qué tratar este tipo de excepciones?. EL método de localización de un servicio RMI, normalmente incumple el principio fundamental de DI, con lo que el objeto cliente es responsable de obtener la referencia del servicio RMI. Con Spring, el cliente se va a comunicar con el servicio remoto mediante el uso de un proxy. El proxy se encarga de ocultar al cliente de las particularidades del protocolo. Asimismo las excepciones propias del protocolo las convierte en excepciones de Runtime (el cliente no trata excepciones propias del protocolo) Spring Remoting 9 Exposición de servicio mediante RMI. Parte servidora Pasos a realizar en una implementación clásica: La implementación de los métodos del servicio deben lanzar java.rmi.RemoteException EL interfaz del servicio debe extender de java.rmi.Remote Compilar los fuentes con el compilador de RMI (rmic) para producir los stubs y skeleton. Arrancar un registro RMI Registrar los servicios en el registro RMI Spring te simplifica todos estos pasos de la siguiente manera: El interfaz no es necesario que extienda de java.rmi.Remote La implementación del servicio es un POJO sin necesidad de lanzar excepciones java.rmi.RemoteException. Por tanto, el componente no tiene ningún código asociado que le haga “comportarse” como un servicio RMI. Una vez definida la implementación e interfaz del servicio, Spring proporciona un componente RMIServiceExporter con todo lo necesario para exponer la lógica como servicio RMI. Por defecto se intenta conectar con el registro RMI en el puerto 1099 de la máquina local. En el caso que se quiera redefinir hay que establecer valor para las propiedades registryHost y registryPort. RMI presenta dos inconvenientes fundamentales: No trabaja bien con firewalls (existe la posibilidad de tunelar el tráfico RMI). El cliente y el servidor deben ser código Java Spring Remoting 10 Exposición mediante Hessian and Burlap Ambos protocolos usan HTTP como protocolo de capa de aplicación (modelo OSI) Hessian lleva asociado un protocolo binario propio y con API’s para ser manejado por clientes que no sean Java: PHP, Python, C++, C#. Burlap, sin embargo, es un protocolo basado en tramas XML con lo que el abanico de clientes se aumenta. Por tanto, en el caso que haya restricciones de ancho de banda Hessian sería la solución más óptima. Sin embargo, si se quiere que la comunicación sea legible se aconseja el uso de Burlap. Spring Remoting 11 Configuración Hessian/Burlap Desde el punto de vista del cliente la configuración es exactamente igual. Para el caso de Hessian se genera el proxy mediante la clase HessianProxyFactoryBean y en el caso de Burlap con la clase BurlapProxyFactoryBean. Exposición de servicio Hessian La implementación del servicio debe extender de HessianServlet. Los métodos deben ser públicos. Sin embargo, con Spring no es necesario este paso, puesto que tiene un componente que aisla de todas las particularidades del servicio: HessianServiceExporter. Es necesario configurar el controlador de Hessian encargado de definir los endpoints donde los servicios escucharan (URL HTTP). HessianServiceExporter es configurado como un controlador Spring MVC. Por tanto es necesario definir el DispatcherServlet, así como el manejador de URL’s. De la misma manera es posible exponer lógica de negocio como WebService mediante el uso de Xfire Spring Remoting 12 Exposición de servicios mediante XFire XFire permitirá el exportar los métodos de la lógica de negocio implementada en POJOS como un web services. XFire permitirá por tanto traducir los mensajes de entrada SOAP en invocaciones a métodos Java. XFire presenta una aproximación bottom-up donde se expone directamente como Servicio Web la API interna de nuestra aplicación. Como ventaja presenta la posibilidad de abstraer al programador de los detalles de la tecnología subyacente. A continuación se ve el diagrama donde se explica el comportamiento del componente XFireExporter: Spring Remoting 13 Declaración de servicios Web usando anotaciones JSR- 181 El problema principal que presenta la solución con XFireExporter es que es necesario definir el bean de exportación por cada bean que quieras exportar como servicio web. Para poder usar las anotaciones con XFire es necesario incluir el soporte JAX-WS para Xfire (dependencia de Maven). Las anotaciones se realizan sobre la clase y el interfaz. Por defecto, se publican todos los métodos públicos de la clase. Cuidado, por tanto, con exponer métodos de la API interna de la aplicación. Dentro de Spring es necesario configurar un mapeador de direcciones específico para que el DispatcherServlet interprete las anotaciones JSR-181 de los beans: JSR181HandlerMapping. Finalmente todos aquellos beans que estén anotados responderán a la dirección: http://<host>:<port>/<contextApp>/services/<serviceName>?wsdl Spring Remoting 14 Consumiendo web services Aunque es posible realizar la llamada al web service mediante la API de XFire: ObjectServiceFactory y XFireProxyFactory, lo lógico es aprovechar las ventajas del patrón DI, evitando al cliente tener que conocer las particularidades de la API. Siguiendo la misma filosofía que en los casos anteriores, haremos uso de una factoría de Proxies que serán los encargados de implementar toda la lógica específica del protocolo. Existen dos proxies para poder realizar esta labor: JaxRpcPortProxyFactoryBean. Esta implementación es propia de Spring XFireClientFactoryBean: Esta factoría es provista dentro de Xfire. Elegiremos XFire por la gestión implícita que hace de los tipos complejos, así como la sencillez a la hora de definirlo: no es necesario definir el nombre del servicio, nombre del puerto, namespace, puesto que él automáticamente lo descubre a partir del WSDL. Al igual que en los casos anteriores el proxy es el que se inyecta al bean cliente, con el objeto de proporcionar una referencia al servicio de invocación remoto. Spring Remoting 15 XFireClientFactoryBean Spring Remoting 16 Conclusiones La exposición de lógica de negocio como servicio mediante el uso de componentes exportadores (aplicación del patrón DI y uso de AOP), permite una solución sencilla, donde no es necesario conocer las particularidades de las tecnologías y protocolos subyacentes. Presenta la ventaja de poder probar la lógica de negocio, puesto que se trata de un POJO. Posibilidad de disponer de mecanismos más ligeros que SOAP, con lo que el rendimiento aumenta. Posibilidad de cambio en el método de exposición, sin que se vean afectadas la parte cliente y la parte servidora. Se desarrollan más rápidos que con Spring-WS Tener cuidado con no exponer la API interna de la aplicación. Quizás será necesario el generar componentes de la capa de servicio de más alto nivel. Cambios en las API’s afectan al entorno cliente (suponen un cambio en el contrato/interfaz). La aproximación no tiene en cuenta el contrato con el cliente. Spring Remoting 17 Implementando Web Services con Spring Aproximación top-down (contract first) 18 Spring Remoting 18 Introducción – Spring WS Como se ha comentado anteriormente los mecanismos de exposición de JavaBeans como servicio remoto, presenta la desventaja de ofrecer la API interna de la aplicación. Como contraposición a este modelo se presenta un modelo de trabajo top-down, donde se enfatiza en qué ofrece el servicio (contrato) del cómo es implementado el mismo. Esto permite que podamos evolucionar el interfaz entre el cliente y el servidor, permitiendo compatibilidad hacia atrás. En el modelo anterior, cambios en la API conducen a cambios en el contrato. Por tanto, en esta aproximación los pasos a realizar son los siguientes: Definir el contrato de servicio: Se definen los mensajes de entrada y salida del servicio, se generan los esquemas XML , los cuales serán usados posteriormente en el WSDL. Implementación del service endpoint. Básicamente este componente se encarga de gestionar los mensajes de entrada y salida del servicio. Configuración del endpoint y de la infraestructura Spring-WS. En este paso, se generará el WSDL usando los componentes que ofrece el framework Spring Remoting 19 Definición del contrato Para la defínición del contrato es necesario modelar los mensajes XML de entrada y de salida. A partir de éstos se infiere el esquema XML. Este paso evita el tener que conocer con gran detalle las particularidades de la tecnología Schema XML. En el ejemplo del seminario se ha usado la herramienta Trang. El contrato de servicio se divide en dos partes: El contrato a nivel de datos: Se definen los mensajes de entrada y de salida del servicio. Contrato operacional: Define las operaciones de servicio. Una operación de servicio no tiene por qué coincidir con un método en la API de servicio. Por tanto, el WSDL se divide en dos partes diferenciadas: Contrato de datos: Donde se incluyen los esquemas de los mensajes de entrada y de salida: elementos <wsdl:types> y <wsdl:message>. Contrato de servicio: Elementos <wsdl:portType> y <wsdl:binding>. Spring Remoting 20 Manejando los mensajes con Service Endpoints Básicamente estos componentes se encargan de gestionar los mensajes XML de entrada y de salida. Los tipos de endpoints que Spring-WS ofrecen son muy variados. Existe la posibilidad de trabajar con cualquier parseador XML: SAX, DOM, StAX. Se integra con las API’s DOM4j, JDOM. Con el objeto de abstraer al programador del tratamiento a bajo nivel del mensaje se ofrece una API: OXM ( Object-XML-Mapping) que realiza procesos de marshalling y unmarshalling de los mensajes. OXM tiene soporte para Castor XML, JAXB v1, JAXB v2, JIBX, XmlStream (limitaciones con namespaces), XMLBeans. Es importante que el MessageEndpoint no se encargue de realizar directamente la lógica de negocio, sino que se inyecte un componente encargado de realizar ésta. Permite la separación del contrato de datos del contrato operacional. Spring Remoting 21 Configuración de Spring WS En la configuración de Spring es necesario definir los siguientes tipos de beans: Mapeador de entrada (PayloadMapping). Encargado de redirigir los mensajes XML de entrada al correspondiente endpoint (Se realiza a partir del nombre cualificado del XML (namespace + elemento raíz). MessageEndpoint. Componente encargado de procesar los ficheros XML del servicio (entrada/salida). Bean lógica de negocio. Se encarga de a partir de los datos de entrada (objetos Java) invocar a la logica de negocio y generar los datos de salida. Este objeto se inyecta al MessageEndpoint. Marshaller. Encargado de realizar los procesos de marshalling y unmarshalling. En nuestro caso se realiza usando Castor XML y apoyándose en el fichero de mapeo. ExceptionResolver: Encargado de generar una SOAP fault a partir de las excepciones Java producidas en la cadena de proceso. Generador dinámico de WSDL. A partir de los esquemas XML y en función de una serie de convenciones (Request y Response) genera los ficheros descriptores del servicio Web. Es posible proporcionar WSDL de manera estática Spring Remoting 22 ExceptionResolver & Generador dinámica WSDL Spring Remoting 23 DispatcherServlet Finalmente es necesario configurar un DispatcherServlet específico para poder permitir que la invocación de los servicios web se realice mediante el protocolo HTTP. Spring Remoting 24 Consumición de servicios web con Spring-WS. WebServiceTemplate Trabajar con WebServiceTemplate. El cliente trabaja directamente con mensajes XML y es el template el encargado de realizar las traducciones necesarias para uso del protocolo SOAP. Básicamente este tipo de templates necesita un componente para poder enviar el mensaje via HTTP (MessageSender) y una factoría de mensajes(MessageFactory) encargada de generar el mensaje SOAP. Existen los siguientes tipos de MessageFactory: AxiomSOAPMessageFactory: Genera los mensajes SOAP usando la API de Axiom (Axis Object Model). Está basado en la API de StAX y se recomienda cuando los mensajes del servicio se prevean sean de un volumen considerable DomPoxMessageFactory: Produce XML plano y es usado para cuando no se prevea el uso de SOAP. En la versión 2 de Spring-WS se prevee soporte para interfaces REST (☺). SaajSOAPMessageFactory: Usa la API SAAJ (Soap With Attachment API). Internamente usa DOM. Cuidado con mensajes largos Rendimiento bajo. Igualmente existen dos tipos de MessageSender: Uno que trabaja directamente con el soporte de gestión HTTP de la JDK: HttpURLConnectiony otro que trabaja con la librería commons-http. Éste último se considera más idóneo para autenticación HTTP y pool de conexiones HTTP. Es posible usar las capacidades de marshalling y unmarshalling para que el cliente componga el mensaje. En este caso el serviceTemplate mantiene una referencia al objeto marshaller y unmarshaller. Spring Remoting 25 WebServiceTemplate con soporte para marshalling Spring Remoting 26 Consumición de servicios web con Spring-WS. Soporte gateway Es posible en Spring-WS evitar que el template sea inyectado. Para ello se ofrece una clase de soporte que automáticamente genera el WebServiceTemplate. Logicamente es necesario proveer un bean definiendo el gateway con la configuración necesaria para que éste pueda crear el WebServiceTemplate (MessageSender, marshaller y unmarshaller). Spring Remoting 27 Conclusiones finales. Contract-first vs contract-last Fragilidad. Cada vez que se cambia el interfaz Java se cambia el contrato de servicio generado. Por tanto, es necesario mantener el contrato con el cliente aunque cambie la API. Rendimiento: Cuando se renderiza automáticamente el objeto Java en XML, puede tener una penalización en el rendimiento (referencias cruzadas). En el caso de contract-first se explicita el mensaje XML que va por el interfaz. Reusabilidad. El esquema XML es un fichero que puede ser reusado para generar el WSDL, o en otros esquemas. Versionado. Al mantener desacoplado el contrato de la implementación es posible mantener el contrato cambiando la implementación del servicio. Además es posible mantener compatibilidad hacia atrás, por ejemplo realizando transformaciones de mensajes antiguos en el nuevo. Soporte de protocolos HTTP/JMS e Email. Los procesos de logging y auditoría de mensajes está integrados con Log4j: log4j.logger.org.springframework.ws.client.MessageTracing.sent=TRACE log4j.logger.org.springframework.ws.client.MessageTracing.received=DEBUG Incluye interceptores de validación de los mensajes de entrada y salida. Spring Remoting 28 Impedancia entre XML y objetos Similar a la impedancia que existe en las soluciones ORM con respecto al modelo entidad/relación, existe problemas al convertir objetos en XML. Extensiones XSD. Las extensiones XSD permiten restricciones en los tipos de datos. Ejemplo: permitir tres letras mayusculas. Este tipo de extensiones no las presenta Java (únicamente extensión de comportamiento y no de restricción). Tipos no soportados. Uno de los principios básicos de la plataforma web service es la interoperabilidad: Java, .NET, Python, … Por ejemplo si desde Java se usa el tipo TreeMap, seguramente en .NET se use el tipo System.collections.Hashtable. Por tanto, la semántica del tipo de dato es diferente. Referencias ciclicas. La forma de representar en XML referencias ciclicas es mediante referencias. El problema es que no se puede usar validadores XML para validar esta estructura. Hay que tener en cuenta estas consideraciones a la hora de implementar web services. Spring Remoting 29 Introducción a WS-Security WS-Security se centra en tres grandes aspectos: Autenticación: Determinar el principal y comprobar qué es quien dice ser. Firma digital: Pieza de información que es basada en el documento y la clave privada de firmante. Internamente se compone de una función hash y una función de firma con la clave privada del firmante. Encriptación y desencriptación. Consideraciones: El uso de WS-Security lleva consigo una penalización importante del rendimiento con lo que se aconseja en algunos casos el uso de mecanismos de seguridad más sencillos como puede ser la los mecanismos de seguridad básicos HTTP. La implementación de WS-Security para Spring dispone de soporte para Acegi Security. Es posible reusar la configuración existente para el soporte de WebServices. Spring Remoting 30