class Vault::Usage::Client

Client provides a Ruby API to access the Vault::Usage HTTP API.

Client for the `Vault::Usage` HTTP API.

Constants

VERSION

The `Vault::Usage::Client` gem version.

Attributes

url[R]

Public Class Methods

new(url = nil) click to toggle source

Instantiate a client.

@param url [String] The URL to connect to. Include the username and

password to use when connecting.
# File lib/vault-usage-client/client.rb, line 14
def initialize(url = nil)
  @url = url || ENV['VAULT_USAGE_URL']
end

Public Instance Methods

close_app_ownership_event(event_id, user_hid, app_hid, stop_time) click to toggle source

Report that ownership of an app by a user stopped at a particular time.

@param event_id [String] A UUID that uniquely identifies the ownership

event.

@param user_hid [String] The user HID, such as `user1234@heroku.com`,

that owned the specified app.

@param app_hid [String] The app HID, such as `app1234@heroku.com`, that

is being transferred away from the specified user.

@param stop_time [Time] The end of the ownership period, always in UTC. @raise [InvalidTimeError] Raised if a non-UTC stop time is provided. @raise [Excon::Errors::HTTPStatusError] Raised if the server returns an

unsuccessful HTTP status code.
# File lib/vault-usage-client/client.rb, line 309
def close_app_ownership_event(event_id, user_hid, app_hid, stop_time)
  unless stop_time.zone.eql?('UTC')
    raise InvalidTimeError.new('Stop time must be in UTC.')
  end
  path = "/users/#{user_hid}/apps/#{app_hid}/close/#{event_id}" +
         "/#{iso_format(stop_time)}"
  connection = Excon.new(@url)
  connection.put(path: path, expects: [201])
end
close_usage_event(event_id, product_name, consumer_hid, stop_time) click to toggle source

Report that usage of a product, by a user or app, stopped at a particular time.

@param event_id [String] A UUID that uniquely identifies the usage

event.

@param product_name [String] The name of the product that was used, such

as `platform:dyno:logical` or `addon:memcache:100mb`.

@param consumer_hid [String] The Heroku ID, such as `app1234@heroku.com`

or `user1234@heroku.com`, that represents the user or app that used
the specified product.

@param stop_time [Time] The end of the usage period, always in UTC. @raise [InvalidTimeError] Raised if a non-UTC stop time is provided. @raise [Excon::Errors::HTTPStatusError] Raised if the server returns an

unsuccessful HTTP status code.
# File lib/vault-usage-client/client.rb, line 67
def close_usage_event(event_id, product_name, consumer_hid, stop_time)
  unless stop_time.zone.eql?('UTC')
    raise InvalidTimeError.new('Stop time must be in UTC.')
  end
  path = "/products/#{product_name}/usage/#{consumer_hid}" +
         "/events/#{event_id}/close/#{iso_format(stop_time)}"
  connection = Excon.new(@url)
  connection.put(path: path, expects: [201])
end
open_app_ownership_event(event_id, user_hid, app_hid, start_time) click to toggle source

Report that ownership of an app by a user started at a particular time.

@param event_id [String] A UUID that uniquely identifies the ownership

event.

@param user_hid [String] The user HID, such as `user1234@heroku.com`,

that owns the specified app.

@param app_hid [String] The app HID, such as `app1234@heroku.com`, that

is being transferred to the specified user.

@param start_time [Time] The beginning of the ownership period, always

in UTC.

@raise [InvalidTimeError] Raised if a non-UTC start time is provided. @raise [Excon::Errors::HTTPStatusError] Raised if the server returns an

unsuccessful HTTP status code.
# File lib/vault-usage-client/client.rb, line 287
def open_app_ownership_event(event_id, user_hid, app_hid, start_time)
  unless start_time.zone.eql?('UTC')
    raise InvalidTimeError.new('Start time must be in UTC.')
  end
  path = "/users/#{user_hid}/apps/#{app_hid}/open/#{event_id}" +
         "/#{iso_format(start_time)}"
  connection = Excon.new(@url)
  connection.put(path: path, expects: [201])
end
open_close_usage_event(event_id, product_name, consumer_hid, start_time, stop_time, detail=nil) click to toggle source

Report that usage of a product, by a user or app, started at a particular time.

@param event_id [String] A UUID that uniquely identifies the usage

event.

@param product_name [String] The name of the product that was used, such

as `platform:dyno:logical` or `addon:memcache:100mb`.

@param consumer_hid [String] The Heroku ID, such as `app1234@heroku.com`

or `user1234@heroku.com`, that represents the user or app that used
the specified product.

@param start_time [Time] The beginning of the usage period, always in

UTC.

@param stop_time [Time] The end of the usage period, always in UTC. @param detail [Hash] Optionally, additional details to store with the

event.  Keys must be of type `Symbol` and values may only be of type
`String`, `Fixnum`, `Bignum`, `Float`, `TrueClass`, `FalseClass` or
`NilClass`.

@raise [InvalidTimeError] Raised if a non-UTC start time is provided. @raise [Excon::Errors::HTTPStatusError] Raised if the server returns an

unsuccessful HTTP status code.
# File lib/vault-usage-client/client.rb, line 97
def open_close_usage_event(event_id, product_name, consumer_hid,
                           start_time, stop_time, detail=nil)
  unless start_time.zone.eql?('UTC')
    raise InvalidTimeError.new('Start time must be in UTC.')
  end
  unless stop_time.zone.eql?('UTC')
    raise InvalidTimeError.new('Stop time must be in UTC.')
  end
  path = "/products/#{product_name}/usage/#{consumer_hid}" +
         "/events/#{event_id}/open/#{iso_format(start_time)}" +
         "/close/#{iso_format(stop_time)}"
  unless detail.nil?
    headers = {'Content-Type' => 'application/json'}
    body = MultiJson.dump(detail)
  end
  connection = Excon.new(@url)
  connection.put(path: path, headers: headers, body: body,
                 expects: [201])
end
open_dynos_for_app(app_hid) click to toggle source

Get the open dyno usage events for the specified app

@param app_hid [String] The app HID, such as `app1234@heroku.com`, to

fetch open dyno usage data for.

@raise [Excon::Errors::HTTPStatusError] Raised if the server returns an

unsuccessful HTTP status code.

@return [Array] A list of usage events for the specified app, matching

the following format:

```
  [{id: '<event-uuid>',
    product: '<name>',
    consumer: '<heroku-id>',
    start_time: <Time>,
    stop_time: <Time>,
    detail: {<key1>: <value1>,
             <key2>: <value2>,
             ...}},
    ...]}
```
# File lib/vault-usage-client/client.rb, line 260
def open_dynos_for_app(app_hid)
  path = "/apps/#{app_hid}/ps/open"
  query = {}
  connection = Excon.new(@url)
  response = connection.get(path: path, expects: [200], query: query)
  payload = MultiJson.load(response.body, {symbolize_keys: true})
  events = payload[:events]
  events.each do |event|
    event.each do |key, value|
      event[key] = parse_date(value) if date?(value)
    end
  end
end
open_usage_event(event_id, product_name, consumer_hid, start_time, detail=nil) click to toggle source

Report that usage of a product, by a user or app, started at a particular time.

@param event_id [String] A UUID that uniquely identifies the usage

event.

@param product_name [String] The name of the product that was used, such

as `platform:dyno:logical` or `addon:memcache:100mb`.

@param consumer_hid [String] The Heroku ID, such as `app1234@heroku.com`

or `user1234@heroku.com`, that represents the user or app that used
the specified product.

@param start_time [Time] The beginning of the usage period, always in

UTC.

@param detail [Hash] Optionally, additional details to store with the

event.  Keys must be of type `Symbol` and values may only be of type
`String`, `Fixnum`, `Bignum`, `Float`, `TrueClass`, `FalseClass` or
`NilClass`.

@raise [InvalidTimeError] Raised if a non-UTC start time is provided. @raise [Excon::Errors::HTTPStatusError] Raised if the server returns an

unsuccessful HTTP status code.
# File lib/vault-usage-client/client.rb, line 37
def open_usage_event(event_id, product_name, consumer_hid, start_time,
                     detail=nil)
  unless start_time.zone.eql?('UTC')
    raise InvalidTimeError.new('Start time must be in UTC.')
  end
  path = "/products/#{product_name}/usage/#{consumer_hid}" +
         "/events/#{event_id}/open/#{iso_format(start_time)}"
  unless detail.nil?
    headers = {'Content-Type' => 'application/json'}
    body = MultiJson.dump(detail)
  end
  connection = Excon.new(@url)
  connection.put(path: path, headers: headers, body: body,
                 expects: [201])
end
usage_for_event(event_id) click to toggle source

Request a single usage event.

@raise [Excon::Errors::HTTPStatusError] Raised if the server returns an

unsuccessful HTTP status code.

@return [Array] A single usage event, matching the following format:

```json
  {id: '<event-uuid>',
   product: '<name>',
   consumer: '<heroku-id>',
   start_time: '<YYYY-MM-DDTHH:MM:SSZ>',
   stop_time: '<YYYY-MM-DDTHH:MM:SSZ>',
   detail: {<key1>: <value1>,
            <key2>: <value2> }
  }
# File lib/vault-usage-client/client.rb, line 133
def usage_for_event(event_id)
  path = "/usage_events/#{event_id}"
  connection = Excon.new(@url)
  response = connection.get(path: path, expects: [200])
  event = MultiJson.load(response.body, {symbolize_keys: true})
  event.each do |key, value|
    event[key] = parse_date(value) if date?(value)
  end
end
usage_for_user(user_hid, start_time, stop_time, exclude=nil, callback_url=nil, snapshot=false) click to toggle source

Get the usage events for the apps owned by the specified user during the specified period.

@param user_hid [String] The user HID, such as `user1234@heroku.com`, to

fetch usage data for.

@param start_time [Time] The beginning of the usage period, always in

UTC, within which events must overlap to be included in usage data.

@param stop_time [Time] The end of the usage period, always in UTC,

within which events must overlap to be included in usage data.

@param exclude [Array] Optionally, a list of product names, such as

`['platform:dyno:physical', 'addon:memcache:100mb']`, to be excluded
from usage data.

@param callback_url [String] The URL vault-usage will callback after generating usage events JSON @param snapshot [Boolean] Whether or not to return only events that were open at the start_time @raise [InvalidTimeError] Raised if a non-UTC start or stop time is

provided.

@raise [Excon::Errors::HTTPStatusError] Raised if the server returns an

unsuccessful HTTP status code.

@return [Array] A list of usage events for the specified user, matching

the following format:

```
  [{id: '<event-uuid>',
    product: '<name>',
    consumer: '<heroku-id>',
    start_time: <Time>,
    stop_time: <Time>,
    detail: {<key1>: <value1>,
             <key2>: <value2>,
             ...}},
    ...]}
```
# File lib/vault-usage-client/client.rb, line 177
def usage_for_user(user_hid, start_time, stop_time, exclude=nil, callback_url=nil, snapshot=false)
  unless start_time.zone.eql?('UTC')
    raise InvalidTimeError.new('Start time must be in UTC.')
  end
  unless stop_time.zone.eql?('UTC')
    raise InvalidTimeError.new('Stop time must be in UTC.')
  end
  path = "/users/#{user_hid}/usage/#{iso_format(start_time)}/" +
               "#{iso_format(stop_time)}"
  query = {}
  query[:snapshot] = true if snapshot
  unless exclude.nil? || exclude.empty?
    query[:exclude] = exclude.join(',')
  end
  query[:callback_url] = callback_url if callback_url
  connection = Excon.new(@url)
  response = connection.get(path: path, expects: [200], query: query)
  payload = MultiJson.load(response.body, {symbolize_keys: true})
  return payload[:job_id] if payload[:job_id]
  events = payload[:events]
  events.each do |event|
    event.each do |key, value|
      event[key] = parse_date(value) if date?(value)
    end
  end
end
usage_for_user_by_product(user_hid, product_name) click to toggle source

Get the usage events for a product specific to a user.

@param user_hid [String] The user HID, such as `user1234@heroku.com`, to

fetch usage data for.

@param product_name [String] The product name such as `account:credit:lumpsum`, to

fetch usage data for.

@raise [Excon::Errors::HTTPStatusError] Raised if the server returns an

unsuccessful HTTP status code.

@return [Array] A list of usage events for the specified user, matching

the following format:

```
  [{id: '<event-uuid>',
    product: '<name>',
    consumer: '<heroku-id>',
    start_time: <Time>,
    stop_time: <Time>,
    detail: {<key1>: <value1>,
             <key2>: <value2>,
             ...}},
    ...]}
```
# File lib/vault-usage-client/client.rb, line 226
def usage_for_user_by_product(user_hid, product_name)
  path = "/users/#{user_hid}/usage/product/#{product_name}"
  connection = Excon.new(@url)
  response = connection.get(path: path, expects: [200])
  payload = MultiJson.load(response.body, {symbolize_keys: true})
  return payload[:job_id] if payload[:job_id]
  events = payload[:events]
  events.each do |event|
    event.each do |key, value|
      event[key] = parse_date(value) if date?(value)
    end
  end
end

Private Instance Methods

date?(value) click to toggle source

Determine if the value is an ISO 8601 date in `YYYY-MM-DDTHH:MM:SSZ` format.

@param value [String] The value to check for date-ness. @return [TrueClass,FalseClass] True if the value resembles a date,

otherwise false.
# File lib/vault-usage-client/client.rb, line 335
def date?(value)
  value =~ /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z/
end
iso_format(time) click to toggle source

Convert a time to an ISO 8601 combined data and time format.

@param time [Time] The time to convert to ISO 8601 format. @return [String] An ISO 8601 date in `YYYY-MM-DDTHH:MM:SSZ` format.

# File lib/vault-usage-client/client.rb, line 325
def iso_format(time)
  time.strftime('%Y-%m-%dT%H:%M:%SZ')
end
parse_date(value) click to toggle source

Parse an ISO 8601 date in `YYYY-MM-DDTHH:MM:SSZ` format into a Time instance.

@param value [String] The value to parse. @raise [ArgumentError] Raised if the value doesn't represent a valid

date.

@return [Time] The Time instance created from the date string in UTC.

# File lib/vault-usage-client/client.rb, line 346
def parse_date(value)
  DateTime.parse(value).to_time.getutc
end