Mostrando entradas con la etiqueta wsdl. Mostrar todas las entradas
Mostrando entradas con la etiqueta wsdl. Mostrar todas las entradas

martes, 20 de mayo de 2008

Web Services: mensaje con formato

N veces he tenido que desarrollar conectores contra un web service utilizando las clases SOAP de Ruby y las N he necesitado ver los mensajes que se envían con un formato decente. Lo mejor que se me ha ocurrido ha sido sacar una traza desde soap/rpc/proxy.rb.

En envío lo realiza el método route

conn_data = @streamhandler.send(@endpoint_url, conn_data, reqopt[:soapaction])

Justo antes pondremos la traza, por ejemplo, por consola

puts conn_data.send_string

Salud y rocanrol!

jueves, 4 de octubre de 2007

SOAP hasta en la SOPA

Madre del amor¡

Llevo tres días intentando desentrañar cómo acceder a un Web Service que no tiene descubrimiento por wsdl. Lo único que tenía era unos xsd medio decentes (y digo medio decentes porque xsd2ruby cascaba al ejecutarlo contra ellos) y unos fuentes java que se supone que funcionan. Además, el acceso se realiza sin SOAP action.

Después de intentar emular al script wsdl2ruby y generar los objetos y métodos que él genera con estas manitas y mi tricotosa he tenido que generar un mensaje con su SOAPHeader y su SOAPBody y enviarlo por el método invoke de SOAP::RPC::Driver. Entre todas las pruebas que he tenido que hacer destaco estas tres:

  • después de observar un mensaje recibido como error del servidor de destino, vi que su SOAPBody contenía objetos SOAPStruct e intenté emularlo para crear la estructura XML que el servidor entiende.
  • tuve que cambiar todos los SOAPStruct por SOAPElement porque el servidor aplicaba sus xsd al contenido recibido y los nodos enviados llevaban el atributo encodingstyle, no aceptado en el formato esperado.
  • cada SOAPElement se puede tratar como Hash y cada SOAPStruct como Hash y como Array.
Unas líneas de código como muestra...

driver = SOAP::RPC::Driver.new("http://localhost:8003", "http://my.namespaces")

sh = SOAP::SOAPHeader.new
sb = SOAP::SOAPBody.new
sb.add('Message', SOAP::SOAPElement.new('Message'))
sb[0].extraattr['xmlns'] = 'http://my.namespaces'
sb[0].extraattr['xmlns:xsi'] = 'http://www.w3.org/2001/XMLSchema-instance'
sb[0].extraattr['xsi:schemaLocation'] = 'http://my.schemas'
sb[0].add(SOAP::SOAPElement.new('Header'))
sb[0].add(SOAP::SOAPElement.new('Body'))
sb[0]['Header'].add(SOAP::SOAPElement.new('MessageID', "000000")) sb[0]['Body'].add(SOAP::SOAPElement.new('Operation'))
sb[0]['Body']['Operation'].add(SOAP::SOAPElement.new('Query', 'This is my query'))
sb[0]['Body']['Operation'].extraattr['OperationName'] = 'QueryRequest'
sb[0]['Body']['Operation'].extraattr['OperationType'] = 'My type'


...

@resp = driver.invoke(sh, sb)

...

code = @resp[1]['Message']['Body']['Operation']['Responses'] ['Response']['Reference']['Code'].data
0.upto((@resp[1]['Message']['Body']['Operation']['Responses'] ['Response']['Records'].members.size rescue 0) - 1) do |r|
  puts @resp[1]['Message']['Body']['Operation']['Responses'] ['Response']['Records'][r]['Id'].data
end

Salud¡