class Chimp::Connection

This class contains all the necessary to make calls to api1.5 via the right_api_client gem or obtain a list of instances via api1.6 calls.

Attributes

all_instances[RW]
client[RW]
retry[RW]

Public Class Methods

all_instances() click to toggle source

Returns every single operational instance in the account

# File lib/right_chimp/resources/connection.rb, line 91
def self.all_instances()
  begin
    Log.debug "[#{Chimp.get_job_uuid}] Requesting all instances"

    filters_list = "state=operational"
    filters = CGI::escape(filters_list)

    query="/api/instances?view=full&filter="+filters

    all_instances = Connection.api16_call(query)

  rescue Exception => e
    Log.error "[#{Chimp.get_job_uuid}] self.all_instaces"
    Log.error "[#{Chimp.get_job_uuid}] #{e.message}"
  end

  return all_instances
end
api16_call(query) click to toggle source

Provides a way to make an api1.6 call directly

# File lib/right_chimp/resources/connection.rb, line 134
def Connection.api16_call(query)
  Thread.current[:retry] = true
  Thread.current[:response] = nil
  retries = 5
  attempts = 0
  sleep_for = 20

  begin
    get = Net::HTTP::Get.new(query)
    if @client.access_token
      # auth using oauth access token
      get['Authorization'] = 'Bearer ' + @client.access_token
    else
      get['Cookie']        = @client.cookies.map { |key, value| "%s=%s" % [key, value] }.join(';')
    end
    get['X-Api_Version'] = '1.6'
    get['X-Account']     = @client.account_id

    http = Net::HTTP.new(@endpoint, 443)
    http.use_ssl = true

    Log.debug "[#{Chimp.get_job_uuid}] Querying API for: #{query}"

    while attempts < retries
      Log.debug "[#{Chimp.get_job_uuid}] Attempt is: #{attempts.to_s}"
      Log.debug "[#{Chimp.get_job_uuid}] Retry is: #{Thread.current[:retry].to_s}"
      if Thread.current[:retry]
        if attempts > 0
          Log.debug "[#{Chimp.get_job_uuid}] Retrying..."
          sleep_time = sleep_for * attempts
          # Add a random amount to avoid staggering calls
          sleep_time += rand(15)

          Log.debug "[#{Chimp.get_job_uuid}] Sleeping between retries for #{sleep_time}"
          sleep(sleep_time)
        end

        Log.debug "[#{Chimp.get_job_uuid}] Attempt # #{attempts+1} at querying the API" unless attempts == 0

        Log.debug "[#{Chimp.get_job_uuid}] HTTP Making http request"
        start_time = Time.now
        Thread.current[:response] = http.request(get)
        end_time = Time.now
        total_time = end_time - start_time

        Log.debug "[#{Chimp.get_job_uuid}] HTTP Request complete"
        attempts += 1

        Log.debug "[#{Chimp.get_job_uuid}] API Request time: #{total_time} seconds"
        Log.debug "[#{Chimp.get_job_uuid}] API Query was: #{query}"

        # Validate API response
        Log.debug "[#{Chimp.get_job_uuid}] Validating..."
        instances = validate_response(Thread.current[:response], query)
      else
        # We dont retry, exit the loop.
        Log.debug "[#{Chimp.get_job_uuid}] Not retrying, exiting the loop."
        Thread.current[:retry] = false
        break
      end
    end

    if attempts == retries

      Log.error "[#{Chimp.get_job_uuid}] Api call failed more than #{retries} times."

      Chimp.set_failure(true)
      Log.error "[#{Chimp.get_job_uuid}] Set failure to true because of max retries"

      instances = []
      raise "[#{Chimp.get_job_uuid}] Api call failed more than #{retries} times."
    end

    if instances.nil?
      Log.error "[#{Chimp.get_job_uuid}] instances is nil!"
    else
      Log.debug "[#{Chimp.get_job_uuid}] API matched #{instances.count} instances"
    end

  rescue Exception => e
    Log.error "[#{Chimp.get_job_uuid}] #{e.message}"
    Log.error "[#{Chimp.get_job_uuid}] Catched exception on http request to the api, retrying"

    instances = []
    attempts += 1
    retry
  end

  return instances
end
audit_url() click to toggle source
# File lib/right_chimp/resources/connection.rb, line 84
def self.audit_url
  @audit_url
end
client() click to toggle source
# File lib/right_chimp/resources/connection.rb, line 76
def self.client
  @client
end
connect() click to toggle source
# File lib/right_chimp/resources/connection.rb, line 32
def self.connect
  self.start_right_api_client
end
connect_and_cache() click to toggle source
# File lib/right_chimp/resources/connection.rb, line 17
def self.connect_and_cache

  self.start_right_api_client

  Log.debug "Making initial Api1.6 call to cache entries."

  result = self.all_instances
  if result.empty? || result.nil?
    Log.error "Couldnt contact API1.6 correctly, will now exit."
    exit -1
  else
    Log.debug "API lists #{result.count} operational instances in the account"
  end
end
endpoint() click to toggle source
# File lib/right_chimp/resources/connection.rb, line 80
def self.endpoint
  @endpoint
end
instances(extra_filters) click to toggle source

Returns every single operational instance in the account, matching the filters passed.

# File lib/right_chimp/resources/connection.rb, line 113
def self.instances(extra_filters)
  Log.debug "[#{Chimp.get_job_uuid}] Requesting some instances"
  begin
    filters_list = "state=operational&"+extra_filters
    filters = CGI::escape(filters_list)

    query="/api/instances?view=full&filter="+filters

    instances = Connection.api16_call(query)

  rescue Exception => e
    Log.error "[#{Chimp.get_job_uuid}] self.instances"
    Log.error "[#{Chimp.get_job_uuid}] #{e.message}"
  end

  return instances
end
new() click to toggle source
# File lib/right_chimp/resources/connection.rb, line 14
def initialize
end
start_right_api_client() click to toggle source
# File lib/right_chimp/resources/connection.rb, line 36
def self.start_right_api_client
  require 'yaml'
  require 'right_api_client'

  begin
    creds = YAML.load_file("#{ENV['HOME']}/.rest_connection/rest_api_config.yaml")

    # Extract the account
    creds[:account] = File.basename(creds[:api_url])

    # Figure out url to hit:
    creds[:api_url] = "https://"+URI.parse(creds[:api_url]).host

    @audit_url = creds[:api_url] + "/acct/" + creds[:account]

    @endpoint = URI.parse(creds[:api_url]).host

    Log.debug "Logging into Api 1.5 right_api_client"
    if creds[:refresh_token] then
      # no account id extraction, must be specified in config file
      # refresh_token must be specified in config
      @client = RightApi::Client.new(refresh_token: creds[:refresh_token],
                                     account_id: creds[:account], api_url: creds[:api_url],
                                     timeout: 60, enable_retry: true)
    else
      @client = RightApi::Client.new(email: creds[:user], password: creds[:pass],
                                     account_id: creds[:account], api_url: creds[:api_url],
                                     timeout: 60, enable_retry: true)
    end
  rescue
    puts "##############################################################################"
    puts "Error: "
    puts " - credentials file could not be loaded correctly"
    puts "or                           "
    puts " - connection couldnt be establishhed"
    puts "##############################################################################"
    exit -1
  end
end
validate_response(response, query) click to toggle source

Verify the results are valid JSON

# File lib/right_chimp/resources/connection.rb, line 228
def Connection.validate_response(response, query)

  resp_code = response.code
  # handle response codes we want to work with (200 or 404) and verify json hash from github
  if resp_code == "200" || resp_code == "404"
    body_data = response.body
    # verify json hash is valid and operate accordingly
    begin
      result = JSON.parse(body_data)
      if result.is_a?(Array)
        # Operate on a 200 or 404 with valid JSON response, catch error messages from github in json hash
        if result.include? 'message'
          Log.error "[#{Chimp.get_job_uuid}] [CONTENT] Errot: Problem with API request: '#{resp_code} #{response.body}'."
          raise "[#{Chimp.get_job_uuid}] [CONTENT] Error: Problem with API request: '#{resp_code} #{response.body}'"
        end
        if result.include? 'Error'
          Log.error "[#{Chimp.get_job_uuid}] [CONTENT] Warning BAD CONTENT: Response content: '#{response.body}'."
          return {} # Return an empty json
        end

        # Log.debug "We received a valid JSON response, therefore returning it."

        Thread.current[:retry] = false

        Log.debug "[#{Chimp.get_job_uuid}] Validated and returning size of #{result.size} "
        return result
      end
    rescue JSON::ParserError
      Log.error "[#{Chimp.get_job_uuid}] Warning: Expected JSON response but was unable to parse!"
      #Log.error "Warning: #{response.body}!"

      return {} # Return an empty result
    end

  elsif resp_code == "502"
    Log.debug "[#{Chimp.get_job_uuid}] Api returned code: 502"
    Log.debug "[#{Chimp.get_job_uuid}] Query was: #{query}"

    Thread.current[:retry] = true

  elsif resp_code == "500"
    Log.debug "[#{Chimp.get_job_uuid}] Api returned code: 500"
    Log.debug "[#{Chimp.get_job_uuid}] Query was: #{query}"

    Thread.current[:retry] = true

  elsif resp_code == "504"
      Log.debug "[#{Chimp.get_job_uuid}] Api returned code: 504"
      Log.debug "[#{Chimp.get_job_uuid}] Query was: #{query}"

      Thread.current[:retry] = true

  else
    # We are here because response was not 200 or 404
    # Any http response code that is not 200 / 404 / 500 / 502 should error out.
    Log.error "[#{Chimp.get_job_uuid}] ERROR: Got '#{resp_code} #{response.msg}' response from api!  "
    Log.error "[#{Chimp.get_job_uuid}] Query was: #{query}"
    raise "[#{Chimp.get_job_uuid}] Couldnt contact the API"
    return {}
  end
end