0

1.1.0 から Savon v2.0.2 にアップグレードしたところ、アプリが壊れてしまいました。エラー コールバック (Savon::SOAP::Fault から Savon::SOAPFault、Savon::HTTP::Error から Savon::HTTPError など) の変更を考慮して、コードに必要な調整を行い、# call と #request メソッド。スタック レベルが深すぎるため、エラーの追跡に問題がありますエラー。ulimit -s を 40000 まで増やしましたが、何の助けにもなりません。v2より前のコードは問題なく動作するため、コードのループであるとは思いません。Savon サイトのどこにでも、または Google 検索の結果として示されている例はどれも、API を提供するアプライアンスに対して行う必要がある (そして行った) XML 呼び出しに近いものではありません。これは、作成する必要があるクライアント構成、XML 構造体、ビルダー、および XML 要求に対して私が持っているものです。アップグレード前の作業バージョンのコードも含めます。どんな方向性でも大歓迎です。セキュリティのために、IP、ドメインなどを隠しています。追加情報が必要な場合はお知らせください。

ありがとうございました!

td

両方のバージョンに共通:

@api = api.capitalize
service_api_host = '10.10.10.1'
url = "https://#{service_api_host}:8443/#{api}/#{api}?wsdl"
@uname = 'username'
@pwd   = 'password'
@xml1   = "xmlns:soapenv"
@xml2   = "xmlns:ws"
@xmlns1 = "http://schemas.xmlsoap.org/soap/envelope/"
@xmlns2 = "http://ws.#{@api.downcase}.myappliances_domain.com"

典型的な XML リクエスト:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.reportingservices.myappliances_domain.com">
  <soapenv:Header xmlns:svsec="http://services.myappliances_domain.com">
    <svsec:username>username</svsec:username>
    <svsec:password>password</svsec:password>
  </soapenv:Header>
  <soapenv:Body>
    <ws:RunTimeSeriesReportRequest>
      <ReportDefinition>MyReportDefinition</ReportDefinition>
      <CsvAttachmentFormat>
        <Compression>None</Compression>
        <Encoding>UTF-8</Encoding>
        <Headers>true</Headers>
      </CsvAttachmentFormat>
      <TimeSeriesReportQuery>
        <QueryFields>
          <QueryField>PeriodStart</QueryField>
          <QueryField>PeriodEnd</QueryField>
          <QueryField>Subscriber.Name</QueryField>
          <QueryField>TotalReceivedBytes</QueryField>
          <QueryField>TotalTransmittedBytes</QueryField>
          <QueryField>TotalBytes</QueryField>
        </QueryFields>
        <QueryFilters>
          <QueryFilter>
            <QueryField>Subscriber.Name</QueryField>
            <Criteria>Equal</Criteria>
            <Value>078DF7</Value>
          </QueryFilter>
        </QueryFilters>
        <MaxRows>0</MaxRows>
        <QueryLocalDataHomeOnly>false</QueryLocalDataHomeOnly>
        <TimeSeries>
          <Start>2012-12-19T06:00:00-07:00</Start>
          <End>2012-12-20T00:00:00-07:00</End>
          <TimeZone>America/Phoenix</TimeZone>
          <Interval>
            <Unit>Hours</Unit>
            <Value>18</Value>
          </Interval>
        </TimeSeries>
      </TimeSeriesReportQuery>
    </ws:RunTimeSeriesReportRequest>
  </soapenv:Body>
</soapenv:Envelope>

完全を期すために:(ユニークなリクエストを作成する多くのビルダーの1つ)

xml = Builder::XmlMarkup.new( :indent=>2 )
xml.soapenv:Envelope, :"#{@xml1}"=>"#{@xmlns1}", :"#{@xml2}"=>"#{@xmlns2}" do
  xml.tag!( 'soapenv:Header', :'xmlns:svsec' => 'http://services.myappliances_domain.com' ) do
    xml.tag!( 'svsec:username', @uname )
    xml.tag!( 'svsec:password', @pwd )
  end
  xml.tag!( 'soapenv:Body' ) do
    xml.tag!( "ws:#{request}" ) do
      xml.ReportDefinition('MyReportDefinition')
      xml.CsvAttachmentFormat do
        xml.Compression('None')
        xml.Encoding('UTF-8')
        xml.Headers('true')
      end
      xml.TimeSeriesReportQuery do
        xml.QueryFields do
          xml.QueryField('PeriodStart')
          xml.QueryField('PeriodEnd')
          xml.QueryField('Subscriber.Name')
          xml.QueryField('TotalReceivedBytes')
          xml.QueryField('TotalTransmittedBytes')
          xml.QueryField('TotalBytes')
        end
        xml.QueryFilters do
          xml.QueryFilter do
            xml.QueryField('Subscriber.Name')
            xml.Criteria('Equal')
            xml.Value(sub)
          end
        end
        xml.MaxRows(0)
        xml.QueryLocalDataHomeOnly('false')
        xml.TimeSeries do
          xml.Start("#{start_date}")
          xml.End("#{end_date}")
          xml.TimeZone('America/Phoenix')
          xml.Interval do
            xml.Unit('Hours')
            xml.Value('18')
          end
        end
      end
    end
  end
end

アップグレード前:

クライアント定義

  @client = Savon::Client.new do |wsdl, http|
    wsdl.document = url
    http.auth.ssl.verify_mode = :none
    http.read_timeout = 120
  end

通話をリクエスト

  @response = @client.request "#{params[:reqMethod]}" do
    soap.xml = "#{params[:xml]}"      
  end

アップグレード後:

クライアント定義

@client = Savon.client(wsdl: url,
                       encoding: "UTF-8",
                       soap_version: 2,
                       ssl_verify_mode: :none,
                       open_timeout: 5,
                       read_timeout: 120)

通話をリクエスト

response = @client.call(:"#{params[:reqMethod]}", xml: params[:xml])

アップデート

Builder の結果を返す典型的なメソッドを次に示します。オブジェクトではなく文字列です。

Rails コンソールから:

ruby-1.9.3-p0 :020 >     @uname = 'username'
 => "username" 
ruby-1.9.3-p0 :021 >     @pwd   = 'password'
 => "password" 
ruby-1.9.3-p0 :022 > api = 'SubscriberServices'
 => "SubscriberServices" 
ruby-1.9.3-p0 :023 >     @api = api.capitalize
 => "Subscriberservices" 
ruby-1.9.3-p0 :024 >     @xml1   = "xmlns:soapenv"
 => "xmlns:soapenv" 
ruby-1.9.3-p0 :025 >     @xml2   = "xmlns:ws"
 => "xmlns:ws" 
ruby-1.9.3-p0 :026 >     @xmlns1 = "http://schemas.xmlsoap.org/soap/envelope/"
 => "http://schemas.xmlsoap.org/soap/envelope/" 
ruby-1.9.3-p0 :027 >     @xmlns2 = "http://ws.#{@api.downcase}.myappliance_domain.com"
 => "http://ws.subscriberservices.myappliance_domain.com" 
ruby-1.9.3-p0 :028 >   def getSubAttributes(subscriber)
ruby-1.9.3-p0 :029?>       request = 'LookupSubscriberRequest'
ruby-1.9.3-p0 :030?>       
ruby-1.9.3-p0 :031 >         xml = Builder::XmlMarkup.new( :indent=>2 )
ruby-1.9.3-p0 :032?>       xml.soapenv:Envelope, :"#{@xml1}"=>"#{@xmlns1}", :"#{@xml2}"=>"#{@xmlns2}" do
ruby-1.9.3-p0 :033 >             xml.tag!( 'soapenv:Header', :'xmlns:svsec' => 'http://services.myappliance_domain.com' ) do
ruby-1.9.3-p0 :034 >                 xml.tag!( 'svsec:username', @uname )
ruby-1.9.3-p0 :035?>               xml.tag!( 'svsec:password', @pwd )
ruby-1.9.3-p0 :036?>             end
ruby-1.9.3-p0 :037?>           xml.tag!( 'soapenv:Body' ) do     
ruby-1.9.3-p0 :038 >                 xml.tag!( "ws:#{request}" ) do
ruby-1.9.3-p0 :039 >                     xml.SubscriberKey() do
ruby-1.9.3-p0 :040 >                         xml.SubscriberRealmKey() do
ruby-1.9.3-p0 :041 >                             xml.Name('DEFAULT')
ruby-1.9.3-p0 :042?>                         end
ruby-1.9.3-p0 :043?>                       xml.Name(subscriber)
ruby-1.9.3-p0 :044?>                     end
ruby-1.9.3-p0 :045?>                   xml.ResponseGroups() do
ruby-1.9.3-p0 :046 >                         xml.ResponseGroup('Subscriber.Attributes')
ruby-1.9.3-p0 :047?>                       xml.ResponseGroup('Subscriber.CurrentIpAssignments')
ruby-1.9.3-p0 :048?>                     end
ruby-1.9.3-p0 :049?>                 end
ruby-1.9.3-p0 :050?>             end
ruby-1.9.3-p0 :051?>         end
ruby-1.9.3-p0 :052?>   end
 => nil 
ruby-1.9.3-p0 :053 > x = getSubAttributes('3C754A70BDE3')
 => "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ws=\"http://ws.subscriberservices.myappliance_domain.com\">\n  <soapenv:Header xmlns:svsec=\"http://services.myappliance_domain.com\">\n    <svsec:username>username</svsec:username>\n    <svsec:password>password</svsec:password>\n  </soapenv:Header>\n  <soapenv:Body>\n    <ws:LookupSubscriberRequest>\n      <SubscriberKey>\n        <SubscriberRealmKey>\n          <Name>DEFAULT</Name>\n        </SubscriberRealmKey>\n        <Name>3C754A70BDE3</Name>\n      </SubscriberKey>\n      <ResponseGroups>\n        <ResponseGroup>Subscriber.Attributes</ResponseGroup>\n        <ResponseGroup>Subscriber.CurrentIpAssignments</ResponseGroup>\n      </ResponseGroups>\n    </ws:LookupSubscriberRequest>\n  </soapenv:Body>\n</soapenv:Envelope>\n" 
ruby-1.9.3-p0 :054 > x.class
 => String 
ruby-1.9.3-p0 :055 > x.target!
NoMethodError: undefined method `target!' for #<String:0x0000000497a348>
    from (irb):55
    from /usr/local/rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.9/lib/rails/commands/console.rb:47:in `start'
    from /usr/local/rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.9/lib/rails/commands/console.rb:8:in `start'
    from /usr/local/rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.9/lib/rails/commands.rb:41:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'
ruby-1.9.3-p0 :056 >

更新 2

xml Builder オブジェクトを明示的に返さない場合は、文字列を取得します。

api = 'SubscriberServices'
@api = api.capitalize
@uname = 'username'
@pwd   = 'password'

@xml1   = "xmlns:soapenv"
@xml2   = "xmlns:ws"
@xmlns1 = "http://schemas.xmlsoap.org/soap/envelope/"
@xmlns2 = "http://ws.#{@api.downcase}.myappliance_domain.com"

def getSubAttributes(subscriber)
  request = 'LookupSubscriberRequest'

  xml = Builder::XmlMarkup.new( :indent=>2 )
  xml.soapenv:Envelope, :"#{@xml1}"=>"#{@xmlns1}", :"#{@xml2}"=>"#{@xmlns2}" do
    xml.tag!( 'soapenv:Header', :'xmlns:svsec' => 'http://services.myappliance_domain.com' ) do
      xml.tag!( 'svsec:username', @uname )
      xml.tag!( 'svsec:password', @pwd )
    end
    xml.tag!( 'soapenv:Body' ) do     
      xml.tag!( "ws:#{request}" ) do
        xml.SubscriberKey() do
          xml.SubscriberRealmKey() do
            xml.Name('DEFAULT')
          end
          xml.Name(subscriber)
        end
        xml.ResponseGroups() do
          xml.ResponseGroup('Subscriber.Attributes')
          xml.ResponseGroup('Subscriber.CurrentIpAssignments')
        end
      end
    end
  end
  return xml
end

テスト中...

ruby-1.9.3-p0 :294 >   api = 'SubscriberServices'
 => "SubscriberServices" 
ruby-1.9.3-p0 :295 > @api = api.capitalize
 => "Subscriberservices" 
ruby-1.9.3-p0 :296 > @uname = 'username'
 => "username" 
ruby-1.9.3-p0 :297 > @pwd   = 'password'
 => "password" 
ruby-1.9.3-p0 :298 > 
ruby-1.9.3-p0 :299 >   @xml1   = "xmlns:soapenv"
 => "xmlns:soapenv" 
ruby-1.9.3-p0 :300 > @xml2   = "xmlns:ws"
 => "xmlns:ws" 
ruby-1.9.3-p0 :301 > @xmlns1 = "http://schemas.xmlsoap.org/soap/envelope/"
 => "http://schemas.xmlsoap.org/soap/envelope/" 
ruby-1.9.3-p0 :302 > @xmlns2 = "http://ws.#{@api.downcase}.myappliance_domain.com"
 => "http://ws.subscriberservices.myappliance_domain.com" 
ruby-1.9.3-p0 :303 > 
ruby-1.9.3-p0 :304 >   def getSubAttributes(subscriber)
ruby-1.9.3-p0 :305?>     request = 'LookupSubscriberRequest'
ruby-1.9.3-p0 :306?>     
ruby-1.9.3-p0 :307 >       xml = Builder::XmlMarkup.new( :indent=>2 )
ruby-1.9.3-p0 :308?>     xml.soapenv:Envelope, :"#{@xml1}"=>"#{@xmlns1}", :"#{@xml2}"=>"#{@xmlns2}" do
ruby-1.9.3-p0 :309 >           xml.tag!( 'soapenv:Header', :'xmlns:svsec' => 'http://services.myappliance_domain.com' ) do
ruby-1.9.3-p0 :310 >               xml.tag!( 'svsec:username', @uname )
ruby-1.9.3-p0 :311?>             xml.tag!( 'svsec:password', @pwd )
ruby-1.9.3-p0 :312?>           end
ruby-1.9.3-p0 :313?>         xml.tag!( 'soapenv:Body' ) do     
ruby-1.9.3-p0 :314 >               xml.tag!( "ws:#{request}" ) do
ruby-1.9.3-p0 :315 >                   xml.SubscriberKey() do
ruby-1.9.3-p0 :316 >                       xml.SubscriberRealmKey() do
ruby-1.9.3-p0 :317 >                           xml.Name('DEFAULT')
ruby-1.9.3-p0 :318?>                       end
ruby-1.9.3-p0 :319?>                     xml.Name(subscriber)
ruby-1.9.3-p0 :320?>                   end
ruby-1.9.3-p0 :321?>                 xml.ResponseGroups() do
ruby-1.9.3-p0 :322 >                       xml.ResponseGroup('Subscriber.Attributes')
ruby-1.9.3-p0 :323?>                     xml.ResponseGroup('Subscriber.CurrentIpAssignments')
ruby-1.9.3-p0 :324?>                   end
ruby-1.9.3-p0 :325?>               end
ruby-1.9.3-p0 :326?>           end
ruby-1.9.3-p0 :327?>       end
ruby-1.9.3-p0 :328?>   
Display all 540 possibilities? (y or n)
ruby-1.9.3-p0 :328?>    xml
ruby-1.9.3-p0 :329?>   end
 => nil 
ruby-1.9.3-p0 :330 > x = getSubAttributes('3C754A70BDE3')
 => <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.subscriberservices.myappliance_domain.com">
  <soapenv:Header xmlns:svsec="http://services.myappliance_domain.com">
    <svsec:username>username</svsec:username>
    <svsec:password>password</svsec:password>
  </soapenv:Header>
  <soapenv:Body>
    <ws:LookupSubscriberRequest>
      <SubscriberKey>
        <SubscriberRealmKey>
          <Name>DEFAULT</Name>
        </SubscriberRealmKey>
        <Name>3C754A70BDE3</Name>
      </SubscriberKey>
      <ResponseGroups>
        <ResponseGroup>Subscriber.Attributes</ResponseGroup>
        <ResponseGroup>Subscriber.CurrentIpAssignments</ResponseGroup>
      </ResponseGroups>
    </ws:LookupSubscriberRequest>
  </soapenv:Body>
</soapenv:Envelope>
<inspect/>

ruby-1.9.3-p0 :331 > x.class
 => "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ws=\"http://ws.subscriberservices.myappliance_domain.com\">\n  <soapenv:Header xmlns:svsec=\"http://services.myappliance_domain.com\">\n    <svsec:username>username</svsec:username>\n    <svsec:password>password</svsec:password>\n  </soapenv:Header>\n  <soapenv:Body>\n    <ws:LookupSubscriberRequest>\n      <SubscriberKey>\n        <SubscriberRealmKey>\n          <Name>DEFAULT</Name>\n        </SubscriberRealmKey>\n        <Name>3C754A70BDE3</Name>\n      </SubscriberKey>\n      <ResponseGroups>\n        <ResponseGroup>Subscriber.Attributes</ResponseGroup>\n        <ResponseGroup>Subscriber.CurrentIpAssignments</ResponseGroup>\n      </ResponseGroups>\n    </ws:LookupSubscriberRequest>\n  </soapenv:Body>\n</soapenv:Envelope>\n<inspect/>\n<class/>\n" 
ruby-1.9.3-p0 :332 > s = x.to_xml
 => "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ws=\"http://ws.subscriberservices.myappliance_domain.com\">\n  <soapenv:Header xmlns:svsec=\"http://services.myappliance_domain.com\">\n    <svsec:username>username</svsec:username>\n    <svsec:password>password</svsec:password>\n  </soapenv:Header>\n  <soapenv:Body>\n    <ws:LookupSubscriberRequest>\n      <SubscriberKey>\n        <SubscriberRealmKey>\n          <Name>DEFAULT</Name>\n        </SubscriberRealmKey>\n        <Name>3C754A70BDE3</Name>\n      </SubscriberKey>\n      <ResponseGroups>\n        <ResponseGroup>Subscriber.Attributes</ResponseGroup>\n        <ResponseGroup>Subscriber.CurrentIpAssignments</ResponseGroup>\n      </ResponseGroups>\n    </ws:LookupSubscriberRequest>\n  </soapenv:Body>\n</soapenv:Envelope>\n<inspect/>\n<class/>\n<to_xml/>\n" 
ruby-1.9.3-p0 :333 > s.class
 => String 
ruby-1.9.3-p0 :334 > 
4

1 に答える 1

0

xmlオブジェクト (からBuilder::XmlMarkup.new) との関係がよくわかりませんでしparams[:xml]たが、スタック レベルが深すぎる問題があり、 を使用してこれを修正しましたmessage: xml.target!

于 2013-01-10T02:11:59.573 に答える