Consumir Web Service .NET con clientes Java mediante Aqualogic
Contenido
Contexto
Consumir un Webservice realizado en .NET utilizando DataSet, a la cual no tenemos posibilidad de modificar el contrato (WSDL).
En el WSDL, como respuesta de operación tenemos:
...
...
<s:element name="BuscarAlumnoResponse">
<s:complexType> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="BuscarAlumnoResult"> <s:complexType> <s:sequence> <s:element ref="s:schema" /> <s:any /> </s:sequence> </s:complexType>
...
...
Cuando al consumir el WebService nos responde:
<xs:schema xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="NewDataSet">
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:Locale="">
... ... </xs:schema> <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1"> <NewDataSet xmlns="">
... </NewDataSet> </diffgr:diffgram> ... ...
Problema
Si queremos consumir el WSDL desde un cliente java, al quere mapear el WSDL (por ejemplo con jaxb) nos dará el siguiente error: [ERROR] undefined element declaration 's:schema'
Explicación
Observando el WSDL, podemos ver que al generar la clase que representan a la respuesta de la operación (BuscarAlumnoResponse), jaxb desconoce como resolver
<s:element ref="s:schema" />
<s:any />
Lo que nos esta diciendo el WSDL es que la operación buscarAlumno, tiene como respuesta un elemento schema y cualquier tipo de objeto como respuesta.
Como vemos en el contrato del servicio, no esta definido realmente el tipo de respuesta (no lo sabemos hasta el momento de ejecutar la operación) lo que nos dificulta la creación del cliente.
Solución
Una posible solución es utilizar un Aqualogic Service Bus, para consumir el webservice y exponerlo en un contrato amigable.
En el Aqualogic, generaremos un proyecto en el cual business sea consumidor del webservice .NET y el proxy es en contrato que expondremos a los clientes Java, para esto último utilizaremos un XSLT para transformar la respuesta del webservice.
Los pasos serían:
1. Definir el nuevo contrato de la operación a exponer
En nuestro caso solo modificaremos la respuesta de la operación:
...
...
<s:element name="BuscarAlumnoResponse">
<s:complexType> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="BuscarAlumnoResult"> <s:complexType> <s:sequence>
<s:element name="alumnos" type="tns:Alumno" minOccurs="0" maxOccurs="unbounded" />
</s:sequence> </s:complexType> </s:element> </s:sequence> </s:complexType>
</s:element>
<s:complexType name="Alumno" >
<s:sequence> <s:element name="legajo" type="s:string" minOccurs="0"/> <s:element name="nombre" type="s:string" minOccurs="0"/> <s:element name="apellido" type="s:string" minOccurs="0"/> </s:sequence>
</s:complexType> ... ...
2. Generar un XSLT
Generaremos un XSLT para transformar la respuesta del servicio .NET al nuevo WSDL que expondremos:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dosideas="http://dosideas.com/dataset">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/> <xsl:template match="*"> <xsl:for-each select="current()/*/*[2]/*"> <xsl:element name="dosideas:BuscarAlumnoResult" namespace="http://dosideas.com/dataset" > <xsl:for-each select="current()/*"> <xsl:element name="dosideas:alumnos" namespace="http://dosideas.com/dataset"> <xsl:for-each select="current()/*"> <xsl:element name="dosideas:{local-name()}" namespace="http://dosideas.com/dataset"> <xsl:apply-templates/> </xsl:element> </xsl:for-each> </xsl:element> </xsl:for-each> </xsl:element> </xsl:for-each> </xsl:template>
</xsl:stylesheet>
3. Exponer el servicio en el Aqualogic Service Bus
Con los WSDL y XSLT generados, realizaremos los siguientes pasos: 3.1 Subir el WSDL del servicio .NET
3.2 Subir el nuevo WSDL del servicio.
3.3 Subir el XSLT para transformar la respuesta.
3.4 Crear un Business Service para consumir el servicio .NET
3.5 Crear un Proxy Service que consuma el Business Service y exponga el resultado según el nuevo contrato.
3.6 Configurar el Proxy Service (Message Flow) para modificar la respuesta del Business Service.
- 3.6.1 Editar el Route que apunta al Business Service creado y en el Response Action, agregamos una acción de replace, donde:
- XPath: //dosideas:BuscarAlumnoResponse
- Expression: <EL XSLT>
- 3.6.2 Al Proxy, agregarle un PipelinePair, con un Stage en el Response.
- 3.6.3 En el Stage del Response:
- XPath: . (El carácter punto)
- Variable: body
- Expression: $body
- Replace entire node