Class: Miasma::Types::Api

Inherits:
Object
  • Object
show all
Includes:
Utils::Lazy, Utils::Memoization
Defined in:
lib/miasma/types/api.rb

Overview

Remote API connection

Direct Known Subclasses

Models::AutoScale, Models::Compute, Models::LoadBalancer, Models::Orchestration, Models::Storage

Instance Method Summary (collapse)

Constructor Details

- (self) initialize(creds)

Create new API connection

Parameters:

  • creds (Smash)

    credentials



16
17
18
19
20
21
22
23
# File 'lib/miasma/types/api.rb', line 16

def initialize(creds)
  if(creds.is_a?(Hash))
    load_data(creds)
  else
    raise TypeError.new "Expecting `credentials` to be of type `Hash`. Received: `#{creds.class}`"
  end
  connect
end

Instance Method Details

- (Object) _memo Originally defined in module Utils::Memoization

- (Api) api_for(type)

Build new API for specified type using current provider / creds

Parameters:

  • type (Symbol)

    api type

Returns:



41
42
43
44
45
46
47
48
49
50
51
# File 'lib/miasma/types/api.rb', line 41

def api_for(type)
  memoize(type) do
    Miasma.api(
      Smash.new(
        :type => type,
        :provider => provider,
        :credentials => attributes
      )
    )
  end
end

- (TrueClass) clear_memoizations! Originally defined in module Utils::Memoization

Remove all memoized values

Returns:

  • (TrueClass)

- (self) connect

Connect to the remote API

Returns:

  • (self)


33
34
35
# File 'lib/miasma/types/api.rb', line 33

def connect
  self
end

- (HTTP) connection

Returns:

  • (HTTP)


54
55
56
# File 'lib/miasma/types/api.rb', line 54

def connection
  HTTP.with_headers('User-Agent' => "miasma/v#{Miasma::VERSION}")
end

- (String) endpoint

Returns url endpoint

Returns:

  • (String)

    url endpoint



59
60
61
# File 'lib/miasma/types/api.rb', line 59

def endpoint
  'http://api.example.com'
end

- (Smash) format_response(result, extract_body = true)

Makes best attempt at formatting response

Parameters:

  • result (HTTP::Response)
  • extract_body (TrueClass, FalseClass) (defaults to: true)

    automatically extract body

Returns:



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/miasma/types/api.rb', line 121

def format_response(result, extract_body=true)
  extracted_headers = Smash[result.headers.map{|k,v| [Utils.snake(k), v]}]
  if(extract_body)
    if(extracted_headers[:content_type].to_s.include?('json'))
      begin
        extracted_body = MultiJson.load(result.body.to_s)
        if(extracted_body.respond_to?(:to_smash))
          extracted_body = extracted_body.to_smash
        elsif(extracted_body.respond_to?(:map!))
          extracted_body.map! do |i|
            i.respond_to?(:to_smash) ? i.to_smash : i
          end
        end
      rescue MultiJson::ParseError
        extracted_body = result.body.to_s
      end
    elsif(extracted_headers[:content_type].to_s.include?('xml'))
      begin
        extracted_body = MultiXml.parse(result.body.to_s)
        if(extracted_body.respond_to?(:to_smash))
          extracted_body = extracted_body.to_smash
        elsif(extracted_body.respond_to?(:map!))
          extracted_body.map! do |i|
            i.respond_to?(:to_smash) ? i.to_smash : i
          end
        end
      rescue MultiXml::ParseError
        extracted_body = result.body.to_s
      end
    end
  end
  unless(extracted_body)
    # @note if body is over 100KB, do not extract
    if(extracted_headers[:content_length].to_i < 102400)
      extracted_body = result.body.to_s
    else
      extracted_body = result.body
    end
  end
  Smash.new(
    :response => result,
    :headers => extracted_headers,
    :body => extracted_body
  )
end

- (HTTP::Response) make_request(connection, http_method, request_args)

Note:

this is mainly here for concrete APIs to override if things need to be done prior to the actual request (like signature generation)

Perform request

Parameters:

  • connection (HTTP)
  • http_method (Symbol)
  • request_args (Array)

Returns:

  • (HTTP::Response)


112
113
114
# File 'lib/miasma/types/api.rb', line 112

def make_request(connection, http_method, request_args)
  connection.send(http_method, *request_args)
end

- (Object) memoize(key, direct = false) { ... } Originally defined in module Utils::Memoization

Memoize data

Parameters:

  • key (String, Symbol)

    identifier for data

  • direct (Truthy, Falsey) (defaults to: false)

    direct skips key prepend of object id

Yields:

  • block to create data

Yield Returns:

  • data to memoize

Returns:

  • (Object)

    data

- (Symbol) provider

Returns name of provider

Returns:

  • (Symbol)

    name of provider



26
27
28
# File 'lib/miasma/types/api.rb', line 26

def provider
  Utils.snake(self.class.to_s.split('::').last).to_sym
end

- (Smash) request(args)

Perform request to remote API

Parameters:

  • args (Hash)

    options

Options Hash (args):

  • :method (String, Symbol)

    HTTP request method

  • :path (String)

    request path

  • :expects (Integer, Array<Integer>)

    expected response status code

  • :disable_body_extraction (TrueClass, FalseClass)

    do not auto-parse response body

Returns:

  • (Smash)

    => HTTP::Response, :headers => Smash, :body => Object



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/miasma/types/api.rb', line 72

def request(args)
  args = args.to_smash
  http_method = args.fetch(:method, 'get').to_s.downcase.to_sym
  unless(HTTP::Request::METHODS.include?(http_method))
    raise ArgumentError.new 'Invalid request method provided!'
  end
  request_args = [].tap do |ary|
    _endpoint = args.delete(:endpoint) || endpoint
    ary.push(
      File.join(_endpoint, args[:path].to_s)
    )
    options = {}.tap do |opts|
      [:form, :params, :json, :body].each do |key|
        opts[key] = args[key] if args[key]
      end
    end
    ary.push(options) unless options.empty?
  end
  if(args[:headers])
    _connection = connection.with_headers(args[:headers])
    args.delete(:headers)
  else
    _connection = connection
  end
  result = make_request(_connection, http_method, request_args)
  unless([args.fetch(:expects, 200)].flatten.compact.map(&:to_i).include?(result.code))
    raise Error::ApiError::RequestError.new(result.reason, :response => result)
  end
  format_response(result, !args[:disable_body_extraction])
end

- (NilClass) unmemoize(key, direct = false) Originally defined in module Utils::Memoization

Remove memoized value

Parameters:

  • key (String, Symbol)

    identifier for data

  • direct (Truthy, Falsey) (defaults to: false)

    direct skips key prepend of object id

Returns:

  • (NilClass)