class GoogleAdsSavon::Client

GoogleAdsSavon::Client

GoogleAdsSavon::Client is the main object for connecting to a SOAP service.

Attributes

instance[RW]
original_self[RW]
config[RW]

Accessor for the GoogleAdsSavon::Config.

Public Class Methods

new(wsdl_document = nil, &block) click to toggle source

Initializes the GoogleAdsSavon::Client for a SOAP service. Accepts a block which is evaluated in the context of this object to let you access the wsdl, http, and wsse methods.

Examples

# Using a remote WSDL
client = GoogleAdsSavon::Client.new("http://example.com/UserService?wsdl")

# Using a local WSDL
client = GoogleAdsSavon::Client.new File.expand_path("../wsdl/service.xml", __FILE__)

# Directly accessing a SOAP endpoint
client = GoogleAdsSavon::Client.new do
  wsdl.endpoint = "http://example.com/UserService"
  wsdl.namespace = "http://users.example.com"
end
# File lib/ads_savon/client.rb, line 33
def initialize(wsdl_document = nil, &block)
  self.config = GoogleAdsSavon.config.clone
  wsdl.document = wsdl_document if wsdl_document

  process 1, &block if block
  wsdl.request = http
end

Public Instance Methods

http() click to toggle source

Returns the HTTPI::Request.

# File lib/ads_savon/client.rb, line 50
def http
  @http ||= HTTPI::Request.new
end
request(*args, &block) click to toggle source

Executes a SOAP request for a given SOAP action. Accepts a block which is evaluated in the context of the SOAP::RequestBuilder object to let you access its soap, wsdl, http and wsse methods.

Examples

# Calls a "getUser" SOAP action with the payload of "<userId>123</userId>"
client.request(:get_user) { soap.body = { :user_id => 123 } }

# Prefixes the SOAP input tag with a given namespace: "<wsdl:GetUser>...</wsdl:GetUser>"
client.request(:wsdl, "GetUser") { soap.body = { :user_id => 123 } }

# SOAP input tag with attributes: <getUser xmlns:wsdl="http://example.com">...</getUser>"
client.request(:get_user, "xmlns:wsdl" => "http://example.com")
# File lib/ads_savon/client.rb, line 73
def request(*args, &block)
  raise ArgumentError, "GoogleAdsSavon::Client#request requires at least one argument" if args.empty?

  options = extract_options(args)

  request_builder = SOAP::RequestBuilder.new(options.delete(:input), options)
  request_builder.wsdl = wsdl
  request_builder.http = http.dup
  request_builder.wsse = wsse.dup
  request_builder.config = config.dup

  post_configuration = lambda { process(0, request_builder, &block) if block }

  response = request_builder.request(&post_configuration).response
  http.set_cookies(response.http)

  if wsse.verify_response
    WSSE::VerifySignature.new(response.http.body).verify!
  end

  response
end
wsdl() click to toggle source

Returns the Wasabi::Document.

# File lib/ads_savon/client.rb, line 45
def wsdl
  @wsdl ||= Wasabi::Document.new
end
wsse() click to toggle source

Returns the Akami::WSSE object.

# File lib/ads_savon/client.rb, line 55
def wsse
  @wsse ||= Akami.wsse
end

Private Instance Methods

evaluate(instance, &block) click to toggle source

Evaluates a given block inside instance. Stores the original block binding.

# File lib/ads_savon/client.rb, line 133
def evaluate(instance, &block)
  original_self = eval "self", block.binding

  # A proxy that attemps to make method calls on +instance+. If a NoMethodError is
  # raised, the call will be made on +original_self+.
  proxy = Object.new
  proxy.instance_eval do
    class << self
      attr_accessor :original_self, :instance
    end

    def method_missing(method, *args, &block)
      instance.send(method, *args, &block)
    rescue NoMethodError
      original_self.send(method, *args, &block)
    end
  end

  proxy.instance = instance
  proxy.original_self = original_self

  proxy.instance_eval &block
end
extract_options(args) click to toggle source

Expects an Array of args and returns a Hash containing the SOAP input, the namespace (might be nil), the SOAP action (might be nil), the SOAP body (might be nil), and a Hash of attributes for the input tag (which might be empty).

# File lib/ads_savon/client.rb, line 102
def extract_options(args)
  attributes = Hash === args.last ? args.pop : {}
  body = attributes.delete(:body)
  soap_action = attributes.delete(:soap_action)

  namespace_identifier = args.size > 1 ? args.shift.to_sym : nil
  input = args.first

  remove_blank_values(
    :namespace_identifier => namespace_identifier,
    :input                => input,
    :attributes           => attributes,
    :body                 => body,
    :soap_action          => soap_action
  )
end
method_missing(method, *args, &block) click to toggle source
# File lib/ads_savon/client.rb, line 144
def method_missing(method, *args, &block)
  instance.send(method, *args, &block)
rescue NoMethodError
  original_self.send(method, *args, &block)
end
process(offset = 0, instance = self, &block) click to toggle source

Processes a given block. Yields objects if the block expects any arguments. Otherwise evaluates the block in the context of instance.

# File lib/ads_savon/client.rb, line 121
def process(offset = 0, instance = self,  &block)
  block.arity > 0 ? yield_objects(offset, instance, &block) : evaluate(instance, &block)
end
remove_blank_values(hash) click to toggle source

Removes all blank values from a given hash.

# File lib/ads_savon/client.rb, line 158
def remove_blank_values(hash)
  hash.delete_if { |_, value| value.respond_to?(:empty?) ? value.empty? : !value }
end
yield_objects(offset, instance) { |*(map { |obj_name| send})| ... } click to toggle source

Yields a number of objects to a given block depending on how many arguments the block is expecting.

# File lib/ads_savon/client.rb, line 127
def yield_objects(offset, instance, &block)
  to_yield = [:soap, :wsdl, :http, :wsse]
  yield *(to_yield[offset, block.arity].map { |obj_name| instance.send(obj_name) })
end