Вызов API с клиентом Savon SOAP приводит к несоответствию ContractFilter при ошибке EndpointDispatcher - PullRequest
4 голосов
/ 26 января 2012

Я столкнулся с проблемой, когда Savon Ruby Gem генерирует вызов API SOAP, который завершается неудачно, однако, когда я копирую и вставляю точное то же самое XML-сообщение в SOAP-UI, это успешно завершается.

Я отправляю это сообщение:

<?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>

Для этого API (Конфигурация удаленной веб-камеры): https://oapqa.onasset.com/Services/SecureOriginCommand.svc?wsdl

Но с этим сообщением не получается:

 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, e.g. Message, Transport, None)</faultstring>
 </s:Fault>
</s:Body>

Моей первой мыслью было, что я должен был сделать опечатку в названии действия.Но нет, когда я пытаюсь точно такое же сообщение в SOAP-UI, я получаю следующий успех:

  <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>

Это приводит меня к мысли, что проблема связана не с форматом моего сообщения XML, а скак я настраиваю свой клиент.Вот фактический код:

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

Я говорил с разработчиком, который поддерживает API, к которому я пытаюсь получить доступ.Я думал, что его ответ может дать подсказку:

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.

Является ли эта проблема известной проблемой с конечными точками Savon и Microsoft SOAP или HTTPS?Или с этим вопросом сталкиваюсь только я?

1 Ответ

5 голосов
/ 26 января 2012

Отладил его и заметил, что Savon, к сожалению, не отправляет правильный HTTP-заголовок SOAPAction. К вашему сведению: после отправки запроса SOAP через soapUI, вы можете нажать на вкладку «RAW» (вертикально выровнен в окне запроса), чтобы продолжить расследование.

Вот полный пример:

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

Надеюсь, у вас все получится!

...