# frozen_string_literal: true require 'config_server_agent/version' require 'net/http' require 'json' require 'digest/sha1' require 'lockfile' class ConfigServerAgent class Error < StandardError; end def initialize( config_server_api_key: ENV['CONFIG_SERVER_API_KEY'], config_server_host: ENV['CONFIG_SERVER_HOST'], user_agent: "ConfigServerAgent/#{ConfigServerAgent::VERSION}", user_agent_comment: nil ) @config_server_api_key = config_server_api_key or raise ArgumentError, 'Missing config_server_api_key parameter' @config_server_host = config_server_host or raise ArgumentError, 'Missing config_server_host parameter' @config = nil @mutex = Mutex.new @user_agent = user_agent @user_agent += " (#{user_agent_comment})" if user_agent_comment end def get_config return @config if @config @mutex.synchronize do @config ||= get_request 'config_pack' end end def get_selected_config(area, item=nil, **options) if options[:ignore_cache] @config = nil end data = get_config.group_by { |x| x['area'] } raise Error, "Area is missing: #{area}" unless data.key? area if item data.fetch(area, []).find { |row_item| break row_item["value"] if row_item["name"] == item } else data.fetch(area, []) end end def set_config(values) raise Error, 'values not found' if values.empty? post_request('set_values', values) end def clear @config = nil end def notify_missing(area, missing) post_request 'notify_missing', area: area, name: missing end private def post_request(endpoint, data={}) dispatch_request(endpoint) do |url| request = Net::HTTP::Post.new url request.body = data.to_json request end end def get_request(endpoint, data={}) dispatch_request(endpoint) do |url| url.query = URI.encode_www_form data Net::HTTP::Get.new url end end def dispatch_request(endpoint) url = URI "#{@config_server_host}/api/#{endpoint}" http = Net::HTTP.new url.host, url.port http.use_ssl = url.scheme == 'https' request = yield url request['user-agent'] = @user_agent request['content-type'] = 'application/json' request['accept'] = 'application/json' request['api-key'] = @config_server_api_key process_response http.request(request) end def process_response(response) unless response['content-type'].start_with? 'application/json' raise Error, "Unexpected content-type from server: #{response['content-type']}" end data = JSON.parse response.read_body raise Error, "Config Server error: #{data['error']}" unless response.is_a? Net::HTTPSuccess data rescue JSON::ParserError raise Error, "Invalid JSON received from #{@config_server_host}" end end