Blog de Antonio Manuel Muñiz

Desarrollo, Ingeniería y Calidad del Software

Archivos por Etiqueta: SOA

Asistencia al JSWEB

La semana que viene acudiré al JSWEB. Por desgracia no hemos podido presentar nada, el año que viene no se nos escapa.

Estoy preparando un post sobre procesos de aseguramiento de la calidad asociados al desarrollo de servicios web, espero tenerlo pronto ;)

Anuncios

Spring beans como Web Services con WSO2 Framework

Hace algún tiempo hablaba de WSO2 y su gran iniciativa en el mundo de los servicios web. He estado probando Web Services Framework for Spring y la verdad es que han conseguido que la árdua tarea de integrar un servicio web basado en Apache Axis2 con Spring sea cuestión de minutos.

Para ilustrar el proceso configuraremos una aplicación web basada en Spring para que exponga uno de sus beans como un servicio web.

La estructura de nuestra aplicación será la siguiente:

+META-INF
+WEB-INF
   + lib
   - applicationContext.xml
   - dispatcher-servlet.xml
   - axis2Config.xml
   - web.xml
+axis2-web
-index.jsp

En WEB-INF/lib debemos copiar el directorio /lib distribuido con el framework. Sería posible evitar esto si nuestro proyecto esta modelado con maven, aprovechando que WSF-Spring también es un proyecto Maven 2, para esto habría que estudiar más a fondo la estructura de WSF-Spring e integrarlo como un módulo de nuestro proyecto.

También debemos copiar el fichero axis2Config.xml a nuestro WEB-INF, y por último copiar el directorio axis2-web (incluido en la distribución) a la raíz de nuestro proyecto.

El bean que expondremos como un servicio será el siguiente:

package sample.spring.axis;
public class Sample {

    private int offset;

    public int add(int i, int j){
        return offset + i + j;
    }

    public void setOffset(int value){
        this.offset = value;
    }
}

Se ha incluido el atributo offset para comprobar como se comporta el servicio manteniendo un estado interno representado mediante esta variable.

El siguiente paso es la inicialización del bean en el contexto de la aplicación (applicationContext.xml):

<bean id="addBean" class="sample.spring.axis.Sample">
    <property name="offset" value="0" />
</bean>

En principio el valor de offset será 0 y la configuración necesaria para mostrar el bean como un servicio será:

<bean id="services" class="org.wso2.spring.ws.WebServices">
    <property name="services">
        <list>
            <bean id="helloService" class="org.wso2.spring.ws.SpringWebService">
                <property name="serviceBean" ref="addBean" />
                <property name="serviceName" value="addBeanService" />
            </bean>
        </list>
    </property>
</bean>

Importar el fichero axis2Config.xml en el applicationContext.xml:

<import resource="axis2Config.xml"/>

En el fichero web.xml de nuestra aplicación incluiremos:

<servlet>
    <servlet-name>axis2</servlet-name>
    <servlet-class>org.wso2.spring.ws.servlet.SpringAxis2Servlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>axis2</servlet-name>
    <url-pattern>/axis2/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>axis2</servlet-name>
    <url-pattern>/services/*</url-pattern>
</servlet-mapping>

Y nada más. Esta es toda la configuración necesaria, si empaquetamos la aplicación web en un WAR y la desplegamos en un servidor de aplicaciones podemos comprobar que el servicio se esta exponiendo correctamente accediendo a http://<dirección_ip&gt;:<puerto>/<contexto>/services/addBeanService?wsdl

Yo lo he desplegado en un servidor Glassfish (donde también tengo una instancia de Hudson ;) dicho sea de paso):

El WSDL se muestra en la URL indicada:

Para probar que el servicio funciona correctamente haremos una petición con SoapUI:

Se puede observar que el servicio generado por WSF-Spring muestra como operaciones todos los métodos públicos del bean, en este caso add y setOffset. Mediante una llamada a setOffset modificaremos la propiedad offset del bean (simulación de estado):

Si volvemos a realizar la llamada a la operación add con los parámetros 2, 3 por ejemplo comprobamos que efectivamente es posible modificar el estado del bean expuesto como servicio.

Construcción y Testing de Web Services con Axis y Maven

Hace tiempo estuve desarrollando un stack de servicios web que dieran acceso a una serie de
procedimientos almacenados en una base de datos Oracle. Uno de los objetivos fue automatizar
totalmente el proceso de construcción de los web services con Maven.
La solución se basó en el framework WS de Apache, Axis2 1.3, que en principio ofrece un conjunto
de herramientas en línea de comandos para la generación del código tanto del servicio como de
los clientes. Para la generación del código del servicio se ejecuta:

wsdl2java -uri InterfazWS.wsdl -p interfaz.ws -o target_directory -d xmlbeans -s -ss -sd

Esto genera todos los artefactos necesarios para gestionar las peticiones al web service, solo
tenemos que implementar la lógica de la clase Skeleton.

Este proceso es algo tedioso cuando se esta desarrollando, y además necesitamos tener instalado wsdl2java para generar el código, vamos a automatizarlo con maven, de forma que solo tenemos que ejecutar el comando anterior una sola vez, la primera, para que nos genere la clase Skeleton, esta clase es la que pondremos como fuente de nuestro proyecto (en src/main/java). Desde luego, en el momento del despliegue del servicio no tendremos que ejecutar wsdl2java en la línea de comandos.

La estructura del proyecto será la siguiente:

- -+ src
- - - -+ main
- - - - - - - -+ java
- - - - - - - - - - -+ InterfazWSSkeleton.java
- - - - - - - -+ resources
- - - - - - - - - - - - -+ META-INF
- - - - - - - - - - - - - - - - -+ InterfazWS.wsdl
- -+ interfaz-ws-soapui-project.xml
- -+ pom.xml

Utilizaremos el plugin axis2-wsdl2code-maven-plugin para la generación del servicio
a partir del WSDL (e la fase generate-sources).

Pero este plugin genera todo el código en el directorio que le indiquemos, en nuestro caso target/generated-by-axis2, ahora tenemos que moverlo a src/main/java. ¿Por que no haberlo generado directamente en src/main/java?, por que entonces se sobreescibiría la clase Skeleton y no queremos que pase esto, es en ella donde dotaremos de lógica al servicio y hay que mantenerla, de hecho, será la única clase que tendremos en src/main/java, el resto se generará. Para mover los fuentes y el resto de recursos utilizaremos maven-antrun-plugin.

El segundo objetivo es automatizar las pruebas, lo haremos con maven-soapui-plugin. Este plugin
necesita un fichero xml generado con la herramienta SoapUI. Por tanto debemos definir nuestros
tests con SoapUI y utilizar el fichero xml en el que la herramienta almacena la información de
los tests definidos. A este plugin solo hay que indicarle donde encontrar el fichero xml de SoapUI
y la URL del servidor en el que se encuentra el servicio (el path al wsdl ya lo contiene el xml de SoapUI).
Por último también tenemos que configurar el plugin maven-clean-plugin para que elimine lo que nos
interesa.

Una vez configurado todo, podemos generar y testear el servicio web automaticamente con maven.
El proceso completo consta de los siguientes pasos:

mvn package

– Genera un jar que podemos desplegar en el Axis Manager (WAR) (o en nuestra aplicación web, en
caso de que la hayamos adaptado para desplegar servicios Axis2)

mvn eviware:maven-soapui-plugin:test

– Ejecución de tests funcionales

mvn eviware:maven-soapui-plugin:loadtest

– Ejecucuión de tests de carga

Aún no lo he probado con la versión 1.4 de Axis, en cuanto lo pruebe comento como ha ido.

Este es el fichero pom.xml completo