Class: VagrantPlugins::Skytap::API::Client
- Defined in:
- lib/vagrant-skytap/api/client.rb
Constant Summary collapse
- MAX_RATE_LIMIT_RETRIES =
3
- DEFAULT_RETRY_AFTER_SECONDS =
10
Instance Attribute Summary collapse
-
#config ⇒ Object
readonly
Returns the value of attribute config.
-
#http ⇒ Object
readonly
Returns the value of attribute http.
Instance Method Summary collapse
- #delete(path, options = {}) ⇒ Object
- #error_string_from_body(resp) ⇒ Object
- #get(path, options = {}) ⇒ Object
-
#initialize(config) ⇒ Client
constructor
A new instance of Client.
- #post(path, body = nil, options = {}) ⇒ Object
- #put(path, body = nil, options = {}) ⇒ Object
-
#req(method, path, body, options = {}) ⇒ Object
path
may optionally include query and fragment parts.
Constructor Details
#initialize(config) ⇒ Client
Returns a new instance of Client.
12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/vagrant-skytap/api/client.rb', line 12 def initialize(config) @logger = Log4r::Logger.new("vagrant_skytap::api_client") @config = config uri = URI.parse(config.base_url) @http = Net::HTTP.new(uri.host, uri.port) #TODO:NLA Turn this on conditionally based on configuration value. @http.verify_mode = OpenSSL::SSL::VERIFY_NONE @http.use_ssl = uri.port == 443 || uri.scheme == 'https' end |
Instance Attribute Details
#config ⇒ Object (readonly)
Returns the value of attribute config.
7 8 9 |
# File 'lib/vagrant-skytap/api/client.rb', line 7 def config @config end |
#http ⇒ Object (readonly)
Returns the value of attribute http.
7 8 9 |
# File 'lib/vagrant-skytap/api/client.rb', line 7 def http @http end |
Instance Method Details
#delete(path, options = {}) ⇒ Object
37 38 39 |
# File 'lib/vagrant-skytap/api/client.rb', line 37 def delete(path, ={}) req('DELETE', path, nil, ) end |
#error_string_from_body(resp) ⇒ Object
96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/vagrant-skytap/api/client.rb', line 96 def error_string_from_body(resp) resp = resp.body if resp.respond_to?(:body) begin resp = JSON.load(resp) errors = resp['error'] || resp['errors'] errors = errors.join('; ') if errors.respond_to? :join rescue # treat non-JSON string as error text errors = resp end errors if errors.present? end |
#get(path, options = {}) ⇒ Object
25 26 27 |
# File 'lib/vagrant-skytap/api/client.rb', line 25 def get(path, ={}) req('GET', path, nil, ) end |
#post(path, body = nil, options = {}) ⇒ Object
29 30 31 |
# File 'lib/vagrant-skytap/api/client.rb', line 29 def post(path, body=nil, ={}) req('POST', path, body, ) end |
#put(path, body = nil, options = {}) ⇒ Object
33 34 35 |
# File 'lib/vagrant-skytap/api/client.rb', line 33 def put(path, body=nil, ={}) req('PUT', path, body, ) end |
#req(method, path, body, options = {}) ⇒ Object
path
may optionally include query and fragment parts
options
are:
query: A string or hash of the query string
extra_headers: A hash of extra headers
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/vagrant-skytap/api/client.rb', line 46 def req(method, path, body, ={}) @logger.info("REST API call: #{method} #{path} #{'body: ' + body if body.present?}") uri = URI.parse(path) if qq = [:query] if qq.is_a?(Hash) extra_query = qq.collect{|k,v| [k,v].join('=')}.join('&') else extra_query = qq.to_s end end if (query = [uri.query, extra_query].compact.join('&')).present? path = [uri.path, query].join('?') end headers = default_headers.merge([:extra_headers] || {}) tries = 0 retry_after = DEFAULT_RETRY_AFTER_SECONDS begin tries += 1 http.send_request(method, URI.encode(path), body, headers).tap do |ret| @logger.debug("REST API response: #{ret.body}") unless ret.code =~ /^2\d\d/ raise Errors::DoesNotExist, object_name: "Object '#{path}'" if ret.code == '404' error_class = case ret.code when '403' Errors::Unauthorized when '422' Errors::UnprocessableEntity when '423' Errors::ResourceBusy when '429' retry_after = ret['Retry-After'] || DEFAULT_RETRY_AFTER_SECONDS Errors::RateLimited else Errors::OperationFailed end raise error_class, err: error_string_from_body(ret) end end rescue Errors::RateLimited => ex raise if tries > MAX_RATE_LIMIT_RETRIES @logger.info("Rate limited, wil retry in #{retry_after} seconds") sleep retry_after.to_f + 0.1 retry end end |