wavefront-sdk 1.6.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +6 -0
- data/HISTORY.md +39 -13
- data/README.md +75 -28
- data/Rakefile +1 -1
- data/lib/wavefront-sdk/alert.rb +113 -17
- data/lib/wavefront-sdk/cloudintegration.rb +8 -8
- data/lib/wavefront-sdk/core/api.rb +99 -0
- data/lib/wavefront-sdk/core/api_caller.rb +211 -0
- data/lib/wavefront-sdk/{exception.rb → core/exception.rb} +11 -6
- data/lib/wavefront-sdk/{logger.rb → core/logger.rb} +2 -3
- data/lib/wavefront-sdk/{response.rb → core/response.rb} +69 -52
- data/lib/wavefront-sdk/credentials.rb +6 -3
- data/lib/wavefront-sdk/dashboard.rb +14 -14
- data/lib/wavefront-sdk/{constants.rb → defs/constants.rb} +1 -0
- data/lib/wavefront-sdk/defs/version.rb +1 -0
- data/lib/wavefront-sdk/derivedmetric.rb +14 -14
- data/lib/wavefront-sdk/distribution.rb +75 -0
- data/lib/wavefront-sdk/event.rb +13 -13
- data/lib/wavefront-sdk/externallink.rb +8 -8
- data/lib/wavefront-sdk/integration.rb +9 -9
- data/lib/wavefront-sdk/maintenancewindow.rb +54 -8
- data/lib/wavefront-sdk/message.rb +4 -4
- data/lib/wavefront-sdk/metric.rb +3 -3
- data/lib/wavefront-sdk/notificant.rb +9 -9
- data/lib/wavefront-sdk/paginator/base.rb +148 -0
- data/lib/wavefront-sdk/paginator/delete.rb +11 -0
- data/lib/wavefront-sdk/paginator/get.rb +11 -0
- data/lib/wavefront-sdk/paginator/post.rb +64 -0
- data/lib/wavefront-sdk/paginator/put.rb +11 -0
- data/lib/wavefront-sdk/proxy.rb +7 -7
- data/lib/wavefront-sdk/query.rb +4 -4
- data/lib/wavefront-sdk/report.rb +9 -25
- data/lib/wavefront-sdk/savedsearch.rb +8 -8
- data/lib/wavefront-sdk/search.rb +16 -13
- data/lib/wavefront-sdk/source.rb +14 -14
- data/lib/wavefront-sdk/{mixins.rb → support/mixins.rb} +8 -2
- data/lib/wavefront-sdk/{parse_time.rb → support/parse_time.rb} +2 -0
- data/lib/wavefront-sdk/types/status.rb +52 -0
- data/lib/wavefront-sdk/user.rb +8 -8
- data/lib/wavefront-sdk/validators.rb +52 -3
- data/lib/wavefront-sdk/webhook.rb +8 -8
- data/lib/wavefront-sdk/write.rb +153 -52
- data/lib/wavefront-sdk/writers/api.rb +38 -0
- data/lib/wavefront-sdk/writers/core.rb +146 -0
- data/lib/wavefront-sdk/writers/http.rb +42 -0
- data/lib/wavefront-sdk/writers/socket.rb +66 -0
- data/lib/wavefront-sdk/writers/summary.rb +39 -0
- data/lib/wavefront_sdk.rb +9 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/wavefront-sdk/alert_spec.rb +6 -0
- data/spec/wavefront-sdk/{base_spec.rb → core/api_caller_spec.rb} +28 -41
- data/spec/wavefront-sdk/core/api_spec.rb +31 -0
- data/spec/wavefront-sdk/{logger_spec.rb → core/logger_spec.rb} +3 -3
- data/spec/wavefront-sdk/core/response_spec.rb +77 -0
- data/spec/wavefront-sdk/credentials_spec.rb +15 -10
- data/spec/wavefront-sdk/distribution_spec.rb +78 -0
- data/spec/wavefront-sdk/paginator/base_spec.rb +67 -0
- data/spec/wavefront-sdk/paginator/post_spec.rb +53 -0
- data/spec/wavefront-sdk/report_spec.rb +3 -1
- data/spec/wavefront-sdk/search_spec.rb +25 -0
- data/spec/wavefront-sdk/stdlib/array_spec.rb +2 -1
- data/spec/wavefront-sdk/stdlib/hash_spec.rb +6 -1
- data/spec/wavefront-sdk/stdlib/string_spec.rb +2 -0
- data/spec/wavefront-sdk/{mixins_spec.rb → support/mixins_spec.rb} +2 -2
- data/spec/wavefront-sdk/{parse_time_spec.rb → support/parse_time_spec.rb} +2 -2
- data/spec/wavefront-sdk/validators_spec.rb +64 -1
- data/spec/wavefront-sdk/write_spec.rb +55 -77
- data/spec/wavefront-sdk/writers/api_spec.rb +45 -0
- data/spec/wavefront-sdk/writers/core_spec.rb +49 -0
- data/spec/wavefront-sdk/writers/http_spec.rb +69 -0
- data/spec/wavefront-sdk/writers/socket_spec.rb +104 -0
- data/spec/wavefront-sdk/writers/summary_spec.rb +38 -0
- data/wavefront-sdk.gemspec +1 -1
- metadata +52 -24
- data/lib/wavefront-sdk/base.rb +0 -264
- data/lib/wavefront-sdk/base_write.rb +0 -185
- data/lib/wavefront-sdk/stdlib.rb +0 -5
- data/lib/wavefront-sdk/version.rb +0 -1
- data/spec/wavefront-sdk/base_write_spec.rb +0 -82
- data/spec/wavefront-sdk/response_spec.rb +0 -39
@@ -1,11 +1,11 @@
|
|
1
|
-
require_relative '
|
1
|
+
require_relative 'core/api'
|
2
2
|
|
3
3
|
module Wavefront
|
4
4
|
#
|
5
5
|
# View and manage Cloud Integrations. These are identified by
|
6
6
|
# a UUID.
|
7
7
|
#
|
8
|
-
class CloudIntegration <
|
8
|
+
class CloudIntegration < CoreApi
|
9
9
|
# GET /api/v2/cloudintegration
|
10
10
|
# Get all cloud integrations for a customer
|
11
11
|
#
|
@@ -14,7 +14,7 @@ module Wavefront
|
|
14
14
|
# @return [Wavefront::Response]
|
15
15
|
#
|
16
16
|
def list(offset = 0, limit = 100)
|
17
|
-
|
17
|
+
api.get('', offset: offset, limit: limit)
|
18
18
|
end
|
19
19
|
|
20
20
|
# POST /api/v2/cloudintegration
|
@@ -26,7 +26,7 @@ module Wavefront
|
|
26
26
|
#
|
27
27
|
def create(body)
|
28
28
|
raise ArgumentError unless body.is_a?(Hash)
|
29
|
-
|
29
|
+
api.post('', body, 'application/json')
|
30
30
|
end
|
31
31
|
|
32
32
|
# DELETE /api/v2/cloudintegration/id
|
@@ -41,7 +41,7 @@ module Wavefront
|
|
41
41
|
#
|
42
42
|
def delete(id)
|
43
43
|
wf_cloudintegration_id?(id)
|
44
|
-
|
44
|
+
api.delete(id)
|
45
45
|
end
|
46
46
|
|
47
47
|
# GET /api/v2/cloudintegration/id
|
@@ -52,7 +52,7 @@ module Wavefront
|
|
52
52
|
#
|
53
53
|
def describe(id)
|
54
54
|
wf_cloudintegration_id?(id)
|
55
|
-
|
55
|
+
api.get(id)
|
56
56
|
end
|
57
57
|
|
58
58
|
# PUT /api/v2/cloudintegration/id
|
@@ -64,7 +64,7 @@ module Wavefront
|
|
64
64
|
def update(id, body)
|
65
65
|
wf_cloudintegration_id?(id)
|
66
66
|
raise ArgumentError unless body.is_a?(Hash)
|
67
|
-
|
67
|
+
api.put(id, body)
|
68
68
|
end
|
69
69
|
|
70
70
|
# POST /api/v2/cloudintegration/id/undelete
|
@@ -75,7 +75,7 @@ module Wavefront
|
|
75
75
|
#
|
76
76
|
def undelete(id)
|
77
77
|
wf_cloudintegration_id?(id)
|
78
|
-
|
78
|
+
api.post([id, 'undelete'].uri_concat)
|
79
79
|
end
|
80
80
|
end
|
81
81
|
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require_relative 'logger'
|
2
|
+
require_relative 'api_caller'
|
3
|
+
require_relative 'exception'
|
4
|
+
require_relative '../validators'
|
5
|
+
require_relative '../support/mixins'
|
6
|
+
|
7
|
+
module Wavefront
|
8
|
+
#
|
9
|
+
# Abstract class from which all API classes inherit. When you make
|
10
|
+
# any call to the Wavefront API from this SDK, you are returned an
|
11
|
+
# OpenStruct object.
|
12
|
+
#
|
13
|
+
# @return a Wavefront::Response object
|
14
|
+
#
|
15
|
+
class CoreApi
|
16
|
+
include Wavefront::Validators
|
17
|
+
include Wavefront::Mixins
|
18
|
+
attr_reader :api, :update_keys, :logger, :creds, :opts
|
19
|
+
|
20
|
+
# Create a new API object. This will always be called from a
|
21
|
+
# class which inherits this one. If the inheriting class defines
|
22
|
+
# #post_initialize, that method will be called afterwards, with
|
23
|
+
# the same arguments.
|
24
|
+
#
|
25
|
+
# @param creds [Hash] must contain the keys `endpoint` (the
|
26
|
+
# Wavefront API server) and `token`, the user token with which
|
27
|
+
# you wish to access the endpoint. Can optionally contain
|
28
|
+
# `agent`, which will become the `user-agent` string sent with
|
29
|
+
# all requests. Passed through to the ApiCaller class.
|
30
|
+
# @param opts [Hash] options governing class behaviour. Expected
|
31
|
+
# keys are `debug`, `noop` and `verbose`, all boolean; and
|
32
|
+
# `logger`, which must be a standard Ruby logger object. You
|
33
|
+
# can also pass :response_only. If this is true, you will only
|
34
|
+
# be returned a hash of the 'response' object returned by
|
35
|
+
# Wavefront. Passed through to the ApiCaller class.
|
36
|
+
# @return [Nil]
|
37
|
+
#
|
38
|
+
def initialize(creds = {}, opts = {})
|
39
|
+
@creds = creds
|
40
|
+
@opts = opts
|
41
|
+
@api = setup_api(creds, opts)
|
42
|
+
@s_api = setup_api(creds, opts)
|
43
|
+
@logger = Wavefront::Logger.new(opts)
|
44
|
+
post_initialize(creds, opts) if respond_to?(:post_initialize)
|
45
|
+
end
|
46
|
+
|
47
|
+
def setup_api(creds, opts)
|
48
|
+
Wavefront::ApiCaller.new(self, creds, opts)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Derive the first part of the API path from the class name. You
|
52
|
+
# can override this in your class if you wish. This method is
|
53
|
+
# called by the ApiCaller class.
|
54
|
+
#
|
55
|
+
# @return [String] portion of API URI
|
56
|
+
#
|
57
|
+
def api_base
|
58
|
+
self.class.name.split('::').last.downcase
|
59
|
+
end
|
60
|
+
|
61
|
+
# The API path is normally /api/v2/something, but not always.
|
62
|
+
# Override this method if not
|
63
|
+
#
|
64
|
+
def api_path
|
65
|
+
['', 'api', 'v2', api_base].uri_concat
|
66
|
+
end
|
67
|
+
|
68
|
+
# Convert an epoch timestamp into epoch milliseconds. If the
|
69
|
+
# timestamp looks like it's already epoch milliseconds, return
|
70
|
+
# it as-is.
|
71
|
+
#
|
72
|
+
# @param t [Integer] epoch timestamp
|
73
|
+
# @return [Ingeter] epoch millisecond timestamp
|
74
|
+
#
|
75
|
+
def time_to_ms(time)
|
76
|
+
return false unless time.is_a?(Integer)
|
77
|
+
return time if time.to_s.size == 13
|
78
|
+
(time.to_f * 1000).round
|
79
|
+
end
|
80
|
+
|
81
|
+
# doing a PUT to update an object requires only a certain subset of
|
82
|
+
# the keys returned by #describe(). This method takes the
|
83
|
+
# existing description of an object and turns it into a new has
|
84
|
+
# which can be PUT.
|
85
|
+
#
|
86
|
+
# @param old [Hash] a hash of the existing object
|
87
|
+
# @param new [Hash] the keys you wish to update
|
88
|
+
# @return [Hash] a hash containing only the keys which need to be
|
89
|
+
# sent to the API. Keys will be symbolized.
|
90
|
+
#
|
91
|
+
def hash_for_update(old, new)
|
92
|
+
raise ArgumentError unless old.is_a?(Hash) && new.is_a?(Hash)
|
93
|
+
|
94
|
+
Hash[old.merge(new).map { |k, v| [k.to_sym, v] }].select do |k, _v|
|
95
|
+
update_keys.include?(k)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,211 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'faraday'
|
3
|
+
require 'addressable'
|
4
|
+
require_relative 'response'
|
5
|
+
require_relative '../defs/version'
|
6
|
+
require_relative '../support/mixins'
|
7
|
+
|
8
|
+
module Wavefront
|
9
|
+
#
|
10
|
+
# Constructs and makes API calls to Wavefront.
|
11
|
+
#
|
12
|
+
class ApiCaller
|
13
|
+
include Wavefront::Mixins
|
14
|
+
|
15
|
+
attr_reader :opts, :noop, :debug, :verbose, :net, :logger,
|
16
|
+
:calling_class
|
17
|
+
|
18
|
+
# @param calling_class [
|
19
|
+
# @param creds [Hash] Wavefront credentials
|
20
|
+
# @param opts [Hash]
|
21
|
+
# @return [Nil]
|
22
|
+
#
|
23
|
+
def initialize(calling_class, creds = {}, opts = {})
|
24
|
+
@calling_class = calling_class
|
25
|
+
@opts = opts
|
26
|
+
setup_class_vars(opts)
|
27
|
+
setup_endpoint(creds)
|
28
|
+
end
|
29
|
+
|
30
|
+
def setup_class_vars(opts)
|
31
|
+
@logger = Wavefront::Logger.new(opts)
|
32
|
+
@noop = opts[:noop] || false
|
33
|
+
@verbose = opts[:verbose] || false
|
34
|
+
@debug = opts[:debug] || false
|
35
|
+
end
|
36
|
+
|
37
|
+
# Create a Faraday connection object. The server comes from the
|
38
|
+
# endpoint passed to the initializer in the 'creds' hash; the
|
39
|
+
# root of the URI is dynamically derived by the #setup_endpoint
|
40
|
+
# method.
|
41
|
+
#
|
42
|
+
# @param headers [Hash] additional headers
|
43
|
+
# @return [URI::HTTPS]
|
44
|
+
#
|
45
|
+
def mk_conn(path, headers = {})
|
46
|
+
url = format('%s://%s%s', net[:scheme], net[:endpoint],
|
47
|
+
[net[:api_base], path].uri_concat)
|
48
|
+
Faraday.new(url: Addressable::URI.encode(url),
|
49
|
+
headers: net[:headers].merge(headers))
|
50
|
+
end
|
51
|
+
|
52
|
+
# Make a GET call to the Wavefront API and return the result as
|
53
|
+
# a Ruby hash.
|
54
|
+
#
|
55
|
+
# @param path [String] path to be appended to the
|
56
|
+
# #net[:api_base] path.
|
57
|
+
# @param query [Hash] optional key-value pairs with will be made
|
58
|
+
# into aquery string
|
59
|
+
# @return [Hash] API response
|
60
|
+
#
|
61
|
+
def get(path, query = {})
|
62
|
+
make_call(mk_conn(path), :get, nil, query)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Make a POST call to the Wavefront API and return the result as
|
66
|
+
# a Ruby hash.
|
67
|
+
#
|
68
|
+
# @param path [String] path to be appended to the
|
69
|
+
# #net[:api_base] path.
|
70
|
+
# @param body [String,Object] optional body text to post.
|
71
|
+
# Objects will be converted to JSON
|
72
|
+
# @param ctype [String] the content type to use when posting
|
73
|
+
# @return [Hash] API response
|
74
|
+
#
|
75
|
+
def post(path, body = nil, ctype = 'text/plain')
|
76
|
+
body = body.to_json unless body.is_a?(String)
|
77
|
+
make_call(mk_conn(path, 'Content-Type': ctype,
|
78
|
+
'Accept': 'application/json'),
|
79
|
+
:post, nil, body)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Make a PUT call to the Wavefront API and return the result as
|
83
|
+
# a Ruby hash.
|
84
|
+
#
|
85
|
+
# @param path [String] path to be appended to the
|
86
|
+
# #net[:api_base] path.
|
87
|
+
# @param body [String] optional body text to post
|
88
|
+
# @param ctype [String] the content type to use when putting
|
89
|
+
# @return [Hash] API response
|
90
|
+
#
|
91
|
+
def put(path, body = nil, ctype = 'application/json')
|
92
|
+
make_call(mk_conn(path, 'Content-Type': ctype,
|
93
|
+
'Accept': 'application/json'),
|
94
|
+
:put, nil, body.to_json)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Make a DELETE call to the Wavefront API and return the result
|
98
|
+
# as a Ruby hash.
|
99
|
+
#
|
100
|
+
# @param path [String] path to be appended to the
|
101
|
+
# #net[:api_base] path.
|
102
|
+
# @return [Hash] API response
|
103
|
+
#
|
104
|
+
def delete(path)
|
105
|
+
make_call(mk_conn(path), :delete)
|
106
|
+
end
|
107
|
+
|
108
|
+
# If we need to massage a raw response to fit what the
|
109
|
+
# Wavefront::Response class expects (I'm looking at you,
|
110
|
+
# 'User'), a class can provide a {#response_shim} method.
|
111
|
+
#
|
112
|
+
def respond(resp)
|
113
|
+
body = if calling_class.respond_to?(:response_shim)
|
114
|
+
calling_class.response_shim(resp.body, resp.status)
|
115
|
+
else
|
116
|
+
resp.body
|
117
|
+
end
|
118
|
+
|
119
|
+
Wavefront::Response.new(body, resp.status, @opts)
|
120
|
+
end
|
121
|
+
|
122
|
+
# Try to describe the actual HTTP calls we make. There's a bit
|
123
|
+
# of clumsy guesswork here
|
124
|
+
#
|
125
|
+
def verbosity(conn, method, *args)
|
126
|
+
return unless noop || verbose
|
127
|
+
log format('uri: %s %s', method.upcase, conn.url_prefix)
|
128
|
+
|
129
|
+
return unless args.last && !args.last.empty?
|
130
|
+
|
131
|
+
log method == :get ? "params: #{args.last}" : "body: #{args.last}"
|
132
|
+
end
|
133
|
+
|
134
|
+
private
|
135
|
+
|
136
|
+
def paginator_class(method)
|
137
|
+
require_relative File.join('..', 'paginator', method.to_s)
|
138
|
+
Object.const_get(format('Wavefront::Paginator::%s',
|
139
|
+
method.to_s.capitalize))
|
140
|
+
end
|
141
|
+
|
142
|
+
# A dispatcher for making API calls. We now have three methods
|
143
|
+
# that do the real call, two of which live inside the requisite
|
144
|
+
# Wavefront::Paginator class
|
145
|
+
# @raise [Faraday::ConnectionFailed] if cannot connect to
|
146
|
+
# endpoint
|
147
|
+
#
|
148
|
+
def make_call(conn, method, *args)
|
149
|
+
verbosity(conn, method, *args)
|
150
|
+
return if noop
|
151
|
+
|
152
|
+
paginator = paginator_class(method).new(self, conn, method, *args)
|
153
|
+
|
154
|
+
case paginator.initial_limit
|
155
|
+
when :all, 'all'
|
156
|
+
paginator.make_recursive_call
|
157
|
+
when :lazy, 'lazy'
|
158
|
+
paginator.make_lazy_call
|
159
|
+
else
|
160
|
+
make_single_call(conn, method, *args)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def make_single_call(conn, method, *args)
|
165
|
+
resp = conn.public_send(method, *args)
|
166
|
+
|
167
|
+
if debug
|
168
|
+
require 'pp'
|
169
|
+
pp resp
|
170
|
+
end
|
171
|
+
|
172
|
+
respond(resp)
|
173
|
+
end
|
174
|
+
|
175
|
+
def setup_endpoint(creds)
|
176
|
+
validate_credentials(creds)
|
177
|
+
|
178
|
+
unless creds.key?(:agent) && creds[:agent]
|
179
|
+
creds[:agent] = "wavefront-sdk #{WF_SDK_VERSION}"
|
180
|
+
end
|
181
|
+
|
182
|
+
@net = { headers: headers(creds),
|
183
|
+
scheme: opts[:scheme] || 'https',
|
184
|
+
endpoint: creds[:endpoint],
|
185
|
+
api_base: calling_class.api_path }
|
186
|
+
end
|
187
|
+
|
188
|
+
def headers(creds)
|
189
|
+
ret = { 'user-agent': creds[:agent] }
|
190
|
+
ret[:Authorization] = "Bearer #{creds[:token]}" if creds[:token]
|
191
|
+
ret
|
192
|
+
end
|
193
|
+
|
194
|
+
def validate_credentials(creds)
|
195
|
+
if calling_class.respond_to?(:validate_credentials)
|
196
|
+
calling_class.validate_credentials(creds)
|
197
|
+
else
|
198
|
+
_validate_credentials(creds)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def _validate_credentials(creds)
|
203
|
+
%w[endpoint token].each do |k|
|
204
|
+
unless creds.key?(k.to_sym)
|
205
|
+
raise(Wavefront::Exception::CredentialError,
|
206
|
+
format('credentials must contain %s', k))
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
@@ -5,41 +5,46 @@ module Wavefront
|
|
5
5
|
class Exception
|
6
6
|
class CredentialError < RuntimeError; end
|
7
7
|
class EmptyMetricName < RuntimeError; end
|
8
|
+
class EnumerableError < RuntimeError; end
|
8
9
|
class InvalidAlertId < RuntimeError; end
|
9
10
|
class InvalidAlertSeverity < RuntimeError; end
|
10
11
|
class InvalidCloudIntegrationId < RuntimeError; end
|
11
12
|
class InvalidDashboardId < RuntimeError; end
|
12
13
|
class InvalidDerivedMetricId < RuntimeError; end
|
14
|
+
class InvalidDistribution < RuntimeError; end
|
15
|
+
class InvalidDistributionInterval < RuntimeError; end
|
16
|
+
class InvalidDistributionCount < RuntimeError; end
|
13
17
|
class InvalidEndpoint < RuntimeError; end
|
14
18
|
class InvalidEventId < RuntimeError; end
|
15
19
|
class InvalidExternalLinkId < RuntimeError; end
|
16
20
|
class InvalidGranularity < RuntimeError; end
|
17
21
|
class InvalidHostname < RuntimeError; end
|
18
22
|
class InvalidIntegrationId < RuntimeError; end
|
19
|
-
class
|
20
|
-
class InvalidTimeUnit < RuntimeError; end
|
23
|
+
class InvalidLinkTemplate < RuntimeError; end
|
21
24
|
class InvalidMaintenanceWindowId < RuntimeError; end
|
22
25
|
class InvalidMessageId < RuntimeError; end
|
23
26
|
class InvalidMetricName < RuntimeError; end
|
24
27
|
class InvalidMetricValue < RuntimeError; end
|
25
|
-
class InvalidNotificantId < RuntimeError; end
|
26
28
|
class InvalidName < RuntimeError; end
|
29
|
+
class InvalidNotificantId < RuntimeError; end
|
27
30
|
class InvalidPoint < RuntimeError; end
|
28
31
|
class InvalidPrefixLength < RuntimeError; end
|
29
32
|
class InvalidProxyId < RuntimeError; end
|
30
|
-
class
|
33
|
+
class InvalidRelativeTime < RuntimeError; end
|
31
34
|
class InvalidSavedSearchEntity < RuntimeError; end
|
35
|
+
class InvalidSavedSearchId < RuntimeError; end
|
32
36
|
class InvalidSourceId < RuntimeError; end
|
33
37
|
class InvalidString < RuntimeError; end
|
34
38
|
class InvalidTag < RuntimeError; end
|
35
|
-
class InvalidLinkTemplate < RuntimeError; end
|
36
39
|
class InvalidTimeFormat < RuntimeError; end
|
40
|
+
class InvalidTimeUnit < RuntimeError; end
|
37
41
|
class InvalidTimestamp < RuntimeError; end
|
38
42
|
class InvalidUserId < RuntimeError; end
|
39
|
-
class InvalidWebhookId < RuntimeError; end
|
40
43
|
class InvalidVersion < RuntimeError; end
|
44
|
+
class InvalidWebhookId < RuntimeError; end
|
41
45
|
class NotImplemented < RuntimeError; end
|
42
46
|
class UnparseableResponse < RuntimeError; end
|
47
|
+
class UnsupportedWriter < RuntimeError; end
|
43
48
|
class ValueOutOfRange < RuntimeError; end
|
44
49
|
end
|
45
50
|
end
|
@@ -1,7 +1,9 @@
|
|
1
1
|
require 'json'
|
2
2
|
require 'map'
|
3
|
+
require_relative 'logger'
|
3
4
|
require_relative 'exception'
|
4
|
-
require_relative '
|
5
|
+
require_relative '../types/status'
|
6
|
+
require_relative '../support/mixins'
|
5
7
|
|
6
8
|
module Wavefront
|
7
9
|
#
|
@@ -32,13 +34,10 @@ module Wavefront
|
|
32
34
|
# has changed underneath us.
|
33
35
|
#
|
34
36
|
def initialize(json, status, opts = {})
|
37
|
+
setup_vars(opts)
|
35
38
|
raw = raw_response(json, status)
|
36
39
|
@status = build_status(raw, status)
|
37
40
|
@response = build_response(raw)
|
38
|
-
@opts = opts
|
39
|
-
|
40
|
-
setup_opts
|
41
|
-
|
42
41
|
logger.log(self, :debug)
|
43
42
|
rescue StandardError => e
|
44
43
|
logger.log(format("could not parse:\n%s", json), :debug)
|
@@ -46,69 +45,87 @@ module Wavefront
|
|
46
45
|
raise Wavefront::Exception::UnparseableResponse
|
47
46
|
end
|
48
47
|
|
49
|
-
|
50
|
-
|
48
|
+
# Were there items in the response?
|
49
|
+
#
|
50
|
+
def empty?
|
51
|
+
response.items.size.zero?
|
52
|
+
rescue StandardError
|
53
|
+
false
|
51
54
|
end
|
52
55
|
|
53
|
-
|
54
|
-
|
56
|
+
# Was the API's response positive?
|
57
|
+
# @return [Bool]
|
58
|
+
#
|
59
|
+
def ok?
|
60
|
+
respond_to?(:status) && status.result == 'OK'
|
61
|
+
end
|
62
|
+
|
63
|
+
# Are there more items in paginated output?
|
64
|
+
# @return [Bool]
|
65
|
+
#
|
66
|
+
def more_items?
|
67
|
+
return false unless response.key?(:moreItems)
|
68
|
+
!!response.moreItems
|
69
|
+
end
|
70
|
+
|
71
|
+
# On paginated output, the offset of the next item, or nil.
|
72
|
+
# @return [Integer, Nil]
|
73
|
+
#
|
74
|
+
def next_item
|
75
|
+
return nil unless more_items?
|
76
|
+
reponse.offset + response.limit
|
55
77
|
rescue StandardError
|
56
|
-
|
78
|
+
nil
|
57
79
|
end
|
58
80
|
|
59
|
-
|
60
|
-
|
81
|
+
# A printable version of a Wavefront::Response object
|
82
|
+
# @return [String]
|
83
|
+
#
|
84
|
+
def to_s
|
85
|
+
inspect.to_s
|
61
86
|
end
|
62
87
|
|
88
|
+
# We often want the IDs of all the objects we retrieved. This
|
89
|
+
# does it.
|
90
|
+
|
91
|
+
def ids
|
92
|
+
response.items.map(&:id)
|
93
|
+
end
|
94
|
+
|
95
|
+
# We often want the names of all the objects we retrieved.
|
96
|
+
#
|
97
|
+
def names
|
98
|
+
response.items.map(&:name)
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
def setup_vars(opts)
|
104
|
+
@opts = opts
|
105
|
+
@logger = Wavefront::Logger.new(opts)
|
106
|
+
end
|
107
|
+
|
108
|
+
# @params raw [Hash] created by #raw_response
|
109
|
+
#
|
63
110
|
def build_response(raw)
|
64
111
|
return Map.new unless raw.is_a?(Hash)
|
65
112
|
return Map.new(raw) unless raw.key?(:response)
|
66
113
|
return raw[:response] unless raw[:response].is_a?(Hash)
|
67
114
|
Map(raw[:response])
|
68
115
|
end
|
69
|
-
end
|
70
116
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
#
|
75
|
-
# An object which provides information about whether the request
|
76
|
-
# was successful or not. Ordinarily this is easy to construct
|
77
|
-
# from the API's JSON response, but some classes, for instance
|
78
|
-
# Wavefront::Write fake it by constructing their own.
|
79
|
-
#
|
80
|
-
# @!attribute [r] result
|
81
|
-
# @return [OK, ERROR] a string telling us how the request went
|
82
|
-
# @!attribute [r] message
|
83
|
-
# @return [String] Any informational message from the API
|
84
|
-
# @!attribute [r] code
|
85
|
-
# @return [Integer] the HTTP response code from the API
|
86
|
-
# request
|
117
|
+
# Turn the API's JSON response and HTTP status code into a Ruby
|
118
|
+
# object.
|
119
|
+
# @return [Hash]
|
87
120
|
#
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
#
|
94
|
-
def initialize(response, status)
|
95
|
-
@obj = response.fetch(:status, response)
|
96
|
-
@status = status
|
97
|
-
end
|
98
|
-
|
99
|
-
def message
|
100
|
-
obj[:message] || nil
|
101
|
-
end
|
102
|
-
|
103
|
-
def code
|
104
|
-
obj[:code] || status
|
105
|
-
end
|
121
|
+
def raw_response(json, status)
|
122
|
+
json.empty? ? {} : JSON.parse(json, symbolize_names: true)
|
123
|
+
rescue StandardError
|
124
|
+
{ message: json, code: status }
|
125
|
+
end
|
106
126
|
|
107
|
-
|
108
|
-
|
109
|
-
return 'OK' if status.between?(200, 299)
|
110
|
-
'ERROR'
|
111
|
-
end
|
127
|
+
def build_status(raw, status)
|
128
|
+
Wavefront::Type::Status.new(raw, status)
|
112
129
|
end
|
113
130
|
end
|
114
131
|
end
|