wavefront-sdk 1.6.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|