Qual é a melhor maneira de usar o SABÃO com Ruby?
-
09-06-2019 - |
Pergunta
Um cliente meu me pediu para integrar uma parte 3ª API em suas Trilhos app.O único problema é que a API usa SABÃO.Ruby tem, basicamente, caiu de SABÃO em favor do RESTO.Eles fornecem um Java adaptador que aparentemente funciona com o Java, Ruby ponte, mas gostaríamos de manter tudo em Ruby, se possível.Eu olhei para soap4r, mas ele parece ter um pouco de má reputação.
Então, qual é a melhor forma de integrar as chamadas SOAP em uma app Rails?
Solução
Usamos o construído em soap/wsdlDriver
de classe, que, na verdade, é SOAP4R.É cão lento, mas muito simples.O SOAP4R que você começa a partir de gemas/etc é apenas uma versão atualizada da mesma coisa.
Exemplo de código:
require 'soap/wsdlDriver'
client = SOAP::WSDLDriverFactory.new( 'http://example.com/service.wsdl' ).create_rpc_driver
result = client.doStuff();
É sobre isso
Outras dicas
Eu construí Savon para tornar a interação com SABÃO webservices via Ruby tão fácil quanto possível.
Eu recomendo que você confira.
Nós mudamos do Handsoap para Savon.
Aqui é um série de posts do blog comparando as duas bibliotecas de cliente.
Eu também recomendo Savon.Eu passei muitas horas tentando lidar com Soap4R, sem resultados.Grande falta de funcionalidade, ausência de doc.
Savon é a resposta para mim.
Tente SOAP4R
E eu só ouviu falar sobre os Trilhos Inveja Podcast (pe 31):
Só tenho o meu material de trabalho dentro de 3 horas, utilizando Savon.
A documentação de introdução no Savon da página inicial foi realmente fácil de seguir, e correspondia o que eu estava vendo (não sempre o caso)
Kent Sibilev de Datanoise também tinha portado Trilhos ActionWebService biblioteca do Rails 2.1 (e acima).Isso permite que você exponha seu próprio Ruby-com base de SABÃO de serviços.Ele tem até um andaime/modo de teste que permite que você teste os seus serviços através de um navegador.
Eu estava tendo o mesmo problema, ligado Savon e, em seguida, apenas testei em um abrir WSDL (eu usei http://www.webservicex.net/geoipservice.asmx?WSDL) e muito bom!
Eu tenho usado o SABÃO em Ruby, quando eu tive de fazer um falso servidor SOAP para os meus testes de aceitação.Eu não sei se essa foi a melhor maneira de abordar o problema, mas ele trabalhou para mim.
Eu tenho usado Sinatra gem (eu escrevi sobre a criação de zombando de pontos de extremidade com Sinatra aqui) para o servidor e também Nokogiri para XML coisas (SOAP é trabalhar com XML).
Assim, para o início eu tenha que criar dois arquivos (e.g.config.rb e respostas.rb) em que eu pus o predefinidos respostas que o SOAP server vai voltar.No config.rb Eu coloquei o arquivo WSDL, mas como uma seqüência de caracteres.
@@wsdl = '<wsdl:definitions name="StockQuote"
targetNamespace="http://example.com/stockquote.wsdl"
xmlns:tns="http://example.com/stockquote.wsdl"
xmlns:xsd1="http://example.com/stockquote.xsd"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns="http://schemas.xmlsoap.org/wsdl/">
.......
</wsdl:definitions>'
No respostas.rb Eu coloquei exemplos para as respostas que o SABÃO servidor irá retornar para diferentes cenários.
@@login_failure = "<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<LoginResponse xmlns="http://tempuri.org/">
<LoginResult xmlns:a="http://schemas.datacontract.org/2004/07/WEBMethodsObjects" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:Error>Invalid username and password</a:Error>
<a:ObjectInformation i:nil="true"/>
<a:Response>false</a:Response>
</LoginResult>
</LoginResponse>
</s:Body>
</s:Envelope>"
Então deixe-me mostrar como eu realmente ter criado o server.
require 'sinatra'
require 'json'
require 'nokogiri'
require_relative 'config/config.rb'
require_relative 'config/responses.rb'
after do
# cors
headers({
"Access-Control-Allow-Origin" => "*",
"Access-Control-Allow-Methods" => "POST",
"Access-Control-Allow-Headers" => "content-type",
})
# json
content_type :json
end
#when accessing the /HaWebMethods route the server will return either the WSDL file, either and XSD (I don't know exactly how to explain this but it is a WSDL dependency)
get "/HAWebMethods/" do
case request.query_string
when 'xsd=xsd0'
status 200
body = @@xsd0
when 'wsdl'
status 200
body = @@wsdl
end
end
post '/HAWebMethods/soap' do
request_payload = request.body.read
request_payload = Nokogiri::XML request_payload
request_payload.remove_namespaces!
if request_payload.css('Body').text != ''
if request_payload.css('Login').text != ''
if request_payload.css('email').text == some username && request_payload.css('password').text == some password
status 200
body = @@login_success
else
status 200
body = @@login_failure
end
end
end
end
Eu espero que você vai encontrar este útil!
Eu tenho usado o HTTP chamada como a seguir para chamar um método de SABÃO,
require 'net/http'
class MyHelper
def initialize(server, port, username, password)
@server = server
@port = port
@username = username
@password = password
puts "Initialised My Helper using #{@server}:#{@port} username=#{@username}"
end
def post_job(job_name)
puts "Posting job #{job_name} to update order service"
job_xml ="<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ns=\"http://test.com/Test/CreateUpdateOrders/1.0\">
<soapenv:Header/>
<soapenv:Body>
<ns:CreateTestUpdateOrdersReq>
<ContractGroup>ITE2</ContractGroup>
<ProductID>topo</ProductID>
<PublicationReference>#{job_name}</PublicationReference>
</ns:CreateTestUpdateOrdersReq>
</soapenv:Body>
</soapenv:Envelope>"
@http = Net::HTTP.new(@server, @port)
puts "server: " + @server + "port : " + @port
request = Net::HTTP::Post.new(('/XISOAPAdapter/MessageServlet?/Test/CreateUpdateOrders/1.0'), initheader = {'Content-Type' => 'text/xml'})
request.basic_auth(@username, @password)
request.body = job_xml
response = @http.request(request)
puts "request was made to server " + @server
validate_response(response, "post_job_to_pega_updateorder job", '200')
end
private
def validate_response(response, operation, required_code)
if response.code != required_code
raise "#{operation} operation failed. Response was [#{response.inspect} #{response.to_hash.inspect} #{response.body}]"
end
end
end
/*
test = MyHelper.new("mysvr.test.test.com","8102","myusername","mypassword")
test.post_job("test_201601281419")
*/
Espero que ajude.Cheers.