wavefront-sdk 3.0.2 → 3.2.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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/HISTORY.md +12 -1
  3. data/README.md +4 -0
  4. data/Rakefile +1 -0
  5. data/lib/wavefront-sdk/alert.rb +36 -49
  6. data/lib/wavefront-sdk/api_mixins/acl.rb +76 -0
  7. data/lib/wavefront-sdk/api_mixins/tag.rb +62 -0
  8. data/lib/wavefront-sdk/api_mixins/user.rb +26 -0
  9. data/lib/wavefront-sdk/apitoken.rb +49 -0
  10. data/lib/wavefront-sdk/core/exception.rb +1 -0
  11. data/lib/wavefront-sdk/dashboard.rb +6 -106
  12. data/lib/wavefront-sdk/defs/version.rb +1 -1
  13. data/lib/wavefront-sdk/derivedmetric.rb +6 -56
  14. data/lib/wavefront-sdk/event.rb +4 -50
  15. data/lib/wavefront-sdk/paginator/base.rb +8 -7
  16. data/lib/wavefront-sdk/paginator/post.rb +7 -5
  17. data/lib/wavefront-sdk/source.rb +4 -48
  18. data/lib/wavefront-sdk/user.rb +2 -2
  19. data/lib/wavefront-sdk/usergroup.rb +2 -2
  20. data/lib/wavefront-sdk/validators.rb +10 -0
  21. data/lib/wavefront-sdk/write.rb +43 -12
  22. data/lib/wavefront-sdk/writers/socket.rb +2 -2
  23. data/spec/.rubocop.yml +1 -1
  24. data/spec/spec_helper.rb +66 -0
  25. data/spec/wavefront-sdk/alert_spec.rb +14 -0
  26. data/spec/wavefront-sdk/{support → api_mixins}/user_mixins_spec.rb +2 -2
  27. data/spec/wavefront-sdk/apitoken_spec.rb +31 -0
  28. data/spec/wavefront-sdk/core/api_spec.rb +3 -5
  29. data/spec/wavefront-sdk/credentials_spec.rb +41 -37
  30. data/spec/wavefront-sdk/dashboard_spec.rb +4 -52
  31. data/spec/wavefront-sdk/distribution_spec.rb +1 -3
  32. data/spec/wavefront-sdk/metric_helper_spec.rb +6 -8
  33. data/spec/wavefront-sdk/report_spec.rb +2 -2
  34. data/spec/wavefront-sdk/stdlib/array_spec.rb +6 -6
  35. data/spec/wavefront-sdk/stdlib/hash_spec.rb +5 -5
  36. data/spec/wavefront-sdk/support/mixins_spec.rb +34 -36
  37. data/spec/wavefront-sdk/support/parse_time_spec.rb +25 -29
  38. data/spec/wavefront-sdk/usergroup_spec.rb +34 -34
  39. data/spec/wavefront-sdk/validators_spec.rb +10 -1
  40. data/spec/wavefront-sdk/write_spec.rb +71 -4
  41. data/spec/wavefront-sdk/writers/core_spec.rb +10 -10
  42. data/spec/wavefront-sdk/writers/socket_spec.rb +13 -1
  43. metadata +10 -5
  44. data/lib/wavefront-sdk/support/user_mixins.rb +0 -24
@@ -1,4 +1,4 @@
1
1
  require 'pathname'
2
2
 
3
- WF_SDK_VERSION = '3.0.2'.freeze
3
+ WF_SDK_VERSION = '3.2.0'.freeze
4
4
  WF_SDK_LOCATION = Pathname.new(__FILE__).dirname.parent.parent.parent
@@ -1,13 +1,12 @@
1
1
  require_relative 'core/api'
2
+ require_relative 'api_mixins/tag'
2
3
 
3
4
  module Wavefront
4
5
  #
5
6
  # View and manage derived metrics
6
7
  #
7
8
  class DerivedMetric < CoreApi
8
- def update_keys
9
- # %i[id name url description sections]
10
- end
9
+ include Wavefront::Mixin::Tag
11
10
 
12
11
  # GET /api/v2/derivedmetric
13
12
  # Get all derived metric definitions for a customer.
@@ -94,59 +93,6 @@ module Wavefront
94
93
  api.get([id, 'history'].uri_concat)
95
94
  end
96
95
 
97
- # GET /api/v2/derivedmetric/id/tag
98
- # Get all tags associated with a specific derived metric
99
- # definition.
100
- #
101
- # @param id [String] ID of the derived metric
102
- # @return [Wavefront::Response]
103
- #
104
- def tags(id)
105
- wf_derivedmetric_id?(id)
106
- api.get([id, 'tag'].uri_concat)
107
- end
108
-
109
- # POST /api/v2/derivedmetric/id/tag
110
- # Set all tags associated with a specific derived metric
111
- # definition.
112
- #
113
- # @param id [String] ID of the derived metric
114
- # @param tags [Array] list of tags to set.
115
- # @return [Wavefront::Response]
116
- #
117
- def tag_set(id, tags)
118
- wf_derivedmetric_id?(id)
119
- tags = Array(tags)
120
- tags.each { |t| wf_string?(t) }
121
- api.post([id, 'tag'].uri_concat, tags.to_json, 'application/json')
122
- end
123
-
124
- # DELETE /api/v2/derivedmetric/id/tag/tagValue
125
- # Remove a tag from a specific derived metric definition.
126
- #
127
- # @param id [String] ID of the derived metric
128
- # @param tag [String] tag to delete
129
- # @return [Wavefront::Response]
130
- #
131
- def tag_delete(id, tag)
132
- wf_derivedmetric_id?(id)
133
- wf_string?(tag)
134
- api.delete([id, 'tag', tag].uri_concat)
135
- end
136
-
137
- # PUT /api/v2/derivedmetric/id/tag/tagValue
138
- # Add a tag to a specific derived metric definition.
139
- #
140
- # @param id [String] ID of the derived metric
141
- # @param tag [String] tag to set.
142
- # @return [Wavefront::Response]
143
- #
144
- def tag_add(id, tag)
145
- wf_derivedmetric_id?(id)
146
- wf_string?(tag)
147
- api.put([id, 'tag', tag].uri_concat)
148
- end
149
-
150
96
  # POST /api/v2/derivedmetric/id/undelete
151
97
  # Move a derived metric definition from 'trash' back into active
152
98
  # service.
@@ -158,5 +104,9 @@ module Wavefront
158
104
  wf_derivedmetric_id?(id)
159
105
  api.post([id, 'undelete'].uri_concat)
160
106
  end
107
+
108
+ def valid_id?(id)
109
+ wf_derivedmetric_id?(id)
110
+ end
161
111
  end
162
112
  end
@@ -1,4 +1,5 @@
1
1
  require_relative 'core/api'
2
+ require_relative 'api_mixins/tag'
2
3
 
3
4
  module Wavefront
4
5
  #
@@ -6,6 +7,8 @@ module Wavefront
6
7
  # epoch timestamp.
7
8
  #
8
9
  class Event < CoreApi
10
+ include Wavefront::Mixin::Tag
11
+
9
12
  def update_keys
10
13
  %i[startTime endTime name annotations]
11
14
  end
@@ -115,57 +118,8 @@ module Wavefront
115
118
  api.post([id, 'close'].uri_concat)
116
119
  end
117
120
 
118
- # GET /api/v2/event/id/tag
119
- # Get all tags associated with a specific event
120
- #
121
- # @param id [String] ID of the event
122
- # @return [Wavefront::Response]
123
- # response keys
124
- #
125
- def tags(id)
126
- wf_event_id?(id)
127
- api.get([id, 'tag'].uri_concat)
128
- end
129
-
130
- # POST /api/v2/event/id/tag
131
- # Set all tags associated with a specific event.
132
- #
133
- # @param id [String] ID of the event
134
- # @param tags [Array] list of tags to set.
135
- # @return [Wavefront::Response]
136
- # response keys
137
- #
138
- def tag_set(id, tags)
139
- wf_event_id?(id)
140
- tags = Array(tags)
141
- tags.each { |t| wf_string?(t) }
142
- api.post([id, 'tag'].uri_concat, tags, 'application/json')
143
- end
144
-
145
- # DELETE /api/v2/event/id/tag/tagValue
146
- # Remove a tag from a specific event.
147
- #
148
- # @param id [String] ID of the event
149
- # @param tag [String] tag to delete
150
- # @return [Wavefront::Response]
151
- #
152
- def tag_delete(id, tag)
153
- wf_event_id?(id)
154
- wf_string?(tag)
155
- api.delete([id, 'tag', tag].uri_concat)
156
- end
157
-
158
- # PUT /api/v2/event/id/tag/tagValue
159
- # Add a tag to a specific event.
160
- #
161
- # @param id [String] ID of the event
162
- # @param tag [String] tag to set.
163
- # @return [Wavefront::Response]
164
- #
165
- def tag_add(id, tag)
121
+ def valid_id?(id)
166
122
  wf_event_id?(id)
167
- wf_string?(tag)
168
- api.put([id, 'tag', tag].uri_concat)
169
123
  end
170
124
  end
171
125
  end
@@ -80,13 +80,14 @@ module Wavefront
80
80
  #
81
81
  def set_pagination(offset, page_size, args)
82
82
  args.map do |arg|
83
- if arg.is_a?(Hash)
84
- arg.tap do |a|
85
- a[:limit] = page_size if a.key?(:limit)
86
- a[:offset] = offset if a.key?(:offset)
87
- end
88
- end
89
- arg
83
+ arg.is_a?(Hash) ? set_limit_and_offset(arg, page_size, offset) : arg
84
+ end
85
+ end
86
+
87
+ def set_limit_and_offset(arg, page_size, offset)
88
+ arg.tap do |a|
89
+ a[:limit] = page_size if a.key?(:limit)
90
+ a[:offset] = offset if a.key?(:offset)
90
91
  end
91
92
  end
92
93
 
@@ -50,15 +50,17 @@ module Wavefront
50
50
 
51
51
  return args if body.class == desired
52
52
 
53
- args[index] = if body.is_a?(String)
54
- JSON.parse(body, symbolize_names: true)
55
- else
56
- body.to_json
57
- end
53
+ args[index] = body_as_json(body)
58
54
  args
59
55
  rescue JSON::ParserError
60
56
  []
61
57
  end
58
+
59
+ def body_as_json(body)
60
+ return body.to_json unless body.is_a?(String)
61
+
62
+ JSON.parse(body, symbolize_names: true)
63
+ end
62
64
  end
63
65
  end
64
66
  end
@@ -1,10 +1,13 @@
1
1
  require_relative 'core/api'
2
+ require_relative 'api_mixins/tag'
2
3
 
3
4
  module Wavefront
4
5
  #
5
6
  # View and manage source metadata.
6
7
  #
7
8
  class Source < CoreApi
9
+ include Wavefront::Mixin::Tag
10
+
8
11
  def update_keys
9
12
  %i[sourceName tags description]
10
13
  end
@@ -100,55 +103,8 @@ module Wavefront
100
103
  'application/json')
101
104
  end
102
105
 
103
- # GET /api/v2/source/id/tag
104
- # Get all tags associated with a specific source.
105
- #
106
- # @param id [String] ID of the source
107
- # @return [Wavefront::Response]
108
- #
109
- def tags(id)
110
- wf_source_id?(id)
111
- api.get([id, 'tag'].uri_concat)
112
- end
113
-
114
- # POST /api/v2/source/id/tag
115
- # Set all tags associated with a specific source.
116
- #
117
- # @param id [String] ID of the source
118
- # @param tags [Array] list of tags to set.
119
- # @return [Wavefront::Response]
120
- #
121
- def tag_set(id, tags)
122
- wf_source_id?(id)
123
- tags = Array(tags)
124
- tags.each { |t| wf_string?(t) }
125
- api.post([id, 'tag'].uri_concat, tags.to_json, 'application/json')
126
- end
127
-
128
- # DELETE /api/v2/source/id/tag/tagValue
129
- # Remove a tag from a specific source.
130
- #
131
- # @param id [String] ID of the source
132
- # @param tag [String] tag to delete
133
- # @return [Wavefront::Response]
134
- #
135
- def tag_delete(id, tag)
136
- wf_source_id?(id)
137
- wf_string?(tag)
138
- api.delete([id, 'tag', tag].uri_concat)
139
- end
140
-
141
- # PUT /api/v2/source/id/tag/tagValue
142
- # Add a tag to a specific source
143
- #
144
- # @param id [String] ID of the source
145
- # @param tag [String] tag to set.
146
- # @return [Wavefront::Response]
147
- #
148
- def tag_add(id, tag)
106
+ def valid_id?(id)
149
107
  wf_source_id?(id)
150
- wf_string?(tag)
151
- api.put([id, 'tag', tag].uri_concat)
152
108
  end
153
109
  end
154
110
  end
@@ -1,12 +1,12 @@
1
1
  require_relative 'core/api'
2
- require_relative 'support/user_mixins'
2
+ require_relative 'api_mixins/user'
3
3
 
4
4
  module Wavefront
5
5
  #
6
6
  # Manage and query Wavefront users
7
7
  #
8
8
  class User < CoreApi
9
- include Wavefront::UserMixins
9
+ include Wavefront::Mixin::User
10
10
 
11
11
  # GET /api/v2/user
12
12
  # Get all users.
@@ -1,12 +1,12 @@
1
1
  require_relative 'core/api'
2
- require_relative 'support/user_mixins'
2
+ require_relative 'api_mixins/user'
3
3
 
4
4
  module Wavefront
5
5
  #
6
6
  # Manage and query Wavefront user groups
7
7
  #
8
8
  class UserGroup < CoreApi
9
- include Wavefront::UserMixins
9
+ include Wavefront::Mixin::User
10
10
 
11
11
  def update_keys
12
12
  %i[id name]
@@ -502,6 +502,16 @@ module Wavefront
502
502
  return true if count.is_a?(Integer) && count.positive?
503
503
  raise Wavefront::Exception::InvalidDistributionCount
504
504
  end
505
+
506
+ # Ensure the given argument is a valid API token ID
507
+ # @param id [String]
508
+ # @raise Wavefront::Exception::InvalidApiTokenId if the
509
+ # count is not valid
510
+ #
511
+ def wf_apitoken_id?(id)
512
+ return true if uuid?(id)
513
+ raise Wavefront::Exception::InvalidApiTokenId
514
+ end
505
515
  end
506
516
  # rubocop:enable Metrics/ModuleLength
507
517
  end
@@ -1,6 +1,7 @@
1
1
  require 'socket'
2
2
  require_relative 'core/exception'
3
3
  require_relative 'core/logger'
4
+ require_relative 'core/response'
4
5
  require_relative 'defs/constants'
5
6
  require_relative 'validators'
6
7
 
@@ -40,16 +41,14 @@ module Wavefront
40
41
  # noauto [Bool] if this is false, #write will automatically
41
42
  # open a connection to Wavefront on each invocation. Set
42
43
  # this to true to manually manage the connection.
44
+ # chunk_size [Integer] So as not to create unusable metric
45
+ # payloads, large batches of points will be broken into
46
+ # chunks. This property controls the number of metrics in a
47
+ # chunk. Defaults to 1,000.
48
+ # chunk_pause [Integer] pause this many seconds between
49
+ # writing chunks. Defaults to zero.
43
50
  #
44
51
  def initialize(creds = {}, opts = {})
45
- defaults = { tags: nil,
46
- writer: :socket,
47
- noop: false,
48
- novalidate: false,
49
- noauto: false,
50
- verbose: false,
51
- debug: false }
52
-
53
52
  @opts = setup_options(opts, defaults)
54
53
  @creds = creds
55
54
  wf_point_tags?(opts[:tags]) if opts[:tags]
@@ -57,6 +56,18 @@ module Wavefront
57
56
  @writer = setup_writer
58
57
  end
59
58
 
59
+ def defaults
60
+ { tags: nil,
61
+ writer: :socket,
62
+ noop: false,
63
+ novalidate: false,
64
+ noauto: false,
65
+ verbose: false,
66
+ debug: false,
67
+ chunk_size: 1000,
68
+ chunk_pause: 0 }
69
+ end
70
+
60
71
  def setup_options(user, defaults)
61
72
  defaults.merge(user)
62
73
  end
@@ -78,15 +89,35 @@ module Wavefront
78
89
  # Writers implement this method differently, Check the
79
90
  # appropriate class documentation for @return information etc.
80
91
  # The signature is always the same.
92
+ # @return [Boolean] false should any chunk fail
93
+ # @raise any exceptions raised by the writer classes are passed
94
+ # through
81
95
  #
82
96
  def write(points = [], openclose = manage_conn, prefix = nil)
83
- writer.write(points, openclose, prefix)
97
+ resps = [points].flatten.each_slice(opts[:chunk_size]).map do |chunk|
98
+ resp = writer.write(chunk, openclose, prefix)
99
+ sleep(opts[:chunk_pause])
100
+ resp
101
+ end
102
+
103
+ composite_response(resps)
84
104
  end
85
105
 
86
- # Wrapper around writer class's #flush method
106
+ # Compound the responses of all chunked writes into one. It will
107
+ # be 'ok' only if *everything* passed.
87
108
  #
88
- def flush
89
- writer.flush
109
+ def composite_response(responses)
110
+ result = responses.all?(&:ok?) ? 'OK' : 'ERROR'
111
+ summary = { sent: 0, rejected: 0, unsent: 0 }
112
+
113
+ %i[sent rejected unsent].each do |k|
114
+ summary[k] = responses.map { |r| r.response[k] }.inject(:+)
115
+ end
116
+
117
+ Wavefront::Response.new(
118
+ { status: { result: result, message: nil, code: nil },
119
+ response: summary.to_h }.to_json, nil
120
+ )
90
121
  end
91
122
 
92
123
  def manage_conn
@@ -49,11 +49,11 @@ module Wavefront
49
49
 
50
50
  private
51
51
 
52
- # @param point [String] point or points in native Wavefront
53
- # format.
52
+ # @param point [String] point or points in native Wavefront format.
54
53
  # @raise [SocketError] if point cannot be written
55
54
  #
56
55
  def _send_point(point)
56
+ return if opts[:noop]
57
57
  conn.puts(point)
58
58
  rescue StandardError
59
59
  raise Wavefront::Exception::SocketError
data/spec/.rubocop.yml CHANGED
@@ -11,7 +11,7 @@ Metrics/MethodLength:
11
11
  Max: 80
12
12
 
13
13
  Metrics/AbcSize:
14
- Max: 45
14
+ Max: 80
15
15
 
16
16
  Metrics/ClassLength:
17
17
  Max: 300