miércoles, 5 de diciembre de 2012

TESTEAR UN SERVICIO WEB CON SOAPUI


En esta sección les explicaré cómo testear un servicio web usando SoapUI. Para ello usaremos el servicio web creado en el post anterior.
  • SoapUI es una aplicación muy versátil que nos permite probar, simular y generar código de servicios web de forma ágil, partiendo del contrato de los mismos en formato WSDL y con vínculo SOAP sobre HTTP. Es una herramienta de software libre gráfica, está basada en Java.

Primero, es necesario tener intalado SoapUI. Instalemos la versión 2.0 o superior. Luego de ello, creamos un nuevo proyecto soapUI para el web service a probar. Vamos al menú File | New soapUI Proyect:



Completamos la siguiente información del proyecto:
  • Project Name: PruebaHolaMundo
  • Initial WSDL/WADL: dirección web o ruta de fichero donde se encuentra el descriptor del servicio web de trabajo. En este caso, la ruta de nuestro servicio web local es: http://localhost:8080/demoWebService/HolaMundo?wsdl

Si la dirección del descriptor es correcta, soapUI lo recuperará y lo analizará. Si no hay errores sintácticos ni ciertas incoherencias semánticas, creará el proyecto con la siguiente estructura:
  • Nombre del proyecto
  • Una interfaz, HolaMundoImplServiceSoapBinding. En este caso en particular el servicio web expone una.
  • Dentro de la interfaz, los métodos del servicio: buscarPersona, decirHola y obtenerPersonas.
  • Dentro de cada método, un esqueleto de mensaje SOAP, con el nombre genérico Request 1.

Haciendo soble click sobre Request 1 del método buscarPersona, accedemos al mensaje de petición SOAP, el que enviaremos al servicio web. Sustituimos los caracteres ? por los parámetros de entrada solicitados por el servicio web:
  • legajo: 1


Enviamos el mensaje al servicio pulsando en la fecha verde de la esquina izquierda. Tras unos instantes, recibimos el mensaje de respuesta SOAP que se mostrará a la derecha de la ventana anterior:


Si deseamos probar otro método del servicio web, en este caso obtenerPersonas, podremos observar que no tiene parámetros de entrada.


Pulsamos  la fecha verde de la esquina izquierda para ejecutar el testeo y el servicio devolverá  los siguientes datos:


lunes, 3 de diciembre de 2012

TESTEAR UN SERVICIO WEB CON JUNIT

En esta sección les explicaré cómo testear un servicio web usando JUnit. Para ello usaremos el servicio web creado en el post anterior.
  • JUnit es un conjunto de clases (framework) que permite realizar la ejecución de clases Java de manera controlada, para poder evaluar si el funcionamiento de cada uno de los métodos de la clase se comporta como se espera. Es decir, en función de algún valor de entrada se evalúa el valor de retorno esperado; si la clase cumple con la especificación, entonces JUnit devolverá que el método de la clase pasó exitosamente la prueba; en caso de que el valor esperado sea diferente al que regresó el método durante la ejecución, JUnit devolverá un fallo en el método correspondiente.
Para hacer las pruebas con JUnit, se tiene que importar el jar respectivo, para ello en el archivo pom.xml, se tiene que agregar el siguiente código dentro de la sección dependencies para que el proyecto Maven descargue el jar:

     <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit-version}</version>
            <scope>test</scope>
        </dependency>


Adicionalmente, creamos un archivo de configuración en el source folder src/test/source llamado applicationTest.xml. Esto ya fue explicado en el post anterior.


Luego de esto, en el source folder src/test/java creamos una clase ClienteTest donde implementaremos el código para las pruebas usando JUnit.



La anotación @RunWith(SpringJUnit4ClassRunner.class) hace que Spring levante su factory y prepare la ejecución. De forma alternativa se puede heredar de la clase AbstractJUnit4SpringContextTests; de hacerlo, se tiene acceso al contexto de Spring y otras utilidades.

La anotación @ContextConfiguration permite decir dónde están los ficheros de configuración de Spring (para nuestro ejemplo sólo usamos uno, pero se puede poner todos los que se quieran). Con @Autowired inyectamos de forma automática las dependencias entre clases (servicios, daos, controllers, etc).

El método assertEquals() generalmente admite dos parámetros: El primero es el valor esperado y el segundo el valor que hemos obtenido. 

Para realizar la prueba, primero tenemos que correr el proyecto. Luego, corremos el test de la siguiente manera:



El resultado que JUnit nos mostrará tiene dos escenarios: éxito y fracaso. El caso exitoso es cuando el resultado esperado es que realmente deseamos y si esto ocurre JUnit nos mostrará una franca verde indicando que todo esta OK.


El escenario de fracaso se da cuando el resultado obtenido no es el que esperamos. JUnit nos mostrará un franja de color rojo indicando el fallo de la prueba y a qué se debió el error:


CREACIÓN DE UN SERVICIO WEB

En esta sección les explicaré como crear un servicio web en java, para esto usaremos como herramienta el SpringSource. Primero, creamos un proyecto maven con apache cfx como se muestra a continuación:





Crearemos 3  Source Folder adicionales  src/main/java , src/test/java , src/test/resources; de la siguiente manera:



En el archivo pom.xml, haremos los siguientes cambios:


<project xmlns="http://maven.apache.org/POM/4.0.0" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

  <modelVersion>4.0.0</modelVersion>
  <groupId>edu.up</groupId>
  <artifactId>demoWebService</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>demoWebService Maven Webapp</name>
  <url>http://maven.apache.org</url>
  

    <!-- Dependency properties -->
    <properties>
        <junit-version>4.5</junit-version>
        <cxf.version>2.2.6</cxf.version>
        <spring-version>3.0.5.RELEASE</spring-version>
        <commons-logging-version>1.1.1</commons-logging-version>
    </properties>

      <!-- Dependency definitions -->
    <dependencies>
    
        <!-- Apache CXF dependencies -->
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        
        <!-- Spring Dependencies -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring-version}</version>
        </dependency>
        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring-version}</version>
        </dependency>        
        
        <!-- Logging -->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>${commons-logging-version}</version>
        </dependency>
        
        <!-- Testing -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit-version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

  
      <!-- Plugin configuration -->
    <build>
        <finalName>demoWebService</finalName>
        <!-- Feel free to change maven-compiler-plugin configuration -->
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.cxf</groupId>
                <artifactId>cxf-java2ws-plugin</artifactId>
                <version>${cxf.version}</version>
                <dependencies>
                    <dependency>
                        <groupId>org.apache.cxf</groupId>
                        <artifactId>cxf-rt-frontend-jaxws</artifactId>
                        <version>${cxf.version}</version>
                    </dependency>
                    <dependency>
                        <groupId>org.apache.cxf</groupId>
                        <artifactId>cxf-rt-frontend-simple</artifactId>
                        <version>${cxf.version}</version>
                    </dependency>
                </dependencies>
             
            </plugin>
        </plugins>
    </build>
    
</project>

En el archivo web.xml hacemos los siguientes cambios:


Creamos 3 clases:
1. Una clase interfaz llamada HolaMundo para el web service.
2. Una clase llamada HolaMundoImpl que implementa los métodos la clase interfaz.
3. Una clase bean llamada Persona que tendrá los datos del objeto persona.

Luego de ello implementaremos los siguientes métodos con las configuraciones respectivas:




Entre las anotaciones para la creación de un web service se tiene.

  • @WebService: indica que la clase será un web service.
  • @WebService(endpointInterface="upc.edu.pe.HolaMundo") : marca la clase como la implementación de un web service.
  • @WebResult(): mapea el resultado de una operación a un wsdl o un xml.
  • @WebParam(): se usa para marcar los parámetros del método como accesibles.
Luego de ello creamos un archivo de configuración en applicationTest.xml y ponemos el siguiente código:


Finalmente, creamos un archivo de configuración llamado applicationContext.xml en la carpeta web-inf del proyecto y añadimos  el siguiente código:


Al tener todo ya configurado, corremos el proyecto y aparecerá la siguiente página:


Al acceder a la ruta mostrada podremos observar la estructura de nuestro servicio web como un archivo xml.



SOA Y LOS SERVICIOS WEB


Un web service es básicamente una función o procedimiento que puede ser accedida vía web por cualquier programa o aplicación sin importar en que plataforma reside el servicio o en que lenguaje ha sido desarrollado, el termino “web” implica que el acceso se hace mediante una conexión a Internet habitualmente vía http aunque otros protocolos de transporte pueden ser utilizados. 
De esta forma, una aplicación Visual Basic puede, por ejemplo, usar una rutina de conversión de metros a yardas que fue realizada en Python y reside en un servidor de la India.

Los Servicios Web se han convertido en el estandarte de SOA, ya que esta tecnología posee un conjunto de características que permiten cubrir todos los principios de la orientación a servicios, no como otras posibles tecnologías de implementación como colas de mensajes o CORBA.

Para entender realmente lo que significa SOA, es necesario examinar los principios sobre los que se asienta, son estos:

  1. Contratos de servicio estandarizados: forma parte de la esencia misma de un servicio. Para que se considere un servicio,  su interfaz de entrada/salida (su contrato con el cliente) tiene que estar explícitamente declarado. Los campos  que forman parte de este interfaz deben estar correctamente tipados y ser conocidos. Con la ayuda de los estándares como WSDL y XSD, el contrato del servicio está autodescrito. Por consiguiente, los servicios web con un campo de entrada y otro de salida, en el que se inserta a su vez un XML como contenido (que no está descrito en ninguna parte) no puede considerarse un servicio web, a pesar de que parece que son los que más abundan.
  2. Servicios con bajo acoplamiento: hace referencia al nivel de dependencia entre servicios, entre el proveedor y el consumidor. Cuanto menos acoplamiento se logra una mayor independencia para el diseño del servicio y su posterior evolución
  3. Abstracción: este principio pone el enfásis en ocultar los detalles internos del servicio, tanto como sea posible. El servicio debe ser una caja negra, únicamente definido por su contrato, que a su vez es el mínimo acoplamiento posible con el consumidor del mismo
  4. Reusabilidad: como es conocido, la arquitectura SOA no busca la sustitución de las lógicas de negocio actuales sino que proporciona una forma de reaprovechar todos estos activos encapsulandolos en servicios para que a su vez puedan ser reutilizados por otros servicios.
  5. Autonomia: Este principio indica que el servicio tiene un alto grado de control sobre su entorno de ejecución y sobre la lógica que encapsula
  6. Sin estado: el tratamiento de una gran información de estado afectaría gravemente a la escalabilidad del servicio, poniendo en riesgo su disponibilidad. Idealmente, todos los datos que necesita el servicio para trabajar provienen de los parámetros de entrada.
  7. Capacidad de descubrimiento: al servicio se le dota de meta datos, gracias a los cuales puede ser descubierto de manera efectiva. Estos meta datos pueden ser interpretados de manera automática pudiendo ser reutilizados. Para ello es necesario disponer de un mecanismo de descubrimiento (llamado registro de servicios) como por ejemplo el UDDI.
  8. Composición: define la capacidad de un servicio para formar parte de un servicio más complejo. A medida de que la arquitectura SOA se consolide, los nuevos servicios (de más alto nivel) podrán implementarse a partir de los servicios de más bajo nivel ya existentes. La implementación de nuevos servicios se reducirá al mínimo y que los nuevos se crearán a partir de otros ya pre existentes.

Elementos de SOA


Esta arquitectura presenta un modelo de construcción sistemas distribuidos en el que la funcionalidad demandada será entregada a la aplicación a través de servicios. En la siguiente figura se muestra el esquema de la arquitectura y los elementos que podrían observarse. Como puede observarse, el esquema se encuentra dividido en 2 zonas; una que abarca el ámbito funcional de la arquitectura y otra vinculada a la calidad de servicio.


Elementos de la arquitectura SOA
A continuación se describen brevemente los elementos representados en la figura anterior:

Funciones:

  • Transporte: es el mecanismo utilizado para llevar las demandas de servicio desde un consumidor de servicio hacia un proveedor de servicio, y las respuestas desde el proveedor hacia el consumidor.
  • Protocolo de comunicación de servicios: es un mecanismo acordado a través del cual un proveedor de servicios y un consumidor de servicios comunican qué está siendo solicitado y qué está siendo respondido.
  • Descripción de servicio: es un esquema acordado para describir qué es el servicio, cómo debe invocarse, y qué datos requiere el servicio para invocarse con éxito.
  • Servicio: describe un servicio actual que está disponible para utilizar.
  • Procesos de Negocio: es una colección de servicios, invocados en una secuencia particular con un conjunto específico de reglas, para satisfacer un requisito de negocio.
  • Registro de Servicios: es un repositorio de descripciones de servicios y datos que pueden utilizar los proveedores de servicios para publicar sus servicios, así como los consumidores de servicios para descubrir o hallar servicios disponibles.
Calidad de Servicio:
  • Política: es un conjunto de condiciones o reglas bajo las cuales un proveedor de servicio hace el servicio disponible para consumidores.
  • Seguridad: es un conjunto de reglas que pueden aplicarse para la identificación, autorización y control de acceso a consumidores de servicios.
  • Transacciones: es el conjunto de atributos que podrían aplicarse a un grupo de servicios para entregar un resultado consistente.
  • Administración: es el conjunto de atributos que podrían aplicarse para manejar los servicios proporcionados o consumidos.