class Zuora::Soap::Client

Constants

SESSION_TOKEN_XPATH
SOAP_API_URI

Attributes

session_token[R]

Public Class Methods

new(username, password, sandbox = true) click to toggle source

Creates a connection instance. Makes an initial SOAP request to fetch session token. Subsequent requests contain the authenticated session id in headers. @param [String] username @param [String] password @param [Boolean] sandbox @return [Zuora::SoapClient]

# File lib/zuora/soap/client.rb, line 21
def initialize(username, password, sandbox = true)
  @sandbox = sandbox
  authenticate!(username, password)
end

Public Instance Methods

call!(call_name, *args) click to toggle source

The primary interface via which users should make SOAP requests. client.call :create, object_name: :BillRun, data: {…} client.call :subscribe, account: {…}, sold_to_contact: {…} @param [Symbol] call_name - one of :create, :subscribe, :amend, :update @return [Faraday:Response] - response

# File lib/zuora/soap/client.rb, line 55
def call!(call_name, *args)
  factory = Zuora::Dispatcher.send call_name
  xml_builder = factory.new(*args).xml_builder
  request_data = envelope_for call_name, xml_builder
  request! request_data
end
request!(body) click to toggle source

Fire a request @param [Xml] body - an object responding to .xml @return [Zuora::Response]

# File lib/zuora/soap/client.rb, line 29
def request!(body)
  raise 'body must support .to_xml' unless body.respond_to? :to_xml

  raw_response = connection.post do |request|
    request.url SOAP_API_URI
    request.headers['Content-Type'] = 'text/xml'
    request.body = body.to_xml
  end

  # Handle rate limiting
  return handle_rate_limiting(body) if raw_response.status == 429

  response = Zuora::Response.new(raw_response)
  begin
    response.handle_errors(response.to_h)
  rescue StandardError => e
    return handle_lock_competition(e, body)
  end
  response
end

Private Instance Methods

api_url() click to toggle source

@return [String] - SOAP url based on @sandbox

# File lib/zuora/soap/client.rb, line 137
def api_url
  host_prefix = @sandbox ? 'sandbox' : ''
  "https://api#{host_prefix}.zuora.com/apps/services/a/91.0"
end
authenticate!(username, password) click to toggle source

Makes auth request, handles response @return [Faraday::Response] @param [String] username @param [String] password

# File lib/zuora/soap/client.rb, line 83
def authenticate!(username, password)
  auth_response = call! :login,
    username: username,
    password: password

  handle_auth_response auth_response
rescue Object => e
  raise Zuora::Errors::SoapConnectionError, e
end
connection() click to toggle source

Initializes a connection using api_url @return [Faraday::Connection]

# File lib/zuora/soap/client.rb, line 130
def connection
  Faraday.new(api_url, ssl: { verify: true }) do |conn|
    conn.adapter Faraday.default_adapter
  end
end
envelope_for(call_name, xml_builder_modifier) click to toggle source

Generate envelope for request @param [Symbol] call_name - one of the supported calls (see call) @param [Callable] xml_builder_modifier - function taking a builder @return [Nokogiri::XML::Builder]

# File lib/zuora/soap/client.rb, line 97
def envelope_for(call_name, xml_builder_modifier)
  if call_name == :login
    Zuora::Utils::Envelope.xml(nil, xml_builder_modifier)
  else
    Zuora::Utils::Envelope.authenticated_xml(@session_token) do |b|
      xml_builder_modifier.call b
    end
  end
end
extract_session_token(response) click to toggle source

Extracts session token from response and sets instance variable for use in subsequent requests @param [Faraday::Response] response - response to auth request

# File lib/zuora/soap/client.rb, line 124
def extract_session_token(response)
  response.to_h.envelope.body.login_response.result.session
end
handle_auth_response(response) click to toggle source

Handle auth response, setting session @params [Faraday::Response] @return [Faraday::Response] @throw [Zuora::Errors::InvalidCredentials]

# File lib/zuora/soap/client.rb, line 111
def handle_auth_response(response)
  if response.raw.status == 200
    @session_token = extract_session_token response
  else
    message = 'Unable to connect with provided credentials'
    raise Zuora::Errors::InvalidCredentials, message
  end
  response
end
handle_lock_competition(error, body) click to toggle source
# File lib/zuora/soap/client.rb, line 71
def handle_lock_competition(error, body)
  if error.message =~ /(Operation failed due to a lock competition)/i
    handle_rate_limiting(body)
  else
    raise error
  end
end
handle_rate_limiting(body) click to toggle source

@param [Xml] body @return [Zuora::Response]

# File lib/zuora/soap/client.rb, line 66
def handle_rate_limiting(body)
  sleep(Zuora::RETRY_WAITING_PERIOD)
  request!(body)
end