class Marshaling::Marshaler

Exception dispatcher based on error logged by BSI

Constants

SSL_RETRY_LIMIT

Public Class Methods

new(url, options={:verify=>true}) click to toggle source
# File lib/rbc/bsi.rb, line 48
def initialize(url, options={:verify=>true})
  @target_url = url
  @debug      = options[:debug]
  @stealth    = options[:stealth]
  @verify_ssl = options[:verify]
end

Public Instance Methods

array_to_xml(noko, array) click to toggle source
# File lib/rbc/bsi.rb, line 160
def array_to_xml(noko, array)
    noko.value{
      noko.array{
        noko.data{
          array.each do |e|
            send("#{e.class.to_s.downcase}_to_xml".to_sym, noko, e)
          end
        }
      }
    }
end
build_call(method_name, *arguments) click to toggle source

Build xml for submission

# File lib/rbc/bsi.rb, line 56
def build_call(method_name, *arguments)

  builder = Nokogiri::XML::Builder.new do |xml|
    xml.methodCall{
      xml.methodName_ method_name.gsub(/_/, '.')
      xml.params{
        arguments.each do |a|
          xml.param{
            unless a.nil?
              type = a.class.to_s.downcase
              send("#{type}_to_xml", xml, a)
            else
              raise "Nil is not an acceptable argument for method: #{method_name}#{arguments.to_s.gsub(/\]/, ')').gsub(/\[/, '(')}"
            end
          }
        end
      }
    }
  end

  # Submit xml to them
  send_xml( builder.to_xml )
end
convert_array(xml) click to toggle source
# File lib/rbc/bsi.rb, line 208
def convert_array(xml)
  array = Array.new
  unless xml['data'].nil?
    case xml['data']['value'].class.to_s.downcase
    when 'array'
      xml['data']['value'].each do |e|
        member_type  = e.keys.first
        member_value = e[member_type]
        array << send( "convert_#{member_type}".to_sym, member_value )
      end
    when 'hash'
      member_type  = xml['data']['value'].keys.first
      member_value = xml['data']['value'][member_type]
      array << send( "convert_#{member_type.gsub(/\./, '_')}".to_sym, member_value )
    end
  else
    array = nil
  end
  array
end
convert_boolean(xml) click to toggle source
# File lib/rbc/bsi.rb, line 234
def convert_boolean(xml)
  xml
end
convert_dateTime_iso8601(xml) click to toggle source
# File lib/rbc/bsi.rb, line 246
def convert_dateTime_iso8601(xml)
  DateTime.parse(xml)
end
convert_int(xml) click to toggle source

Methods to convert XML BSI sends back to us into ruby

# File lib/rbc/bsi.rb, line 230
def convert_int(xml)
  xml.to_i
end
convert_nil(xml) click to toggle source
# File lib/rbc/bsi.rb, line 238
def convert_nil(xml)
  nil
end
convert_string(xml) click to toggle source
# File lib/rbc/bsi.rb, line 242
def convert_string(xml)
  xml
end
convert_struct(xml) click to toggle source
# File lib/rbc/bsi.rb, line 197
def convert_struct(xml)
  hash = Hash.new
  xml['member'].each do |e|
    member_name  = e['name']
    member_value_type = e['value'].keys.first
    member_value = send("convert_#{ member_value_type.gsub(/\./, '_') }".to_sym, e['value'][member_value_type] )
    hash.store( member_name, member_value )
  end
  hash
end
enumerator_to_xml(noko, enumerator) click to toggle source
# File lib/rbc/bsi.rb, line 150
def enumerator_to_xml(noko, enumerator)
  # this should only be exercised when trying to pass a byte array
  # this should be sent enclosed in <base64> and encoded as such

  noko.value{
    noko.base64_ Base64.encode64(enumerator.to_a.pack('c*'))
  }

end
fixnum_to_xml(noko, int) click to toggle source
# File lib/rbc/bsi.rb, line 191
def fixnum_to_xml(noko, int)
  noko.value{
    noko.int_ int
  }
end
float_to_xml(noko, float) click to toggle source

Methods to convert ruby structures into XML in the format BSI expects

# File lib/rbc/bsi.rb, line 144
def float_to_xml(noko, float)
  noko.value{
    noko.float_ float
  }
end
generate_exception(code, message) click to toggle source
# File lib/rbc/bsi.rb, line 35
def generate_exception(code, message)
  case code
  when 9000
    # 9000 level
    case message
    when 'Logon failed: Broken pipe'
      raise Error.new(code, message, 'retry')
    end
  else
    raise Error.new(code, message)
  end
end
hash_to_xml(noko, hash) click to toggle source
# File lib/rbc/bsi.rb, line 172
def hash_to_xml(noko, hash)
    noko.value{
      noko.struct{
        hash.each do |k,v|
          noko.member{
            noko.name_ k.to_s
            send("#{v.class.to_s.downcase}_to_xml".to_sym, noko, v) unless v.nil?
          }
        end
      }
    }
end
parse(xml) click to toggle source
# File lib/rbc/bsi.rb, line 80
def parse(xml)

  # Handle Errors appropriately
  unless xml['methodResponse'].keys.include?('fault')
    type = xml['methodResponse']['params']['param']['value'].keys.pop
    # Handle happy path, no errors
    send("convert_#{type}".to_sym, xml['methodResponse']['params']['param']['value'][type])
  else
    # Error occurred, extract it, notify
    code = xml['methodResponse']['fault']['value']['struct']['member'][0]['value']['int'].to_i
    message = xml['methodResponse']['fault']['value']['struct']['member'][1]['value']['string']
    # How we should generate exceptions
    generate_exception(code, message)
  end
end
send_xml( xml) click to toggle source
# File lib/rbc/bsi.rb, line 96
def send_xml( xml)

  options = {:body => xml}
  if @target_url.match(/https/)
    options.merge!(:ssl_version=>:SSLv3)
    options.merge!(:verify => @verify_ssl)
  end
  if @debug
    puts "Sending:"
    puts xml
    puts ""
  end

  try_num = 0
  unless @stealth
    begin
      response =  HTTParty.post(@target_url, options)
    rescue OpenSSL::SSL::SSLError => e
      if try_num < SSL_RETRY_LIMIT
        try_num = try_num + 1
        puts "SSL error.  Retry #{try_num}"
        retry
      else
        raise e
      end
    rescue Error => e
      puts 'Broken Pipe error, retrying'
      retry if e.action == 'retry'
    end
  end

  unless @stealth
    if @debug
      puts "Recieved:"
      puts Nokogiri::XML(response.body, &:noblanks)
    end

    parse(response)
  end

end
string_to_xml(noko, string) click to toggle source
# File lib/rbc/bsi.rb, line 185
def string_to_xml(noko, string)
  noko.value{
    noko.string_ string
  }
end
test_send_xml(xml) click to toggle source
# File lib/rbc/bsi.rb, line 138
def test_send_xml(xml)
  puts xml
end