Colas De Mensajes Con AquaLogic

De Dos Ideas.
Revisión del 14:51 21 jul 2009 de Ale holman (discusión | contribuciones) (Validamos el mensaje contra el esquema xml)
Saltar a: navegación, buscar

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.

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":

Aqualogic demoFactura 1.jpg

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

Aqualogic demoFactura 2.jpg

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:”

Aqualogic demoFactura 3.jpg

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

Aqualogic demoFactura 4.jpg

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

Aqualogic demoFactura 5.jpg

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:

Aqualogic demoFactura 6.jpg

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”.

Aqualogic demoFactura 7.jpg

Seteamos request y response como texto:

Aqualogic demoFactura 8.jpg

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 “.”)

Aqualogic demoFactura 9.jpg

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

Aqualogic demoFactura 10.jpg

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”:

Aqualogic demoFactura 11.jpg

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

Aqualogic demoFactura 12.jpg

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:

Aqualogic demoFactura 13.jpg

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

Aqualogic demoFactura 14.jpg

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:

Aqualogic demoFactura 15.jpg

Y definimos un ruteo:

Aqualogic demoFactura 16.jpg Aqualogic demoFactura 17.jpg Aqualogic demoFactura 18.jpg

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

Aqualogic demoFactura 19.jpg

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

Aqualogic demoFactura 20.jpg

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:

Aqualogic demoFactura 21.jpg

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

Aqualogic demoFactura 22.jpg

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.

Aqualogic demoFactura 23.jpg

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:

Aqualogic demoFactura 24.JPG

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.

Aqualogic demoFactura 25.JPG

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

Aqualogic demoFactura 26.JPG

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.

Aqualogic demoFactura 27.JPG

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í:

Aqualogic demoFactura 28.JPG

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

Aqualogic demoFactura 29.JPG

Nos agrega:

Aqualogic demoFactura 30.JPG

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

Aqualogic demoFactura 31.JPG

Y en Add action agregamos un fault:

Aqualogic demoFactura 32.JPG

Completamos el código y mensaje para el error:

Aqualogic demoFactura 33.JPG

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

Aqualogic demoFactura 34.JPG