class SoapyCake::Client

Constants

HEADERS

Attributes

api_key[R]
domain[R]
opts[R]
retry_count[R]
time_converter[R]
write_enabled[R]

Public Class Methods

new(opts = {}) click to toggle source
# File lib/soapy_cake/client.rb, line 11
def initialize(opts = {})
  @opts = opts
  @domain = fetch_opt(:domain) || raise(Error, 'Cake domain missing')
  @api_key = fetch_opt(:api_key) || raise(Error, 'Cake API key missing')
  @retry_count = fetch_opt(:retry_count, 4)
  @write_enabled = ['yes', true].include?(fetch_opt(:write_enabled))
  @time_converter = TimeConverter.new(fetch_opt(:time_zone))
end

Public Instance Methods

read_only?() click to toggle source
# File lib/soapy_cake/client.rb, line 24
def read_only?
  !write_enabled
end
run(request) click to toggle source
# File lib/soapy_cake/client.rb, line 28
def run(request)
  check_write_enabled!(request)
  request.api_key = api_key
  request.time_converter = time_converter

  with_retries do
    response = Response.new(response_body(request), request.short_response?, time_converter)
    xml_response? ? response.to_xml : response.to_enum
  rescue RequestFailed => e
    raise RequestFailed.new(
      e.message,
      request_path: request.path,
      request_body: request.xml,
      response_body: e.response_body || response.body
    )
  end
end
xml_response?() click to toggle source
# File lib/soapy_cake/client.rb, line 20
def xml_response?
  opts[:xml_response] == true
end

Private Instance Methods

check_write_enabled!(request) click to toggle source
# File lib/soapy_cake/client.rb, line 56
def check_write_enabled!(request)
  return if request.read_only? || write_enabled

  raise Error, 'Writes not enabled (pass write_enabled: true or set CAKE_WRITE_ENABLED=yes)'
end
fetch_opt(key, fallback = nil) click to toggle source
# File lib/soapy_cake/client.rb, line 52
def fetch_opt(key, fallback = nil)
  opts.fetch(key, ENV.fetch("CAKE_#{key.to_s.upcase}", fallback))
end
http_request(request) click to toggle source
# File lib/soapy_cake/client.rb, line 83
def http_request(request)
  http_req = Net::HTTP::Post.new(request.path, HEADERS)
  http_req.body = request.xml
  http_req
end
http_response(request) click to toggle source
# File lib/soapy_cake/client.rb, line 71
def http_response(request)
  response = nil
  logger.tagged('soapy_cake', unique_id) do
    log_request(request)
    response = perform_http_request(http_request(request))
    log_response(response)
  end

  raise_if_unsuccessful(response)
  response.body
end
log_request(request) click to toggle source
# File lib/soapy_cake/client.rb, line 93
def log_request(request)
  logger.tagged('request') do
    logger.info(
      request
        .xml
        .gsub(/>[\n\s]+</, '><')
        .sub(request.api_key, '[REDACTED]')
    )
  end
end
log_response(response) click to toggle source
# File lib/soapy_cake/client.rb, line 104
def log_response(response)
  logger.tagged('response', response.code) do
    logger.info(response.body)
  end
end
logger() click to toggle source
# File lib/soapy_cake/client.rb, line 110
def logger
  @logger ||= ActiveSupport::TaggedLogging.new(
    opts[:logger] || (defined?(::Rails) && ::Rails.logger) || Logger.new('/dev/null')
  )
end
perform_http_request(http_request) click to toggle source
# File lib/soapy_cake/client.rb, line 116
def perform_http_request(http_request)
  t0 = Time.now
  response = Net::HTTP.start(
    domain,
    use_ssl: true,
    open_timeout: NET_TIMEOUT,
    read_timeout: NET_TIMEOUT
  ) do |http|
    http.request(http_request)
  end
  logger.info("took: #{(Time.now - t0).round(2)} s")
  response
end
raise_if_unsuccessful(response) click to toggle source
# File lib/soapy_cake/client.rb, line 130
def raise_if_unsuccessful(response)
  return if response.is_a?(Net::HTTPSuccess)

  raise RequestFailed.new(
    "Request failed with HTTP #{response.code}",
    response_body: response.body
  )
end
response_body(request) click to toggle source
# File lib/soapy_cake/client.rb, line 67
def response_body(request)
  request.opts[:response].presence || http_response(request)
end
unique_id() click to toggle source
# File lib/soapy_cake/client.rb, line 89
def unique_id
  SecureRandom.hex(4)
end
with_retries(&block) click to toggle source
# File lib/soapy_cake/client.rb, line 62
def with_retries(&block)
  opts = { tries: retry_count + 1, on: [RateLimitError, SocketError], sleep: ->(n) { 3**n } }
  Retryable.retryable(opts, &block)
end