class ForemanApi::Base
Constants
- API_VERSION
Attributes
client[R]
config[R]
logger[R]
Public Class Methods
doc()
click to toggle source
# File lib/foreman_api/base.rb, line 81 def self.doc raise NotImplementedError end
method_doc(method)
click to toggle source
# File lib/foreman_api/base.rb, line 89 def self.method_doc(method) method_docs[method.to_s] end
new(config, options = {})
click to toggle source
# File lib/foreman_api/base.rb, line 33 def initialize(config, options = {}) config = config.dup self.logger = config.delete(:logger) headers = { :content_type => 'application/json', :accept => "application/json;version=#{API_VERSION}" } headers.merge!(config[:headers]) unless config[:headers].nil? headers.merge!(options.delete(:headers)) unless options[:headers].nil? resource_config = { :user => config[:username], :password => config[:password], :oauth => config[:oauth], :headers => headers }.merge(options) @client = RestClient::Resource.new(config[:base_url], resource_config) @config = config end
validation_hash(method)
click to toggle source
# File lib/foreman_api/base.rb, line 85 def self.validation_hash(method) validation_hashes[method.to_s] end
Private Class Methods
construct_validation_hash(method)
click to toggle source
# File lib/foreman_api/base.rb, line 198 def self.construct_validation_hash(method) if method['params'].any? { |p| p['params'] } method['params'].reduce({ }) do |h, p| h.update(p['name'] => (p['params'] ? p['params'].map { |pp| pp['name'] } : nil)) end else method['params'].map { |p| p['name'] } end end
method_docs()
click to toggle source
# File lib/foreman_api/base.rb, line 183 def self.method_docs @method_docs ||= doc['methods'].inject({ }) do |hash, method| hash[method['name']] = method hash end end
params_in_path(url)
click to toggle source
# File lib/foreman_api/base.rb, line 208 def self.params_in_path(url) url.scan(/:([^\/]*)/).map { |m| m.first } end
validation_hashes()
click to toggle source
# File lib/foreman_api/base.rb, line 190 def self.validation_hashes @validation_hashes ||= method_docs.inject({ }) do |hash, pair| name, method_doc = pair hash[name] = construct_validation_hash method_doc hash end end
Public Instance Methods
http_call(http_method, path, params = { }, headers = { })
click to toggle source
# File lib/foreman_api/base.rb, line 64 def http_call(http_method, path, params = { }, headers = { }) headers ||= { } args = [http_method] if %w[post put].include?(http_method.to_s) args << params.to_json else headers[:params] = params if params end logger.info "#{http_method.upcase} #{path}" logger.debug "Params: #{params.inspect}" logger.debug "Headers: #{headers.inspect}" args << headers if headers process_data client[path].send(*args) end
logger=(logger)
click to toggle source
# File lib/foreman_api/base.rb, line 106 def logger=(logger) if logger.nil? logger = Logger.new(STDOUT) logger.level = Logger::WARN end @logger = logger end
perform_call(method_name, params, headers)
click to toggle source
# File lib/foreman_api/base.rb, line 55 def perform_call(method_name, params, headers) method_doc = self.class.method_doc(method_name) check_params params, :allowed => method_doc['params'].any?, :method => method_name method_apis = method_doc['apis'] api = find_suitable_api_call(method_apis, params) url, params = fill_params_in_url api['api_url'], params return http_call(api['http_method'].downcase, url, params, headers) end
validate_params!(params, rules)
click to toggle source
# File lib/foreman_api/base.rb, line 93 def validate_params!(params, rules) return unless params.is_a?(Hash) invalid_keys = params.keys.map(&:to_s) - (rules.is_a?(Hash) ? rules.keys : rules) raise ArgumentError, "Invalid keys: #{invalid_keys.join(", ")}" unless invalid_keys.empty? if rules.is_a? Hash rules.each do |key, sub_keys| validate_params!(params[key], sub_keys) if params[key] end end end
Protected Instance Methods
check_params(params, options = { })
click to toggle source
# File lib/foreman_api/base.rb, line 126 def check_params(params, options = { }) raise ArgumentError unless (method = options[:method]) return unless config[:enable_validations] case options[:allowed] when true validate_params!(params, self.class.validation_hash(method)) when false raise ArgumentError, "this method '#{method}' does not support params" if params && !params.empty? else raise ArgumentError, "options :allowed should be true or false, it was #{options[:allowed]}" end end
fill_params_in_url(url, params)
click to toggle source
@return url and rest of the params
# File lib/foreman_api/base.rb, line 168 def fill_params_in_url(url, params) params ||= { } # insert param values url_param_names = self.class.params_in_path(url) url = url_param_names.inject(url) do |url, param_name| param_value = params[param_name] or raise ArgumentError, "missing param '#{param_name}' in parameters" url.sub(":#{param_name}", URI.escape(param_value.to_s)) end return url, params.reject { |param_name, _| url_param_names.include? param_name } end
find_suitable_api_call(possible_apis, params)
click to toggle source
@param possible_apis [Array] Array of hasahs in form of
[{:api_url => '/path1', :http_method => 'GET'}, {...}]
@param params [Hash] enterred params @return api that suits the enterred params mosts
Given this paths:
1. +/comments+ 2. +/users/:user_id/comments+ 3. +/users/:user_id/posts/:post_id/comments+
If :user_id
and :post_id
is pecified, the third
path is used. If only :user_id
is specified, the second one is
used. The selection defaults to the path with the least number of incuded
params in alphanumeric order.
# File lib/foreman_api/base.rb, line 154 def find_suitable_api_call(possible_apis, params) apis_with_params = possible_apis.map do |api| [api, self.class.params_in_path(api['api_url'])] end.sort_by { |api, url_params| [-1 * url_params.count, api['api_url']] } suitable_api = apis_with_params.find do |api, url_params| url_params.all? { |url_param| params.keys.map(&:to_s).include?(url_param) } end suitable_api ||= apis_with_params.last return suitable_api.first end
process_data(response)
click to toggle source
# File lib/foreman_api/base.rb, line 116 def process_data(response) data = begin JSON.parse(response.body) rescue JSON::ParserError response.body end logger.debug "Returned data: #{data.inspect}" return data, response end