lib/smooth_operator/operator.rb
require "smooth_operator/remote_call/base"
require "smooth_operator/operators/faraday"
require "smooth_operator/operators/typhoeus"
require "smooth_operator/remote_call/errors/timeout"
require "smooth_operator/operators/connection_wrapper"
require "smooth_operator/remote_call/errors/connection_failed"
module SmoothOperator
module Operator
def headers
{}
end
def make_the_call(http_verb, relative_path = '', data = {}, options = {})
options ||= {}
relative_path = resource_path(relative_path)
options[:headers] = headers.merge(options[:headers] || {})
options[:parent_object] ||= _options[:parent_object]
call_args = before_request(http_verb, relative_path, data, options)
self.class.make_the_call(*call_args) do |remote_call|
yield(remote_call)
end
end
def resource_path(relative_path)
if Helpers.absolute_path?(relative_path)
Helpers.remove_initial_slash(relative_path)
elsif persisted?
id = Helpers.primary_key(self)
Helpers.present?(relative_path) ? "#{id}/#{relative_path}" : id.to_s
else
relative_path
end
end
def self.included(base)
base.extend(ClassMethods)
end
protected ################# PROTECTED ####################
def before_request(http_verb, relative_path, data, options)
[http_verb, relative_path, data, options]
end
module ClassMethods
OPTIONS = { endpoint: '', endpoint_user: '', endpoint_pass: '',
timeout: '', server_name: '', connection_options: {} }
OPTIONS.each do |option, default|
define_method(option) { get_option option, default }
end
def headers
get_option :headers, {}
end
def make_the_call(http_verb, relative_path = '', data = {}, options = {})
options = HelperMethods.populate_options(self, options)
resource_path = resource_path(relative_path, options)
http_verb, resource_path, data, options = before_request(http_verb, resource_path, data, options)
params, data = *HelperMethods.strip_params(self, http_verb, data)
operator = HelperMethods.get_me_an_operator(options)
operator.make_the_call(http_verb, resource_path, params, data, options) do |remote_call|
block_given? ? yield(remote_call) : remote_call
end
end
def query_string(params)
params
end
def resource_path(relative_path, options)
resources_name = options[:resources_name] || self.resources_name
if Helpers.present?(resources_name)
Helpers.present?(relative_path) ? "#{resources_name}/#{relative_path}" : resources_name
else
relative_path.to_s
end
end
def generate_parallel_connection
Operators::Typhoeus.generate_parallel_connection
end
protected ################# PROTECTED ####################
def before_request(http_verb, relative_path, data, options)
[http_verb, relative_path, data, options]
end
end
module HelperMethods
extend self
def get_me_an_operator(options)
if options[:parallel_connection].nil?
Operators::Faraday
else
options[:connection] = options.delete(:parallel_connection)
Operators::Typhoeus
end
end
def populate_options(object, options)
options ||= {}
ClassMethods::OPTIONS.each do |option, default|
options[option] ||= object.send(option)
end
options[:headers] = object.headers.merge(options[:headers] || {})
parent_object = options[:parent_object]
if !parent_object.nil? && options[:ignore_parent] != true
id = Helpers.primary_key(parent_object)
id = "#{id}/" if Helpers.present?(id)
options[:resources_name] ||= "#{parent_object.class.resources_name}/#{id}#{object.resources_name}"
end
options
end
def strip_params(object, http_verb, data)
data ||= {}
if [:get, :head, :delete].include?(http_verb)
[object.query_string(data), nil]
else
[object.query_string({}), data]
end
end
end
end
end