class Antbird::Client
Attributes
adapter[R]
api_specs[R]
last_request[R]
open_timeout[R]
read_timeout[R]
scope[R]
url[R]
version[R]
Public Class Methods
new( scope: {}, url: "http://localhost:9200", version: nil, read_timeout: 5, open_timeout: 2, adapter: ::Faraday.default_adapter, &block)
click to toggle source
# File lib/antbird/client.rb, line 7 def initialize( scope: {}, url: "http://localhost:9200", version: nil, read_timeout: 5, open_timeout: 2, adapter: ::Faraday.default_adapter, &block) @read_timeout = read_timeout @open_timeout = open_timeout @adapter = adapter @block = block @url = url @scope = scope.transform_keys(&:to_sym) @version = version @api_specs = {} end
Public Instance Methods
connection()
click to toggle source
# File lib/antbird/client.rb, line 179 def connection @connection ||= Faraday.new(url) do |conn| @block&.call(conn) conn.request :json conn.response :json, content_type: /\bjson$/ conn.options[:timeout] = read_timeout conn.options[:open_timeout] = open_timeout conn.adapter adapter end end
extract_body(params)
click to toggle source
# File lib/antbird/client.rb, line 156 def extract_body(params) body = params.delete :body return if body.nil? body = case body when String body when Array if body.all? { |b| b.is_a?(Hash) } body.map { |b| JSON.dump(b) }.join("\n") + "\n" else body << nil unless body.last.nil? body.join "\n" end else JSON.dump(body) end # Prevent excon from changing the encoding (see https://github.com/github/elastomer-client/issues/138) body.freeze end
extract_method(params)
click to toggle source
# File lib/antbird/client.rb, line 142 def extract_method(params) params.delete(:method)&.to_sym end
extract_scopes(params)
click to toggle source
# File lib/antbird/client.rb, line 146 def extract_scopes(params) scopes = {} [:index, :type, :id].each do |s| scope = params.delete(s) next unless scope scopes[s] = scope end scopes end
request(api_name, api_spec, params)
click to toggle source
# File lib/antbird/client.rb, line 41 def request(api_name, api_spec, params) validate_params(api_spec, params) body = extract_body(params) scopes = extract_scopes(params) forced_method = extract_method(params) # Greedy match api_path = nil api_path_template = nil path_methods = nil sort_url_paths(api_spec['url']['paths']).each do |path| if path.is_a?(Hash) path_methods = path['methods'] path = path['path'] end embeded = path.gsub(/{([a-z_\-}]+)}/) do |match| scopes[$1.to_sym] || @scope[$1.to_sym] || match end unless embeded.include?('{') api_path_template = path api_path = embeded break end end unless api_path raise "API path not found: paths: #{api_spec['url']['paths']}, scope: #{@scope}" end methods = (path_methods || api_spec['methods']).map { |m| m.downcase.to_sym } method = if forced_method forced_method elsif methods.include?(:put) :put elsif methods.include?(:post) :post else methods.first end read_timeout = params.delete(:read_timeout) params.reject! { |_, v| v.nil? } @last_request = { method: method, forced_method: forced_method, api_path: api_path, api_path_template: api_path_template, params: params } response = case method when :head connection.head(api_path) do |req| req.params = params unless params.empty? req.options[:timeout] = read_timeout if read_timeout end when :get connection.get(api_path) do |req| req.params = params unless params.empty? req.body = body if body req.options[:timeout] = read_timeout if read_timeout end when :put connection.put(api_path, body) do |req| req.params = params unless params.empty? req.options[:timeout] = read_timeout if read_timeout end when :post connection.post(api_path, body) do |req| req.params = params unless params.empty? req.options[:timeout] = read_timeout if read_timeout end when :delete connection.delete(api_path) do |req| req.params = params unless params.empty? req.body = body if body req.options[:timeout] = read_timeout if read_timeout end else raise ArgumentError, "Unknown HTTP request method: #{method.inspect}" end if method == :head case response.status when 200 return true when 404 return false end end handle_errors!(response) response.body end
scoped(new_scope = {})
click to toggle source
# File lib/antbird/client.rb, line 31 def scoped(new_scope = {}) Client.new( scope: new_scope, url: url, version: version, read_timeout: read_timeout, open_timeout: open_timeout ) end
Private Instance Methods
api_specs_loaded?()
click to toggle source
# File lib/antbird/client.rb, line 239 def api_specs_loaded? !!@api_specs_loaded end
ensure_api_spec_loaded()
click to toggle source
# File lib/antbird/client.rb, line 228 def ensure_api_spec_loaded return if api_specs_loaded? @version ||= fetch_version class_version = @version.split('.')[0, 2].join('_') require "antbird/rest_api/rest_api_v#{class_version}" extend Antbird::RestApi.const_get "RestApiV#{class_version}" @api_specs_loaded = true end
fetch_version()
click to toggle source
# File lib/antbird/client.rb, line 224 def fetch_version connection.get('/').body.dig('version', 'number') end
handle_errors!(response)
click to toggle source
# File lib/antbird/client.rb, line 207 def handle_errors!(response) if response.status >= 500 raise ServerError, response elsif response.body.is_a?(Hash) && response.body.key?("error") raise RequestError, response end end
method_missing(name, *args, &block)
click to toggle source
Calls superclass method
# File lib/antbird/client.rb, line 243 def method_missing(name, *args, &block) return super if api_specs_loaded? ensure_api_spec_loaded return super unless respond_to?(name) __send__(name, *args, &block) end
sort_url_paths(url_paths)
click to toggle source
NOTE: stable sort
# File lib/antbird/client.rb, line 196 def sort_url_paths(url_paths) i = 0 url_paths.sort_by do |path| if path.is_a?(Hash) [-path['path'].count('{'), (path['deprecated'] ? 1 : 0), i += 1] else [-path.count('{'), i += 1] end end end
validate_params(api_spec, params)
click to toggle source
# File lib/antbird/client.rb, line 215 def validate_params(api_spec, params) # TODO case: required parameter is missing # TODO case: invalid parameter name # TODO case: invalid parameter format if api_spec.dig('body', 'required') && !params.key?(:body) raise ArgumentError, 'Body is missing' end end