Class: Armrest::Api::Base

Inherits:
Object
  • Object
show all
Extended by:
Memoist
Includes:
Mods
Defined in:
lib/armrest/api/base.rb

Direct Known Subclasses

Auth::Base, Auth::CLI, Main

Constant Summary collapse

HTTP_WRITE_METHODS =
%w[post patch put delete]
HTTP_READ_METHODS =
%w[get head]
MAX_RETRIES =
(ENV['ARMREST_MAX_RETRIES'] || 3).to_i

Instance Method Summary collapse

Methods included from Settings

#client_id, #client_secret, #endpoint, #group, #location, #resource, #subscription_id, #tenant_id

Methods included from HandleResponse

#load_json, #ok?

Methods included from Logging

#default_logger, #logger, #logger=

Constructor Details

#initialize(options = {}) ⇒ Base

Returns a new instance of Base.



9
10
11
# File 'lib/armrest/api/base.rb', line 9

def initialize(options={})
  @options = options
end

Instance Method Details

#append_api_version(path) ⇒ Object



89
90
91
92
# File 'lib/armrest/api/base.rb', line 89

def append_api_version(path)
  separator = path.include?('?') ? '&' : '?'
  path + separator + "api-version=#{api_version}"
end

#build_request(klass, path, data = {}) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/armrest/api/base.rb', line 65

def build_request(klass, path, data={})
  req = klass.new(path) # url includes query string and uri.path does not, must used url
  set_headers!(req)

  logger.debug "build_request data #{data}"

  # Note: Need to use to_s for case statement to work right
  case klass.to_s.split('::').last.underscore
  when "delete", "patch",  "post",  "put"
    text = JSON.dump(data)
    req.body = text
    req.content_length = text.bytesize
  when "get"
    req.set_form_data(data) if data && !data.empty?
  end

  req
end

#headersObject

interface method



101
102
103
# File 'lib/armrest/api/base.rb', line 101

def headers
  {}
end

#http(url) ⇒ Object



105
106
107
108
109
110
111
112
# File 'lib/armrest/api/base.rb', line 105

def http(url)
  uri = URI(url)
  http = Net::HTTP.new(uri.host, uri.port)
  http.open_timeout = @open_timeout || 30
  http.read_timeout = @read_timeout || 30
  http.use_ssl = true if uri.scheme == 'https'
  http
end

#request(klass, path, data = {}) ⇒ Object

Always translate raw json response to ruby Hash



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/armrest/api/base.rb', line 27

def request(klass, path, data={})
  path = standarize_path(path)
  url = url(path)
  req = build_request(klass, path, data)
  http = http(url)
  meth = klass.to_s.split('::').last.underscore
  logger.debug "#{meth.upcase} #{url}".color(:yellow)
  # logger.debug "req['Authorization'] #{req['Authorization']}"

  resp = send_request(http, req)

  logger.debug "resp #{resp}"
  logger.debug "resp.code #{resp.code}"
  logger.debug "resp.body #{resp.body}"

  if HTTP_WRITE_METHODS.include?(meth) && resp.code !~ /^20/
    raise Armrest::Error.new(resp)
  end

  resp
end

#send_request(http, req) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/armrest/api/base.rb', line 50

def send_request(http, req)
  retries = 0
  resp = http.request(req) # send request
  retry_codes = [/^5/, "429"]
  retry_code_detected = retry_codes.detect { |code| resp.code.match(code) }
  if retry_code_detected && retries < MAX_RETRIES
    retries += 1
    delay = 2 ** retries
    logger.debug "retries #{retries} sleep #{delay} and will retry."
    sleep delay
    resp = http.request(req) # send request
  end
  resp
end

#set_headers!(req) ⇒ Object



94
95
96
97
98
# File 'lib/armrest/api/base.rb', line 94

def set_headers!(req)
  headers.each do |k,v|
    req[k.to_s] = v.to_s
  end
end

#standarize_path(path) ⇒ Object



84
85
86
87
# File 'lib/armrest/api/base.rb', line 84

def standarize_path(path)
  path = "/#{path}" unless path.starts_with?('/')
  path = append_api_version(path)
end

#url(path) ⇒ Object

interface method. API endpoint does not include the /. IE: login.microsoftonline.com



122
123
124
# File 'lib/armrest/api/base.rb', line 122

def url(path)
  "#{endpoint}#{path}"
end

#with_open_timeout(value) ⇒ Object



115
116
117
118
119
# File 'lib/armrest/api/base.rb', line 115

def with_open_timeout(value)
  saved, @open_timeout = @open_timeout, value
  yield
  @open_timeout = saved
end