Diferencias en servicios SOAP de GeneXus Evo3 y GeneXus 16.
Realizando una conversión de una KB que está en GeneXus Evo3 a GeneXus 16, tenemos varios servicios web con protocolo SOAP. Despues de tener algunos inconvenientes con las pruebas de los mismos, tuve que hacer la comparación mas exhaustiva de la salida de los servicios SOAP y comparar los resultados.
En las pruebas me lleve varias sorpresas.
Hice un web service soap (procedure/main/call protocol=SOAP/Use SOAP native=NO) que recibe un SDT con un numero con signo de -N(8.2) y asi como lo recibe lo devuelve.
&SDTEntrada Collection=True
&Numero -N(8.2)
con la regla
parm(in:&SDTEntrada,out:&SDTSalida);
y el código
//Asigno lo mismo que recibo.
&SDTSalida = &SDTEntrada
Los Request que se envían a ambos sistemas en Evo3 y GX16 son parecidos a
y la salida es de la forma:
La tabla de comparación de las salidas tiene:
En general, me gusta mucho mas como funciona en la versión nueva que en la vieja, pero como son varios los casos en que los request funcionan diferente, hay que prepararse para tener algunos líos de soporte cuando los usuarios manden request que trabajan con la version vieja a la versión nueva.
En los casos que GX16 dea SOAP-ENV:Fault, esta diciendo que recibe un request invalido, pero termina con código HTTP 200 y debería terminar con un HTTP 500 (como indica el protocolo SOAP ) para que la aplicación cliente sepa que hay un error.
Tengo que repetir estas pruebas de regresión, para los demás tipos de datos (fechas, fecha hora, booleanos, texto, etc). Pinta divertido.
Y una recomendación para que los nuevos desarrollos de servicios SOAP hacerlos con la propiedad Use SOAP Native = Yes, para ahorrarnos dolores de cabeza.
En las pruebas me lleve varias sorpresas.
Hice un web service soap (procedure/main/call protocol=SOAP/Use SOAP native=NO) que recibe un SDT con un numero con signo de -N(8.2) y asi como lo recibe lo devuelve.
&SDTEntrada Collection=True
&Numero -N(8.2)
con la regla
parm(in:&SDTEntrada,out:&SDTSalida);
y el código
//Asigno lo mismo que recibo.
&SDTSalida = &SDTEntrada
Los Request que se envían a ambos sistemas en Evo3 y GX16 son parecidos a
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:kbn="KBNamespace"> <soapenv:Header/> <soapenv:Body> <kbn:Procedure11_redondeoSDT.Execute> <kbn:Entradanumeros> <kbn:Numeros.NumerosItem> <kbn:Numero>8888888888888</kbn:Numero> </kbn:Numeros.NumerosItem> </kbn:Entradanumeros> </kbn:Procedure11_redondeoSDT.Execute> </soapenv:Body> </soapenv:Envelope>
y la salida es de la forma:
<?xml version = "1.0" encoding = "utf-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <SOAP-ENV:Body> <Procedure11_redondeoSDT.ExecuteResponse xmlns="KBNamespace"> <Salidanumeros xmlns="KBNamespace"> <Numeros.NumerosItem xmlns="KBNamespace"> <Numero>**********</Numero> </Numeros.NumerosItem> </Salidanumeros> </Procedure11_redondeoSDT.ExecuteResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
La tabla de comparación de las salidas tiene:
En general, me gusta mucho mas como funciona en la versión nueva que en la vieja, pero como son varios los casos en que los request funcionan diferente, hay que prepararse para tener algunos líos de soporte cuando los usuarios manden request que trabajan con la version vieja a la versión nueva.
En los casos que GX16 dea SOAP-ENV:Fault, esta diciendo que recibe un request invalido, pero termina con código HTTP 200 y debería terminar con un HTTP 500 (como indica el protocolo SOAP ) para que la aplicación cliente sepa que hay un error.
Tengo que repetir estas pruebas de regresión, para los demás tipos de datos (fechas, fecha hora, booleanos, texto, etc). Pinta divertido.
Y una recomendación para que los nuevos desarrollos de servicios SOAP hacerlos con la propiedad Use SOAP Native = Yes, para ahorrarnos dolores de cabeza.
Hola Enrique, te hago una consulta sobre tu ejemplo... usas un SDT Collection como parámetro de entrada del WS. Lo consumís desde SOAPUI ?
ResponderBorrarNo hemos conseguido hacer funcionar eso desde Genexus 9 hasta Evo 3, con generador Java web. He leído que algunos tuvieron el mismo problema pero no encuentro solución.
Vos estás usando .net o java?
Probamos armando el SDT de muchas formas, también probamos con el SDT simple y la variable del prc como collection, los resultados son los mismos...
por ej, al enviar este xml:
X
X
X
X
Nos devuelve:
SOAP-ENV:Client
X
X
X
X
]]>
2
Cualquier idea que nos puedas aportar nos ayuda.
Saludos
No quedo bien formateado el mensaje y no se puede leer.
Borrarah, perdón, los tags xml se convirtieron, a ver así
Borrarrequest:
<fen:TrackingCP.Execute>
<fen:Cpeventosrequest>
<!--Zero or more repetitions:-->
<fen:CPEventosRequest>
<fen:cporigen>X</fen:cporigen>
<fen:cpnro>X</fen:cpnro>
<fen:cpfecha>X</fen:cpfecha>
<fen:cpinfadi>X</fen:cpinfadi>
</fen:CPEventosRequest>
</fen:Cpeventosrequest>
</fen:TrackingCP.Execute>
response:
<TrackingCP.ExecuteResponse xmlns="Fenix">
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Client</faultcode>
<faultstring><![CDATA[Error reading fen:TrackingCP.Execute
Message: <fen:CPEventosRequest>
<fen:cporigen>X</fen:cporigen>
<fen:cpnro>X</fen:cpnro>
<fen:cpfecha>X</fen:cpfecha>
<fen:cpinfadi>X</fen:cpinfadi>
</fen:CPEventosRequest>]]></faultstring>
<detail>2</detail>
</SOAP-ENV:Fault>
</TrackingCP.ExecuteResponse>
Ahora que salió bien el xml, completo con algunas observaciones:
ResponderBorrar- El procedimiento solo recibe el SDT como parámetro y devuelve una variable varchar(200) con un texto fijo, no hace nada adentro.
- Ese error lo arroja cuando el SDT de entrada es una colección.
- Si no es colección funciona correctamente
- Si se agrega al SDT una subestructura como colección, al consumir el enviando datos de esa subestructura da el mismo error, pero si no se envían datos funciona correctamente
Saludos
Si, hemos consumido muchos servicios soap con java, en varias versiones.
ResponderBorrarSi tenes el WSDL del servicio, lo mejor es consumirlo desde SOAPui, pasandole varios valores a la coleccion y viendo el resultado correcto, guardandote el request y el response correcto
Luego en GeneXus, importas dicho WSDL y ves si te da algun error.
Al ejecutarlo vas a ver el request y el response.
Si el request queda mal armado, puede ser que necesites usar el httprequest para armarlo, en caso que GeneXus lo este armando mal.
Es imposible solo viendo el request saber si algo esta bien o mal, pues hay que compararlo con el wsdl y es una tarea bastante complicada para los seres humanos, pero facil para las maquinas.