domingo, 28 de septiembre de 2008

Web Services con Mule CXF y Spring

Hola que tal

Despues de un rico desayuno en un agradable domingo en casa de mis padres, saque del polvo mi cuenta de integracion y pues aqui estamos; Antes de entrar en materia he de comentarles que han pasado muchas cosas interesantes en el trabajo, una que me tiene muy entusiasmado es el proyecto de SOA, mas alla del nombre, es interesante ver como gran parte de la comunidad de sistemas tiene su propia definion de SOA lo entendemos de diferentes maneras (no quiero pensar en la gente que es de negocio).. es un reto interesante en lo personal ya que se derivan muchas cosas desde la parte tecnica como la parte de venta la parte de convencer todo lo que vamos a estar haciend... en fin. Estuve leyendo el ultimo post de gustavo y comparto la opinion acerca de nuestros hermanos de la india, asi como en mexico, en la india hay gente muy trabajadora, muy comprometida y sobretodo sencilla, ya les contare mas detalle lo que estamos haciendo por aca en el trabajo.

Bien pues despues de lo anterior..... el post de hoy habla de de como combinar Spring, CXF y MULE, para generar y exponer servicios web usando el ESB Mule.

Bien, en muchas ocasiones me ha tocado ver como compañeros del trabajo les encargan generar un servicio web que exponga funcionalidad de negocio y me sorprende ver como tardan mas en generar todo la talacha que implica el exponer el servicio, que en lo que generan sus servicios de negocio.... creo que todo lo anterior tiene una explicacion, no estamos acostumbrados a trabajar con frameworks. Hoy en dia existen framworks como spring que como dicen en muchas paginas "hace la plomeria el plumbing", este tipo de marcos de trabajo nos permiten concentrarnos en generar nunestros componentes de negocio. En el siguiente ejemplo vamos a ver como exponemos un POJO como servicio web.

Bien los ingredientes son:

  • La distribucion de Mule (que esta basada en spring)
  • Si gustan usamos Eclipse Mule IDE
Es todo, ahora bien iniciamos pensando que tenemos un POJO sencillo basado en una INTERFAZ que realiza los siguientes calculos :D suma, resta, multiplicacion y division.

El codigo como sigue

public interface ICalculadora {
public float suma(float a, float b);
public float resta(float a, float b);
public float division(float a, float b);
public float multiplicacion(float a, float b);

}

y la implementacion

public class CalculadoraImpl implements ICalculadora {
public float division(float a, float b) {
if (b==0) return -1;
else return a/b;

}
public float multiplicacion(float a, float b) { return a*b;}
public float resta(float a, float b) { return a-b; }
public float suma(float a, float b) { return a+b; }
}

woow!!!, ahora bien si este pojo lo queremos usar con spring lo unico que necesitamos haces es su archivo de configuracion el application context:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

<bean id="calculadora"
class="ejercicio.CalculadoraImpl"
scope="singleton">
</bean>

</beans>

Ahora bien... hasta aqui nada nuevo... para los que han manejado spring no tiene nada de complicado lo anterior. Bien, pues vamos a hacer la pregunta que generalmente se coloca en el google "How do I expose my POJO as a webservice in Mule?", hay varios caminos... uno de ellos es usando CXF de apache para lo cual debemos de colocar una serie de anotaciones en nuestra clase y nuestra interfaz... veamos:

import javax.jws.WebResult;
import javax.jws.WebService;

@WebService
public interface ICalculadora {

@WebResult(name="suma")
public float suma(float a, float b);

@WebResult(name="resta")
public float resta(float a, float b);

@WebResult(name="division")
public float division(float a, float b);

@WebResult(name="multiplicacion")
public float multiplicacion(float a, float b);

}

y para la implementacion:

import javax.jws.WebService;

@WebService(endpointInterface = "ejercicio.ICalculadora",
serviceName = "Calculadora")
public class CalculadoraImpl implements ICalculadora {

public float division(float a, float b) {
if (b==0) return -1;
else return a/b;

}

public float multiplicacion(float a, float b) {
return a*b;
}

public float resta(float a, float b) {
return a-b;
}

public float suma(float a, float b) {
return a+b;

}

}

Las anotaciones usadas @WebService indican que la clase es un servicio web y @WebResult los valores a recibir. Estas anotaciones serviran para que CXF y Mule compongan el WSDL que describira nuestro servicio.

Una vez colocadas las anotaciones lo que sigue es generar nuestro archivo de configuracion de Mule mule-config.xml tal y como sigue:

<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns="http://www.mulesource.org/schema/mule/core/2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:soap="http://www.mulesource.org/schema/mule/soap/2.0"
xmlns:cxf="http://www.mulesource.org/schema/mule/cxf/2.0"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.mulesource.org/schema/mule/core/2.0 http://www.mulesource.org/schema/mule/core/2.0/mule.xsd
http://www.mulesource.org/schema/mule/soap/2.0 http://www.mulesource.org/schema/mule/soap/2.0/mule-soap.xsd
http://www.mulesource.org/schema/mule/cxf/2.0 http://www.mulesource.org/schema/mule/cxf/2.0/mule-cxf.xsd">

<spring:beans>
<spring:import resource="springContext.xml"/>
</spring:beans>

<model name="servicescalculadora">
<service name="Calculadora">
<inbound>
<cxf:inbound-endpoint address="http://localhost:65082/services/Calculadora" />
</inbound>
<component>
<spring-object bean="calculadora" />
</component>
</service>
</model>

</mule>


Bien pues ya tenemos todos los componentes, ahora vamos a ejecutar nuestro archivo de configuracion de mule, si lo hacen si el ide consideren todas las dependencias para que el poryecto compile:

MULE_HOME\mule -config mule-config.xml

Se ejecuta el servidor de mule al finalizar debemos de ver algo como lo siguiente:

INFO: Setting the server's publish address to be http://localhost:65082/services/Calculadora

Bien, pues listo! ya estsmos en posibilidades de ver el WSDL

http://localhost:65082/services/Calculadora?WSDL

Ahora solo es cuestion de ejecutar pruebas con nuestro servicio web, en lo personal yo uso SOAP UI, pero pues lo pueden hacer con cualquier herramienta que pueda mandar peticiones hacia sua servicios web.



Bueno pues es todo, esperemos que les sirva, quejas y sugerencias seran bien recibidas.

Por una integracion mejor, hasta la vista!!

Tuzo

2 comentarios:

Jordi dijo...

Antes de nada agradecerte la simplicidad y exactitud del ejemplo expuesto.
Encuentro muy interesante la combinación de cxf, spring y mule para la creación y despliegue de websevices ya que simplifica enormemente su desarrollo, pero ¿Qúe pasaría en el caso de tener una serie de webservices YA DESARROLLADOS por ejemplo en axis (como es mi caso) y los quisiera integrar en un bus mule?
Es decir, intentaré explicarme mejor... tengo una serie de webservices que he desarrollado WSDLtoJAVA, se han creado los descriptores (wsdl y schemas) de los webservices y a partir de un plugin de Axis2 para eclipse se ha generado automáticamente el código java necesario para su despliegue en un servidor axis (skeleton, mensajería, etc).
Pues bien ¿Qué debería hacer para incluir estos WebServices, ya desarrollados, en un esb como Mule sin tener que crearlos de nuevo?,
¿Es posible darlos de alta en el esb a partir de su WSDL?

Te agradecería muchísimo cualquier comentario...

Andry dijo...

Hola, muy buen ejemplo este que expones aca, gracias.
Quisiera hacerte 2 preguntas pues he buscado pero aun no he podido encontrarle respuesta, resulta que soy nuevo trabajando con este tipo de tecnologia y en este caso espesífico con Mule, las interrogantes son las siguientes:
1- Mule cuenta con un archivo configuracion XML que puede ser supongamos el del hello-config.xml que trae por ejemplo, cuando levantamos Mule este archivo se le pasa a la consola mediante el siguiente comando (mule -config hello-config.xml) y es con el cual se carga Mule exponiendo los distintos servicios que se definan en el XML, ahora bien mi pregunta es: toda la logica de enrutamiento de todos mis servicios va a estar descrita en este unico XML, cuyo trabajo con el mismo se hace tedioso si tengo mas de 40 o 50 servicios o existe alguna manera de poder tener varios de estos XMLs que conformarian las distintas capas de una arquitectura X y llamarlos desde una sola instancia de Mule, o hay que levantar por cada XML una instancia de mule aun si estan en el mismo servidor.
2- Conoce ud de algun ejemplo o algun tutorial donde se pueda ver un ejemplo bien explicado del uso de los diferentes transportes de Mule o los tipos de Ruters cuando usar uno u otro, pues existe una gran variedad de estos.
3- Adopto tambien la duda de Jordi, descrita anteriormente como mía.

Disculpe la molestia o lo excesivo de las preguntas, le agradeseria mucho su respuesta.
Slds