lunes, 6 de febrero de 2017

Consumir Web Service Seguro NO Genexus

¡Hola a todos!

En estos últimos años he participado (y lo sigo haciendo) en varios proyectos que consisten en adaptar sistemas de facturación ya operativos a las exigencias de e-factura que impulsó DGI (Dirección General Impositiva) en nuestro país.
DGI expone Web Services a través de los cuales se debe enviar on line cierta información referente a la facturación de la empresa. En cuanto a la comunicación con estos Web Services, hemos trabajado con un socio de negocios que se encarga de resolver esa problemática. Lo positivo de esto es que este sistema (middleware para nosotros) nos brinda distintas alternativas de comunicación con ellos, lo que nos ha permitido optar entre ellas según las necesidades de nuestros clientes.

Entonces, yendo a la problemática que quisiera compartir, en uno de nuestros clientes hemos tenido que encontrar una solución al consumo de WS Seguro desde Genexus 9, generando Java Web, desplegando la aplicación en un Tomcat 6 y utilizando BD Postgres (tener en cuenta que queremos consumir un WS Seguro NO GENEXUS).

Las alternativas que tenemos son servicios web SOAP o REST, en ambos casos utilizando Certificado + Usuario y Contraseña.

Entonces, investigando sobre el consumo de WS Seguros desde GX encontramos bastante información útil, aquí van los links


SOAP: se consume el WSDL tal como se hace con un WS SOAP común, la diferencia es que la URL del WSDL es https. Acá algunos links sobre el uso de WSDL en versiones GX9 o inferior y en GX Evolution.


REST: no es necesario utilizar WSDL Inspector, si no que directamente se consume configurando un HttpClient

HttpClient: permite implementar ambas alternativas, tanto SOAP como REST, aquí unos links.


Extra: a continuación van algunos links sobre el consumo de servicios web seguros utilizando Java y Tomcat


Son varios los problemas que hemos encontrado, vamos por partes...
  • Necesitamos consumir desde una app web un WS Seguro (Certificado + Usuario-Contraseña) desde una KB GX9 (Dev. U7, Java U5). Utilizamos Tomcat 6 y el tema del certificado está resuelto, ya que se instaló en un KeyStore del Tomcat tal como se explica en uno de los links anteriores y no da problemas. El problema surge con Usuario y Contraseña.
    • Intentando consumirlo con SOAP, nos dio error por falta de credenciales porque GX no agrega Usuario y Contraseña en los Headers del mensaje SOAP
    • Intentando consumirlo con REST, nos dio error por falta de credenciales porque GX no agregar Usuario y Contraseña en los Headers del mensaje HTTP
  • Dada la situación, decidimos probar lo mismo pero en Evo3 U4 (última versión disponible de GX en ese momento)
    • En SOAP obtuvimos el mismo error
    • En REST funcionó!
  • Entonces decidimos usar como "puente" la webapp en Evo3 U4 y consumir desde GX9 otro servicio publicado en esa webapp "puente". Dado que estaría en el mismo servidor, no utilizaríamos los mecanismos de seguridad que no funcionan y además la comunicación sería de GX a GX.
    • En SOAP funcionó!
    • En REST obtenemos un error 415 (Unsupported Media Type) porque intentamos consumirlo utilizando XML, ya que JSON no podemos desde GX9 (Nota: por las dudas hicimos algunas pruebas y ese WS en Evo3 funciona bien, porque lo consumimos como JSON desde la misma webapp "puente")

En definitiva, más allá de que logramos una solución utilizando GX9 >>> SOAP >>> GXEvo3U4 >>> REST >>>> WS SEGURO NO GX, es una solución un poco rebuscada (preferiríamos poder consumir el WS Seguro directamente desde GX9 (ya sea SOAP o REST). Algo positivo es que el middleware que utilizamos nos dio la posibilidad de consumir el WS SOAP con Usuario-Contraseña en un campo específico del cuerpo del mensaje. Sin embargo, esta última opción tampoco funcionó desde GX9...

Hicimos varias pruebas implementando de maneras diferentes el consumo del WS desde GX9 con la opción de Usuario-Contraseña en un campo específico del cuerpo del mensaje, pero no dimos con una solución. Las alternativas que probamos desde GX9 consumiendo el WS SOAP fueron:
  • Invoke() del web service pasando como parámetro un sdt: no funcionó porque la estructura del xml que generaba genexus no cumplía con ciertos requisitos del servidor y además faltaban algunos Headers
  • &httpClient.AddString() pasando como parámetro un sdt: aunque pudimos editar los Headers, no funcionó porque la estructura del xml que generaba genexus no cumplía con ciertos requisitos del servidor
  • &writer.OpenRequest(&httpClient) en donde &writer era una variable de tipo XMLWriter: aunque el cuerpo del mensaje lo armamos todo nosotros, la respuesta del servicio incluía el Header “Set-Cookie=ASP.NET_SessionId=...; path=/; HttpOnly” que no es soportado por GX9-Java
En fin, tuvimos bastantes problemas a lo largo de la búsqueda de la solución. Es una lástima encontrarse con tantas limitantes, quizás algunas por falta de conocimientos de nuestra parte o quizás por falta de fortuna en la combinación de las versiones de las tecnologías involucradas, pero bueno... son los riesgos que se corren cuando se utiliza una versión de Genexus que no es de las últimas y que por lo tanto hay temas técnicos de actualidad que naturalmente no están resueltos (y dificilmente se resuelvan a esta altura) y lleva su trabajo encontrar un work around.

En definitiva, terminamos utilizando WS SOAP desde GX9 haciendo “puente” con WS SOAP desde Evo3 U4 con Certificado en el Tomcat y Usuario-Contraseña en un campo específico del cuerpo del mensaje.




¡Hasta la próxima!

No hay comentarios:

Publicar un comentario