Adding a property to xml request - ruby

I'm using Savon Ruby gem to call a SOAP API, I have the request almost ready but one thing is bugging still.
savonclient = Savon.client(wsdl: 'test.wsdl',
endpoint: 'http://endpoint.biz/',
log: true,
log_level: :debug,
pretty_print_xml: true,
convert_request_keys_to: :none,
namespaces: { 'xmlns:buggy' => 'http://otherdomain.biz/something.xsd'},
soap_header: { 'buggy:client' => {
"id:property1" => 'value1',
"id:property2" => 'value2'
}
This produces
<env:Header>
<buggy:client>
<id:property1>value1</id:property1>
<id:propert2>value2</id:property2>
</buggy:client>
What I need is to have property after buggy:client, like this:
<buggy:client id:objecttype="something">
I tried adding attributes hash for the soap_header, but it only creates a new attribute below .
Any ideas?

Related

Connect to a SOAP API with savon and specify Domain

With SoapUI, I am successfully connecting to a SOAP API with details such as:
Initial WSDL: http://11.11.1.11:7303/FOO/BAR/BAZ
Username: foo
Password: bar
Domain: example
But I am not sure how to do this with Savon. I am trying this (not quite understanding if ntlm is the correct setting here):
savon_defaults = {
:wsdl => "http://11.11.1.11:7303/FOO/BAR/BAZ",
:ntlm => ["foo", "bar", "example"],
:log_level => :debug,
:pretty_print_xml => true,
:log => true
}
#client = Savon.client(savon_defaults)
#client.call(:foo, :message => {:bar => "baz"})
The above outputs:
D, [2020-05-18T21:21:14.853929 #7156] DEBUG -- : HTTPI /peer GET request to 11.11.1.11 (httpclient)
Savon::HTTPError: HTTP error (401)
Any ideas?

How to create SOAP nested headers with SAVON

I would like to generate following soap header with SAVON but cannot really find any proper documentation for it any help would be appreciated.
<SOAP-ENV:Header>
<trp:protocolVersion>4.0</trp:protocolVersion>
<trp:id>*******</trp:id>
<trp:userId>*******</trp:userId>
<trp:service crv:objectType=“SERVICE”>
<crv:memberClass>xxxxxx</crv:memberClass>
<crv:memberCode>xxxxxx</crv:memberCode>
<crv:subsystemCode>xxxxxxxx</crv:subsystemCode>
<crv:serviceCode>xxx</crv:serviceCode>
</trp:service>
</SOAP-ENV:Header>
This is what I have so far, but I am struggling to build the nested objectType in the header
{
"trp:protocolVersion" => 4.0
"trp:id" => id,
"trp:userId" => user_id
"trp:service" => {
'',
:attributes!=> {
'trp:service' => {'objectType' =>'SERVICE'}} },
}

savon gem example_body not coming properly

I have a wsdl url to give request and get response this is my code(using savon gem for this)
client = Savon.new('http://services.chromedata.com/Description/7a?wsdl')
service = :Description7a
port = :Description7aPort
operation = :getDivisions
division = client.operation(service, port, operation)
I am able to print example_body like
division.example_body
=> {:DivisionsRequest=>{:accountInfo=>{:_number=>"string", :_secret=>"string", :_country=>"string", :_language=>"string", :_behalfOf=>"string"}, :_modelYear=>"int"}}
and i'm able to set values like
division.body = {.........}
other operation such like
operationlist = client.operations(service, port)
=> ["getVersionInfo", "getModelYears", "getDivisions", "getSubdivisions", "getModels", "getStyles", "describeVehicle", "getCategoryDefinitions", "getTechnicalSpecificationDefinitions"]
I used describe vehicle
desc_veh = client.operation(service, port, "describeVehicle")
whose example_body is like
desc_veh.example_body
=> {:VehicleDescriptionRequest=>{}}
so unable to set values for desc_veh.body and the use the .call function
I don know whether it is a savon gem problem or the wsdl url problem
Your code could look like this:
gem "savon", "~> 2.0"
require "savon"
client = Savon.client(
:wsdl => 'http://services.chromedata.com/Description/7a?wsdl',
:convert_request_keys_to => :camelcase,
:log => true,
:log_level => :debug,
:pretty_print_xml => true
)
res = client.call(:get_divisions,
message: { :param1 => 'value1', :param2 => 'value2' }
)
print res.to_hash
The parameters are simply a hash in key/value pairs.

Authenticate with http headers with savon 2.3.0

I had this code in Savon v1:
client = Savon.client("http://www.server.com:9191/soapserver?wsdl")
service = client.request :get_authentication do
client.http.headers["username"] = "myuser"
client.http.headers["password"] = "mypass"
end
After the update to savon v2.3.0, I don't manage to retranslate. It should be something like
client = Savon.client do
wsdl "http://www.shab.ch:9191/soapserver?wsdl
end
service = client.call(:get_authentication, {username: "myuser", password: "mypass"})`
but the line service = client.call(..." does not work. Any idea?
I think what you want to do is:
gem "savon"
require "savon", "~>2.0"
...
client = Savon.client(headers: { username: "user", password: "password"},
wsdl: "http://www.example.com/?wsdl",
log: true,
log_level: :debug,
pretty_print_xml: true
#, and more options here if necessary)
That will inject the key/values pairs into the http headers.
That last code block of yours is missing a " on line #2 and has a ``` too much in the end. It should look like:
client = Savon.client do
wsdl "http://www.shab.ch:9191/soapserver?wsdl"
end
service = client.call(:get_authentication, {username: "myuser", password: "mypass"})
to not trigger any syntax errors.
This works for me after a lot of trial and error:
client = Savon.client( wsdl: "http://www.server.com:9191/soapserver?wsdl", <\br>
headers: {'username' => 'myuser', 'password' => 'mypass'} )
service = client.call(:get_authentication)
So the header injection I do before calling the :get_authentication function.

Constructing this SOAP header properly?

I'm attempting to build a proper SOAP header:
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:sen="https://webservices.averittexpress.com/SendWebImageService">
<soapenv:Header
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <ns:authnHeader
soapenv:mustUnderstand="0"
xmlns:ns="http://webservices.averittexpress.com/authn">
<Username>xxxxxxxx</Username> <Password>xxxxxxxx</Password>
</ns:authnHeader> </soapenv:Header>
This is my Savon client call, I'm using version 2:
client = Savon.client(
wsdl: api_url,
raise_errors: false,
convert_request_keys_to: :camelcase,
element_form_default: :qualified,
env_namespace: :soapenv,
soap_header: {'username' => username, 'password' => password }
)
I'm getting the following SOAP error:
fault=>
{:faultcode=>"soapenv:Server",
:faultstring=>"java.lang.NullPointerException",
:detail=>nil}}
How do I get the sapoenv:mustUserstand="0" line, and what is it?
Plus I'm confused how to set the xmlns:ns="http://webservices.averittexpress.com/authn">.
I've little experience using SOAP requests, and am coming from a Ruby/Rails RESTful background. Any help would be appreciated.
Savon uses Gyoku to convert both SOAP header and body to XML.
Following this libraries conventions, here's what your Hash needs to look like:
soap_header = {
"ns:authnHeader" => {
"#soapenv:mustUnderstand" => 0,
"#xmlns:ns" => "http://webservices.averittexpress.com/authn",
"Username" => "x",
"Password" => "x"
}
}
Savon.client(:soap_header => soap_header)

Resources