Colas De Mensajes Con AquaLogic

De Dos Ideas.

Vamos a exponer con AquaLogic un Web Service que nos permita enviar un mensaje a una cola de mensajería. Partimos de un WSDL en donde definimos una operación “enviarFactura” que recibe como parámetro un elemento de tipo factura. Los elementos y tipos de dato de una factura se encuentran definidos en el esquema xml asociado al WSDL.

Contenido

La definición del servicio

Wsdl

<?xml version="1.0" encoding="UTF-8"?>
<definitions name="facturaWsdl" targetNamespace="http://j2ee.netbeans.org/wsdl/facturaWsdl"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://j2ee.netbeans.org/wsdl/facturaWsdl"
xmlns:ns="http://xml.netbeans.org/schema/facturaXmlSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
 
<types>
<xsd:schema targetNamespace="http://j2ee.netbeans.org/wsdl/facturaWsdl">
<xsd:import namespace="http://xml.netbeans.org/schema/facturaXmlSchema"
schemaLocation="../schema/facturaXmlSchema.xsd"/>
</xsd:schema>
</types>
<message name="enviarFacturaRequest">
<part name="part1" element="ns:factura"/>
</message>
<message name="enviarFacturaResponse"/>
<portType name="facturaWsdlPortType">
<operation name="enviarFactura">
<input name="input1" message="tns:enviarFacturaRequest"/>
<output name="output1" message="tns:enviarFacturaResponse"/>
</operation>
</portType>
<binding name="facturaWsdlBinding" type="tns:facturaWsdlPortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="enviarFactura">
<soap:operation/>
<input name="input1">
<soap:body use="literal"/>
</input>
<output name="output1">
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="facturaWsdlService">
<port name="facturaWsdlPort" binding="tns:facturaWsdlBinding">
<soap:address
location="http://localhost:${HttpDefaultPort}/facturaWsdlService/facturaWsdlPort"/>
</port>
</service>
</definitions>

El Esquema XML (XSD)

<?xml version="1.0" encoding="UTF-8"?>
 
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://xml.netbeans.org/schema/facturaXmlSchema"
xmlns:tns="http://xml.netbeans.org/schema/facturaXmlSchema"
elementFormDefault="qualified">
 
<xsd:element name="factura">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="numeroFactura" type="xsd:string"/>
<xsd:element name="fecha" type="xsd:string"/>
<xsd:element name="items" type="tns:listaItemsFactura"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
 
<xsd:complexType name="itemFactura">
<xsd:all>
<xsd:element name="codigoArticulo" type="xsd:string"/>
<xsd:element name="descripcion" minOccurs="0" type="xsd:string"/>
<xsd:element name="cantidad" type="xsd:int"/>
<xsd:element name="precio" type="xsd:double"/>
</xsd:all>
</xsd:complexType>
 
<xsd:complexType name="listaItemsFactura">
<xsd:sequence>
<xsd:element name="item" maxOccurs="unbounded" type="tns:itemFactura"/>
</xsd:sequence>
</xsd:complexType>
 
</xsd:schema>

Creación del proyecto

Recordemos que para crear objetos y/o modificarlos en AquaLogic se debe crear una sesión y luego activar la misma para que los cambios tengan efecto.

Desde la consola de aqualogic, en el Project Explorer creamos un proyecto llamado "demoFactura":

Para ser ordenados, dentro del proyecto demoFactura creamos una carpeta “envío de facturas”, donde crearemos todos los recursos de esta demo.

Agregamos el Esquema XML (XSD)

Para subir el esquema XML al AquaLogic, dentro de nuestra carpeta elegimos la opción XML Schema en el combo “Create Resource:”

Image:Aqualogic_demoFactura_3.jpg

Le ponemos un nombre al recurso que estamos creando y cargamos el archivo de definición de una factura.

Después de hacer click en Save vemos que tenemos el archivo xsd cargado correctamente:

Agregamos el WSDL

Para cargar el wsdl seguimos los mismos pasos que en el apartado anterior, eligiendo en el combo “Create Resource:” la opción WSDL.

Después de dar un nombre al recurso, cargar el archivo .wsdl y guardar los cambios tendremos:

Creamos un Business Service

El business service será el responsable de enviar el mensaje a la queue. Si elegimos la opción “Business Service” del combo “Create Resource” ingresamos al wizard para configurar este servicio. En el primer paso damos un nombre al servicio e indicamos que es de tipo “Messaging Service”.

Seteamos request y response como texto:

Marcamos que se utilizará el protocolo jms y agregamos con el botón Add los destinos del mensaje. El formato de las uri es jms://<host>:<puerto>/<jndi-connection-factory>/<jndi-queue> (Si nuestros jndi contienen “/”, las escapeamos con “.”)

Indicamos que el destinatario es una queue y que se enviará un text message.

En el último paso del wizard verificamos toda la información ingresada y guardamos los cambios. Entonces ya podemos probar el bussinessService mediante el ícono de “Launch Test Console”:

Escribimos el texto que viajará en el mensaje y presionamos el botón Execute:

El servicio termina correctamente y podemos ver que nuestra queue ha recibido un mensaje con el texto ingresado.

Creamos un Proxy Service

El Proxy service nos permitirá exponer el servicio para ser invocado vía http. Ingresamos al wizard de configuración eligiendo la opción “Proxy Service” en el combo “Create Resource”. Ponemos un nombre al servicio e indicamos que lo vamos a crear a partir de nuestro wsdl, el cual elegimos mediante el botón Browse:

Marcamos que podrá ser consumido mediante el protocolo http y definimos la url de invocación:

Dejamos todas las opciones por defecto hasta que termina el wizard y activamos los cambios.

Ahora hay que asociar el Proxy a nuestro business service. Para eso editamos el flujo del mensaje:

Y definimos un ruteo:

Click en el link <service> para buscar nuestro business service y que nos quede así:

Guardamos los cambios y probamos nuestro Proxy con el ícono de “Launch Test Console”, como hicimos antes con el business service.

Ejecutado ese request podemos ver que el mensaje completo llegó a la queue correctamente.

Agregamos el JMSType al mensaje

Vamos a editar el routeo entre el proxy y el business service para agregar el JMSType del mensaje que se encola:

Presionamos Add header y seleccionamos en el combo la opción JMSType:

Editamos el link <Expression> con el jmsType deseado, en este caso ‘facturaType’. Activamos los cambios y si probamos de nuevo el Proxy vemos que el mensaje se encola con el type indicado.

Validamos el mensaje contra el esquema xml

Si probamos sacando del request el tag numeroFactura, que es requerido según el .xsd, vemos que la petición no falla. Esto se debe a que debemos indicar a aqualogic explícitamente que valide la petición contra el esquema XML. Para eso editamos el routeo de nuevo y en primer lugar, creamos una variable:

A la variable le ponemos como nombre facturaSoapRequest. En la edición del link <expression> podemos navegar en “Variable Structures” buscando la parte del mensaje que se quiere asignar a la variable, en este caso la factura dentro del apartado body del request.

Y (como no se puede hacer drag and drop) copiamos la expresión desde el property inspector:

Ahora agregamos la acción de validación propiamente dicha. Lo que hacemos es indicar que verifique el contenido de la variable que definimos recién contra el esquema xml.

En variable ponemos la que definimos recién, facturaSoapRequest, y en <resource> buscamos nuestro xsd. Además, elegimos la opción de que lance un fault en caso de que el mensaje no se corresponda con el esquema y nos queda así:

Guardamos los cambios y probando el Proxy verificamos que si no le pasamos el tag numeroFactura la respuesta es:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<soapenv:Fault>
<faultcode>soapenv:Server</faultcode>
<faultstring>
BEA-382505: ALSB Validate action failed validation
</faultstring>
<detail>
<con:fault xmlns:con="http://www.bea.com/wli/sb/context">
<con:errorCode>BEA-382505</con:errorCode>
<con:reason>ALSB Validate action failed validation</con:reason>
<con:details>
<con1:ValidationFailureDetail
xmlns:con1="http://www.bea.com/wli/sb/stages/transform/config">
<con1:message>
Expected element
'numeroFactura@http://xml.netbeans.org/schema/facturaXmlSchema'
instead of
'fecha@http://xml.netbeans.org/schema/facturaXmlSchema'
here in element factura@http://xml.netbeans.org/schema/facturaXmlSchema
</con1:message>

Agregamos otras validaciones

Vamos a agregar como ejemplo, que el Proxy verifique que el número de la factura no supere los 8 caracteres. Para ello editamos el ruteo nuevamente y si creamos una acción

Nos agrega:

Editamos el link <condition> buscando variables y funciones de x-query (y siempre copiando del property inspector) hasta que tengamos la siguiente expresión:

Y en Add action agregamos un fault:

Completamos el código y mensaje para el error:

Activamos los cambios y verificamos el fault cuando invocamos al servicio con un número de factura mayor a 8 caracteres: