API call with Savon SOAP client results if ContractFilter does not match with EndpointDispatcher error

I have a problem where the Savon Ruby Gem generates a SOAP API call that fails, however when I copy and paste the same XML message into the SOAP-UI, it succeeds.

I am sending this message:

<?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tem="http://tempuri.org/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:vis="http://schemas.datacontract.org/2004/07/Vision.SecureOriginCommand.ServiceContracts"> <soapenv:Body> <tem:CameraConfiguration> <tem:request> <vis:ClientToken>5555</vis:ClientToken> <vis:DeviceID>26219</vis:DeviceID> <vis:Enabled>1</vis:Enabled> <vis:Interval>60</vis:Interval> </tem:request> </tem:CameraConfiguration> </soapenv:Body> 

To this API (remote webcam configuration): https://oapqa.onasset.com/Services/SecureOriginCommand.svc?wsdl

But this message fails:

  SOAP response (status 500): <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Body> <s:Fault><faultcode xmlns:a="http://schemas.microsoft.com/ws/2005/05/addressing/none">a:ActionNotSupported</faultcode> <faultstring xml:lang="en-US">The message with Action 'oapSetSentryReportingIntervalRequest' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, eg Message, Transport, None)</faultstring> </s:Fault> </s:Body> 

My first thought was that I had to make a typo in the name of the action. But no, when I try the exact same message in SOAP-UI, I get the following success:

  <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Body> <CameraConfigurationResponse xmlns="http://tempuri.org/"> <CameraConfigurationResult xmlns:a="http://schemas.datacontract.org/2004/07/Vision.SecureOriginCommand.ServiceContracts" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <a:Error/> <a:Result>true</a:Result> </CameraConfigurationResult> </CameraConfigurationResponse> </s:Body> </s:Envelope> 

This makes me think that the problem is not caused by the format of my xml message, but with the way I configure my client. Here is the actual code:

 Savon.configure do |config| config.log = :debug config.env_namespace = :soapenv config.raise_errors = false end # TODO Enable ssl certficate verification client = Savon::Client.new do wsdl.document = TARGET_SO_WSDL http.auth.ssl.verify_mode = :none end resp = client.request 'tem', 'CameraConfiguration' do soap.namespaces['xmlns:vis'] = 'http://schemas.datacontract.org/2004/07/Vision.SecureOriginCommand.ServiceContracts' soap.namespaces['xmlns:tem'] = 'http://tempuri.org/' soap.body = { 'tem:request' => { 'vis:ClientToken' => ON_ASSET_API_KEY, 'vis:DeviceID' => webcam.gps_device.device_id, 'vis:Enabled' => 1, 'vis:Interval' => webcam.report_interval } } end 

I spoke with a developer who supports the API I'm trying to access. I thought his answer might give a clue:

 Binding on the RemoteSentryService was set to mexHttpBinding instead of mexHttpsBinding. I don't think this should give you a fault exception, because its working on .NET simulator client I have. And this endpoint is only used to generate the wsdl (MetaExchange Binding). But, given you are using a different client, I would still give it a shot. I also regenerated the proxy from wsdl and updated my sample simulator and it looks good. 

Is this a known issue with Savon and Microsoft SOAP endpoints or HTTPS? Or is it a problem that I am just facing?

+4
source share
1 answer

Debugged it and noticed that Savon, unfortunately, was not sending the correct HTTP SOAPAction header. FYI: after sending a SOAP request through soapUI, you can click the "RAW" tab (vertically aligned to the request window) to continue exploring.

Here is a complete example:

 client = Savon::Client.new do wsdl.document = TARGET_SO_WSDL http.auth.ssl.verify_mode = :none end resp = client.request 'tem', 'CameraConfiguration' do # Notice, that the SOAPAction needs to the wrapped in double quotes: http.headers['SOAPAction'] = %("http://tempuri.org/ISecureOriginCommand/CameraConfiguration") soap.namespaces['xmlns:vis'] = 'http://schemas.datacontract.org/2004/07/Vision.SecureOriginCommand.ServiceContracts' soap.body = { 'tem:request' => { 'vis:ClientToken' => 5555, 'vis:DeviceID' => 26219, 'vis:Enabled' => 1, 'vis:Interval' => 60 } } end 

Hope this works for you!

+5
source

Source: https://habr.com/ru/post/1393068/


All Articles