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!
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
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:
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¡
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.
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¡
Suscribirse a:
Entradas (Atom)