If i use savon with raw xml everything works fine, this is the raw xml example:
request = client.call(:authenticate, xml:'<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="xxxx/">
<SOAP-ENV:Body>
<ns1:authenticate>
<ns1:username>user</ns1:username>
<ns1:password>pwd</ns1:password>
<ns1:cultureInfo>it</ns1:cultureInfo>
</ns1:authenticate>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>')
If I use the builtin method to call the method I got an error, this is the code:
credentials={ username: 'user', password: 'pwd!!', cultureInfo: "it" }
response = client.call(:authenticate, message: credentials)
This is the xml produced by the above code:
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:wsdl="http://tempuri.org/"
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Body>
<wsdl:authenticate>
<username>user</username>
<password>pwd</password>
<cultureInfo>it</cultureInfo>
</wsdl:authenticate>
</env:Body>
</env:Envelope>
Any Idea?
I usually do just this (untested). It's not pretty but it works.
credentials = { 'ns1:username' => 'user',
'ns1:password' => 'pwd!!',
'ns1:cultureInfo' => "it" }
response = client.call(:authenticate, message: credentials)
You might want to adapt the use of ns1 to the actually used namespace in your case.
Related
I need to hit a SOAP service, however, the server won't accept my request but throws an error due to the below header and footer in the request.
As per the logs, the request/response looks like below:
SOAP **request**: http://www.url.co.au/wserv/wslms.php
SOAPAction: "insertlmsdata", Content-Type: text/xml;charset=UTF-8, Content-Length: 938
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tns="urn:lmsdataautomation" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Body>
<tns:insertlmsdata>
<lmsinfo>
<userCred>
<clientCode>code</clientCode>
<username>name</username>
<password>ee##!</password>
</userCred>
<lead>
<requestno>3</requestno>
<firstname>Meckinsey</firstname>
<lastname>Meth</lastname>
<email>meckinsey.meth#er.com</email>
<mobileno>4233333333</mobileno>
<keyword>Romali</keyword>
<requestMessage>looking for Romali</requestMessage>
<responseMessage>Romadd</responseMessage>
<operator>you</operator>
<circle>Romaon</circle>
<requestDate>20-04-2017</requestDate>
<shortCode>2222</shortCode>
<category>DOM</category>
<city>Sydney</city>
<destination>Perth</destination>
</lead>
</lmsinfo>
</tns:insertlmsdata>
</env:Body>
</env:Envelope>
HTTPI POST request to www.egggo.co.au (excon)
SOAP **response** (status 200)
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:lmsdataautomation" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:insertlmsdataResponse>
<output xsi:type="xsd:string"><output>Either parsed xml is not valid or contains special chars like & "'</output></output>
</ns1:insertlmsdataResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
I have looked thoroughly Savon Documentation, couldn't find anything relevant. Can I configure Savon to not add headers, footer, envelope and just the body?
Basically to ignore the below data:
SOAP request: http://www.url.co.au/wserv/wslms.php
SOAPAction: "insertlmsdata", Content-Type: text/xml;charset=UTF-8, Content-Length: 938
Otherwise, the SOAP server rejects the request. Please help, TIA
Adding the body of the request:
client = Savon.client(wsdl: url, log: true, logger: Rails.logger, log_level: :debug, pretty_print_xml: true, encoding: 'UTF-8')
response = client.call(:insertlmsdata, message: {'lmsinfo'=> {'userCred'=> {'clientCode' => 'code', 'username' => 'dom', 'password' => '#pass' }, 'lead' => {'requestno' => 3, 'firstname'=>'Methyl', 'lastname'=> 'Orange', 'email' => 'methyl.orange#egg.com', 'mobileno' => '55555555', 'keyword' => 'atlanta', 'requestMessage' => 'looking for atlant', 'responseMessage' => 'dd', 'operator' => 'you', 'circle' => 'sydney', 'requestDate' => '04-20-2017', 'shortCode' => 2222, 'category'=> 'DOM', 'city' => 'Sydney', 'destination' => 'Atlanta' } } })
I am having a hard time figuring out how to match stub_request with XML requests using webmock.
Request:
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Header>
<RequesterCredentials xmlns="urn:ebay:api:PayPalAPI" xmlns:n1="urn:ebay:apis:eBLBaseComponents" env:mustUnderstand="0">
<n1:Credentials>
<n1:Username>XYZ</n1:Username>
<n1:Password>ABC</n1:Password><n1:Subject/>
<n1:Signature>HUGE-STRING</n1:Signature>
</n1:Credentials>
</RequesterCredentials>
</env:Header>
<env:Body>
<ManageRecurringPaymentsProfileStatusReq xmlns="urn:ebay:api:PayPalAPI">
<ManageRecurringPaymentsProfileStatusRequest xmlns:n2="urn:ebay:apis:eBLBaseComponents">
<n2:Version>124</n2:Version>
<n2:ManageRecurringPaymentsProfileStatusRequestDetails>
<ProfileID>sdaddsadsd</ProfileID>
<n2:Action>Cancel</n2:Action>
</n2:ManageRecurringPaymentsProfileStatusRequestDetails>
</ManageRecurringPaymentsProfileStatusRequest>
</ManageRecurringPaymentsProfileStatusReq>
</env:Body>
</env:Envelope>
Stubs I tried:
stub_request(:any, /.*.sandbox.paypal.com\/2.0\//).
with(:body => WebMock::Matchers::HashIncludingMatcher.new({'n2:Action'=>'Cancel'}),
:headers => {'User-Agent'=>'Ruby'}).
to_return(:status => 200, ...
or
stub_request(:any, /.*.sandbox.paypal.com\/2.0\//).
with(query:
hash_including({ProfileID: 'sdaddsadsd'}),
:headers => {'User-Agent'=>'Ruby'}).
to_return(:status => 200, ...
(etc.)
have failed.
Anyone?
Provided you can save your XML to be stubbed into separate XML file (say request.xml), it is quite easy:
stub_request(:any, 'https://sandbox.paypal.com')
.with(body: File.read('request.xml').strip)
Headers can be omitted.
How to use webmock regex matcher? might help you with URL matching.
P.S. strip is to remove ending line feed
I want to convert the keys for xml response So that they match with third party Api request.
class Person1
include ActiveModel::Serializers::Xml
attr_accessor :name, :age
def attributes
{'name' => nil, 'age' => nil}
end
def capitalized_name
name.capitalize
end
end
p = Person1.new
p.name = "test"
puts p.to_xml
output ::-
<?xml version="1.0" encoding="UTF-8"?>
<person1>
<age nil="true"/>
<name>test</name>
</person1>
I am looking for a way to change keys in xml output like.
<?xml version="1.0" encoding="UTF-8"?>
<person1>
<Age nil="true"/>
<Name>test</Name>
</person1>
How about:
puts p.to_xml(:camelize => true)
<?xml version="1.0" encoding="UTF-8"?>
<Person1>
<Age nil="true"/>
<Name>test</Name>
</Person1>
Or if the uppercase Person bothers you, I guess you can do something like that:
puts p.to_xml(:camelize => true).sub('<Person1>','<person1>').sub('</Person1>','</person1>')
<?xml version="1.0" encoding="UTF-8"?>
<person1>
<Age nil="true"/>
<Name>test</Name>
</person1>
I am working with the Savon gem (version 2.5.1) for creating a Soap request and need if to be formatted as follows:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:soap1="urn:website.co.uk/soap:callreport7">
<soap:Header>
<soap1:callcreditheaders>
<soap1:company>?</soap1:company>
<soap1:username>?</soap1:username>
<soap1:password>?</soap1:password>
</soap1:callcreditheaders>
</soap:Header>
<soap:Body>
<soap1:Test07a>?</soap1:Test07a>
</soap:Body>
</soap:Envelope>
I have so far come up with the following:
client = Savon.client(
wsdl: "CallReport7.wsdl",
env_namespace: :soap,
soap_header: {
"soap1:callcreditheaders" => {
'soap1:company' => 'XXXX',
'soap1:username' => 'XXXX',
'soap1:password' => 'XXXX'
}
}
)
response = client.call(:test07a, message: "Test" )
This is returning an error when running in the console of:
Savon::SOAPFault: (soap:Server) An internal system error has occurred
If I remove the soap_header hash then the test runs and returns:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<Test07aResponse xmlns="website.co.uk/soap:callreport7">
<TestResult>
<datetime>2014-06-06T14:18:35.081125+01:00</datetime>
</TestResult>
</Test07aResponse>
</soap:Body>
</soap:Envelope>
The problem is I need the header information and I cannot work out how to format the request for this.
As usual: First create a valid request using SoapUI. Then build the equivalent (doesn't have to be exact the same) in Savon.
It turned out the problem was with the envelope. I enabled logging in my code so I could see the SOAP produced by Savon and this then allowed me to try the request in SoapUI and do some trial and error testing. Turned out the problem was with the Envelope so the below fixed the problem in my case:
client = Savon.client(
wsdl: "CallReport7.wsdl",
pretty_print_xml: true,
log: true,
env_namespace: :soap,
namespaces: {"xmlns:soap" => "http://www.w3.org/2003/05/soap-envelope", "xmlns:soap1" => "urn:website.co.uk/soap:callreport7"},
soap_header: {
"soap1:callcreditheaders" => {
'soap1:company' => 'XXXX',
'soap1:username' => 'XXXX',
'soap1:password' => 'XXXX'
}
}
)
response = client.call(:test07a, message: "Test" )
The logging line of code was the key to solving this problem for me.
I am trying to send a SOAP request to a resource on the web. It is expecting to receive this:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<DiscoverParameterValues xmlns="http://comscore.com/">
<parameterId>loc</parameterId>
<query xmlns="http://comscore.com/ReportQuery">
<Parameter KeyId="geo" Value="124" />
</query>
</DiscoverParameterValues>
</soap:Body>
</soap:Envelope>
This is the Ruby code that Im using to send a request that will result in an XML similar to the one above.
require 'savon'
#Connect to the Comscore API
client = Savon.client(
wsdl:"https://api.comscore.com/KeyMeasures.asmx?WSDL",
basic_auth: ["username", "pw" ],
log: true, :pretty_print_xml=>true)
And this is the XML thats generated:
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tns="http://comscore.com/"
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ins0="http://comscore.com/Report"
xmlns:ins1="http://comscore.com/ReportQuery"
xmlns:ins2="http://comscore.com/ReportModel"
xmlns:ins3="http://comscore.com/FetchMedia"
xmlns:ins4="http://comscore.com/Media/Response">
<env:Body>
<tns:DiscoverParameterValues>
<tns:parameterId>loc</tns:parameterId>
==> <tns:query>
<tns:Parameter>
<tns:attributes>
<tns:KeyId>geo</tns:KeyId>
<tns:Value>124</tns:Value>
</tns:attributes>
</tns:Parameter>
==> </tns:query>
</tns:DiscoverParameterValues>
</env:Body>
</env:Envelope>
As you can see there is a difference in how the XML from my code and the XML thats required looks. Ive marked it with "=>"
Here is the gem documentation page that Im using to structure my query:
http://savonrb.com/version2/locals.html
Ive tried playing around with this but I dont understand how to get the "attributes" to work right.
Any suggestions?
UPDATE:
After reading this post, I changed my ruby syntax to the following:
attributes = { "KeyId"=>"geo", "Value" =>"124"}
parameter = {
:parameterId=>"loc",
:query=>{ "Parameter" => { attributes: attributes}}
}
response = client.call(:discover_parameter_values,
message:{:parameterId=>"loc",
:query =>{ "Parameter"=> "", :attributes! =>
{ "Parameter" =>
{ "KeyId" => "geo" , "Value"=>"124" }}},
},
:attributes => {"xmlns" => "http://comscore.com/" })
My XML changed to this:
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tns="http://comscore.com/"
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ins0="http://comscore.com/Report"
xmlns:ins1="http://comscore.com/ReportQuery"
xmlns:ins2="http://comscore.com/ReportModel"
xmlns:ins3="http://comscore.com/FetchMedia"
xmlns:ins4="http://comscore.com/Media/Response">
<env:Body>
<tns:DiscoverParameterValues xmlns="http://comscore.com/">
<tns:parameterId>loc</tns:parameterId>
<tns:query>
<tns:Parameter KeyId="geo" Value="124"/>
</tns:query>
</tns:DiscoverParameterValues>
</env:Body>
</env:Envelope>
So everything works EXCEPT - I cannot set "attributes" on the "query" tag.
I would like to set this as an attribute on the query: "xmlns=http://comscore.com/ReportQuery"
How do I do that?
Question: Does it work?
Savon uses the namespace qualifiert in a different way than your first example.
In the following snippet the tags within have an implicit namespace as specified in the attribute xmlns.
<DiscoverParameterValues xmlns="http://comscore.com/">
<parameterId>loc</parameterId>
<query xmlns="http://comscore.com/ReportQuery">
<Parameter KeyId="geo" Value="124" />
</query>
</DiscoverParameterValues>
Savon uses a different syntax. It defines all needed namespace in the envelope and uses the prefixes per tag later. Different syntax for the same expression.
SoapUI uses often the former variant, Savon the latter.
ParameterIdcomes in both cases from the namespace http://comscore.com/.
UPDATE response:
You can go different ways:
Is usually cheat: I just write fully qualified keys, eg.
...
:query => { "Parameter" => "", :attributes! =>
{ "Parameter" =>
{ "ins1:KeyId" => "geo", "ins1:Value" => "124" }}},
...
If you absolutely want to put the key as attribute on "query" then you can define it like this:
response = client.call(:discover_parameter_values,
message:{:parameterId=>"loc",
:query =>{ "Parameter"=> "", :attributes! =>
{ "Parameter" =>
{ "KeyId" => "geo" , "Value"=>"124" }}},
:attributes! => {'tns:query' =>
{ "xmlns" => "http://comscore.com/ReportQuery" }
},
:attributes => {"xmlns" => "http://comscore.com/" })