module Eco module API class Session class Config class Api < Hash class << self def to_version(str) case str.to_sym when :external, :v1 :v1 when :v2, :oozes :v2 when :graphql :graphql else # :internal, :v0 :v0 end end def api_class(version = :v0) case to_version(version) when :v0 Ecoportal::API::Internal when :v1 Ecoportal::API::V1 when :v2 require 'ecoportal/api-v2' Ecoportal::API::V2 when :graphql require 'ecoportal/api-graphql' Ecoportal::API::GraphQL else end end end def initialize(name, root:, key:, host:, version:, mode: :local, user_key: nil, external_key: nil, email: nil, pass: nil, org_id: nil) super(nil) @root = root @apis = {} self["name"] = name self["key"] = key self["host"] = host self["version"] = version self["mode"] = mode self["user_key"] = user_key self["external_key"] = external_key self["email"] = email || ENV['USER_EMAIL'] self["pass"] = pass || ENV['USER_PASS'] self["org_id"] = org_id end # @return [Eco::API::Session::Config] the `root` config def config @root.config end # Obtain an `API` object of a specific `version`. # @param version [Symbol] any of the available `API` versions [`:v0`, `:v1`, `:v2`]. # @param logger [Logger] the logger that will be used with this api instance. # @return [Ecoportal::API::Internal, Ecoportal::API::V2, Ecoportal::API::V1] def api(version: nil, logger: nil) version = version ? version : self.version switch_logger = (logger != @logger) @logger = logger if logger if (current = get(version)) && !switch_logger return current end unless api_params?(version) raise "The api configuration for '#{name}' is missing data for the api version '#{self.version(version)}'" end new_api(version).tap do |pi| set(version, pi) end end def set(version, api) @apis[self.version(version)] = api end def get(version) @apis[self.version(version)] end def name self["name"] end def one_off? name.is_a?(Symbol) end def key self["key"] end def user_key self["user_key"] || @root.default_user_key end def external_key self["external_key"] || ([:v1, :v2].include?(version) && key) end def internal_key (version == :v0) && self["key"] end def org_id self["org_id"] end def email self["email"] || @root.default_email end def pass self["pass"] || @root.default_pass end def host self["host"] end # @param mode [Symbol] to define if running on `:remote` or `:local` def mode=(mode) self["mode"] = (mode == :remote)? :remote : :local end # @return [Symbol] if running on `:remote` or `:local` def mode self["mode"] end def local? mode == :local end def remote? !local? end # @return [Boolean] whether or not `version` is available def version_available?(version) api_params?(version) end def version(value = nil) self.class.to_version(value || self["version"]) end # if no low level connection messages: use `IO::NULL` def logger @logger ||= ::Logger.new(IO::NULL) log_connection? ? @logger : ::Logger.new(IO::NULL) end private # Generates a **new** `API` object of version `version`. def new_api(version) klass = self.class.api_class(version) case self.version(version) when :v0 klass.new(internal_key, host: host, logger: logger) when :v1 klass.new(external_key, host: host, logger: logger) when :v2 klass.new(user_key: user_key, org_key: external_key, host: host, logger: logger) when :graphql klass.new(host: host, org_id: org_id, email: email, pass: pass) end.tap do |api| unless !api || log_connection? @logger.info("Created api#{self.version(version)} connection on '#{name}' enviro, pointing to '#{host}' in '#{mode}' mode") api.logger.level = ::Logger::UNKNOWN if api.respond_to?(:logger) end end end # Checks if the necessary parameters for a specific `API` version are available. def api_params?(version) case self.class.to_version(version) when :v0 internal_key && host when :v1 external_key && host when :v2 external_key && user_key && host when :graphql email && pass && org_id && host end end def log_connection? config.logger.log_connection? end end end end end end