hawkular-client 4.1.0 → 5.0.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6d77d09316e981da7ac6e3b388086113d124edd8
4
- data.tar.gz: b68cd6c87554d6277d2f3f58c2ed58d7af667b51
3
+ metadata.gz: 9ce43741f3e66c655f0d1c559576dad7296a8e32
4
+ data.tar.gz: 70e51c3bed465d9ce434b4eef252722c8afff244
5
5
  SHA512:
6
- metadata.gz: 401153f15fb3a7fb00414e9febdb8499521338607dd473880ff66dfca8c742b7f613f4517126210d6991dbf4f91478c2ad3a111ea0629e680978755b94707d1b
7
- data.tar.gz: f90f8cc4c20d36967403fca69d68c438b7166deb11637c0daf72e375712e6db1527b2bb9bda777f29db7f3f68308ebfbe0cdc75c4355408189e6f41847f28400
6
+ metadata.gz: 78e7755e7ecb8ec09c31c59758302a3cf5ce76d302fe7dadfb71f226a91ad81db7b7a33829c6edf7ebdecf7f346b03c31975725e86d424a160b23f70ce15dcab
7
+ data.tar.gz: 571f341fef1bff183163ecd58027d1e8cfc81b4c94e68cb2f21aaffbf877098c2d5e68728dd3f2b3b93a860255acf8502d2c1da0d7b34dd3859dc1ec1051c3b7
@@ -3,6 +3,20 @@
3
3
  This document describes the relevant changes between releases of the
4
4
  _hawkular-client_ project.
5
5
 
6
+ === v 5.0.0.pre1
7
+ * Hawkular services version 0.40.x and Hawkular Agent 1.x will be the last
8
+ versions to include support for _inventory-on-metrics_ and Hawkular Metrics.
9
+ The following versions won't be backwards compatible. Right now, a new API
10
+ for inventory is already implemented. This pre-release of the client is
11
+ adding support for this new inventory API and removing all support for the
12
+ previous implementation. See link:api_breaking_changes.rdoc for more details.
13
+ * Because of the new inventory implementation, the _Operations_ client requires
14
+ the feed id to be sent on all operations. See link:api_breaking_changes.rdoc
15
+ for more details.
16
+ * Support for a _sender_request_id_ has been added to the _Operations_ client.
17
+ This allows to match operation requests with their respective operation result
18
+ websocket messages.
19
+
6
20
  === v 4.1.0
7
21
  * Fixed binary data handling when invoking <em>Export JDR</em> on operations API.
8
22
  * Added <em>delete_immediately</em> parameter to <em>Export JDR</em> operation.
@@ -3,6 +3,7 @@ require 'addressable/uri'
3
3
 
4
4
  require 'hawkular/logger'
5
5
  require 'hawkular/client_utils'
6
+ require 'erb'
6
7
 
7
8
  module Hawkular
8
9
  # This is the base functionality for all the clients,
@@ -40,6 +41,10 @@ module Hawkular
40
41
  fail Hawkular::ArgumentError, 'You need to provide an entrypoint' if entrypoint.nil?
41
42
  end
42
43
 
44
+ def url(url_format, *params)
45
+ url_format % params.map { |p| ERB::Util.url_encode(p) }
46
+ end
47
+
43
48
  def http_get(suburl, headers = {})
44
49
  res = rest_client(suburl).get(http_headers(headers))
45
50
 
@@ -34,7 +34,7 @@ module Hawkular
34
34
  end
35
35
 
36
36
  def inventory
37
- @inventory ||= Inventory::Client.new("#{@state[:entrypoint]}/hawkular/metrics",
37
+ @inventory ||= Inventory::Client.new("#{@state[:entrypoint]}/hawkular/inventory",
38
38
  @state[:credentials],
39
39
  @state[:options])
40
40
  end
@@ -1,308 +1,134 @@
1
1
  # It contains class definitions that are used by the inventory REST client
2
2
  module Hawkular::Inventory
3
- # A Basic inventory entity with id, name, path and optional properties
4
- class BaseEntity
5
- # @return [String] Full path of the entity
6
- attr_reader :path
7
- # @return [String] Name of the entity
3
+ class Metric
4
+ # @return [String] Name of the metric
8
5
  attr_reader :name
9
- # @return [String] Id of the entity
10
- attr_reader :id
11
- # @return [String] Feed this entity belongs to (or nil in case of a feedless entity)
12
- attr_reader :feed
13
- # @return [String] Name of the environment for this entity
14
- attr_reader :env
15
- # @return [String] Properties of this entity
6
+ # @return [String] Type of the metric
7
+ attr_reader :type
8
+ # @return [String] Unit of the metric
9
+ attr_reader :unit
10
+ # @return [Hash<String,String>] Properties of this metric
16
11
  attr_reader :properties
17
12
 
18
13
  def initialize(hash)
19
- @id = hash['id']
20
- @path = hash['path']
21
- @name = hash['name'] || @id
14
+ @name = hash['name']
15
+ @type = hash['type']
16
+ @unit = hash['unit']
22
17
  @properties = hash['properties'] || {}
23
- @_hash = hash.dup
24
-
25
- return if @path.nil?
26
-
27
- tmp = @path.split('/')
28
- tmp.each do |pair|
29
- (key, val) = pair.split(';')
30
- case key
31
- when 'f'
32
- @feed = val
33
- when 'e'
34
- @env = val
35
- end
36
- end
37
- end
38
-
39
- def ==(other)
40
- self.equal?(other) || other.class == self.class && other.id == @id
41
- end
42
-
43
- # Returns a hash representation of the resource type
44
- # @return [Hash<String,Object>] hash of the type
45
- def to_h
46
- @_hash.dup
47
- end
48
- end
49
-
50
- # A ResourceType is like a class definition for {Resource}s
51
- # ResourceTypes are currently unique per feed, but one can assume
52
- # that a two types with the same name of two different feeds are
53
- # (more or less) the same.
54
- class ResourceType < BaseEntity
55
- def initialize(rt_hash)
56
- super(rt_hash)
57
18
  end
58
- end
59
19
 
60
- # A Resource is an instantiation of a {ResourceType}
61
- class Resource < BaseEntity
62
- # @return [String] Full path of the {ResourceType}
63
- attr_reader :type_path
64
-
65
- def initialize(res_hash)
66
- super(res_hash)
67
- if res_hash.key? :resourceTypePath
68
- @type_path = res_hash[:resourceTypePath]
69
- elsif res_hash.key? 'resourceTypePath'
70
- @type_path = res_hash['resourceTypePath']
71
- else
72
- @type = res_hash['type']
73
- @type_path = res_hash['type']['path']
74
- end
20
+ def hawkular_id
21
+ @properties.fetch('hawkular.metric.id')
75
22
  end
76
- end
77
-
78
- # Fields that are common for MetricType and Metric
79
- module MetricFields
80
- # @return [String] GAUGE, COUNTER, etc.
81
- attr_reader :type
82
- # @return [String] metric unit such as NONE, BYTES, etc.
83
- attr_reader :unit
84
- # @return [Long] collection interval in seconds, it has different semantics for MetricType and for Metric
85
- # for MetricType it's a default that will be applied to all the metric of that type,
86
- # in the Metric this can be overridden
87
- attr_reader :collection_interval
88
- end
89
-
90
- # Definition of a Metric Type inside the inventory.
91
- class MetricType < BaseEntity
92
- include MetricFields
93
23
 
94
- def initialize(type_hash)
95
- super(type_hash)
96
- @type = type_hash['type']
97
- @unit = type_hash['unit']
98
- @collection_interval = type_hash['collectionInterval']
24
+ def hawkular_type
25
+ @properties.fetch('hawkular.metric.type')
99
26
  end
100
- end
101
-
102
- # Definition of a Metric inside the inventory.
103
- class Metric < BaseEntity
104
- include MetricFields
105
-
106
- attr_reader :type_id
107
- # @return [String] metric id used in Hawkular Metrics
108
- attr_reader :hawkular_metric_id
109
27
 
110
- def initialize(metric_hash, metric_type)
111
- super(metric_hash)
112
- @type = metric_type.type
113
- @type_path = metric_hash['metricTypePath']
114
- @type_id = metric_type.id
115
- @unit = metric_type.unit
116
- @collection_interval = metric_hash['collectionInterval'] || metric_type.collection_interval
117
- @hawkular_metric_id = @properties.key?('hawkular-metric-id') ? @properties['hawkular-metric-id'] : @id
28
+ def hawkular_type_id
29
+ @properties.fetch('hawkular.metric.typeId')
118
30
  end
119
31
  end
120
32
 
121
- class OperationDefinition < BaseEntity
33
+ class Operation
34
+ # @return [String] Name of the operation
35
+ attr_reader :name
122
36
  attr_reader :params
123
37
 
124
38
  def initialize(op_hash)
125
- super(op_hash)
39
+ @name = op_hash['name']
126
40
  @params = (op_hash.key? 'parameters') ? op_hash['parameters'] : {}
127
41
  end
128
42
  end
129
43
 
130
- # Definition of a Relationship between two entities in Inventory
131
- class Relationship
132
- attr_accessor :source_id
133
- attr_reader :target_id
134
- attr_reader :properties
135
- attr_reader :name
44
+ class ResourceType
45
+ # @return [String] Id of the resource type
136
46
  attr_reader :id
47
+ # @return [Hash<String,String>] Properties of this resource type
48
+ attr_reader :properties
49
+ # @return [List<Operation>] Operations associated with this type
50
+ attr_reader :operations
137
51
 
138
- def initialize(hash = {})
139
- if hash.empty?
140
- @properties = {}
141
- return
142
- end
143
-
144
- @source_id = hash['source']
145
- @target_id = hash['target']
146
- @properties = hash['properties']
147
- @name = hash['name']
52
+ def initialize(hash)
148
53
  @id = hash['id']
54
+ @properties = hash['properties'] || {}
55
+ @operations = (hash['operations'] || []).map { |op| Operation.new(op) }
56
+ @_hash = hash.dup
57
+ end
58
+
59
+ def ==(other)
60
+ self.equal?(other) || other.class == self.class && other.id == @id
149
61
  end
150
62
 
63
+ # Returns a hash representation of the resource type
64
+ # @return [Hash<String,Object>] hash of the resource type
151
65
  def to_h
152
- hash = {}
153
- hash['source'] = @source_id
154
- hash['target'] = @target_id
155
- hash['properties'] = @properties
156
- hash['name'] = @name
157
- hash['id'] = @id
158
- hash
66
+ @_hash.dup
159
67
  end
160
68
  end
161
69
 
162
- class CanonicalPath
163
- include Hawkular::ClientUtils
164
-
165
- attr_reader :tenant_id
166
- attr_reader :feed_id
167
- attr_reader :environment_id
168
- attr_reader :resource_ids
169
- attr_reader :metric_id
170
- attr_reader :resource_type_id
171
- attr_reader :metric_type_id
70
+ class Resource
71
+ # @return [String] Id of the entity
72
+ attr_reader :id
73
+ # @return [String] Name of the entity
74
+ attr_reader :name
75
+ # @return [String] Feed this entity belongs to
76
+ attr_reader :feed
77
+ # @return [ResourceType] Type of this resource
78
+ attr_reader :type
79
+ # @return [String] Parent ID of this entity (nil if it's a root resource)
80
+ attr_reader :parent_id
81
+ # @return [Hash<String,String>] Properties of this resource
82
+ attr_reader :properties
83
+ # @return [Hash<String,String>] Config map of this resource
84
+ attr_reader :config
85
+ # @return [List<Metric>] Metrics associated to this resource
86
+ attr_reader :metrics
87
+ # @return [List<Resource>] List of children (present when the whole tree is loaded, else nil)
88
+ attr_reader :children
172
89
 
173
90
  def initialize(hash)
174
- @tenant_id = hash[:tenant_id]
175
- @feed_id = hash[:feed_id]
176
- @environment_id = hash[:environment_id]
177
- @resource_type_id = hash[:resource_type_id]
178
- @metric_type_id = hash[:metric_type_id]
179
- @resource_ids = hash[:resource_ids]
180
- @metric_id = hash[:metric_id]
181
- end
182
-
183
- def self.parse(path)
184
- fail Hawkular::ArgumentError, 'CanonicalPath must not be nil or empty' if path.to_s.strip.length == 0
185
-
186
- CanonicalPath.new(path_to_h path)
187
- end
188
-
189
- def self.parse_if_string(path)
190
- path.is_a?(CanonicalPath) ? path : CanonicalPath.parse(path)
191
- end
192
-
193
- def copy_hash
194
- hash = to_h
195
- hash[:resource_ids] = hash[:resource_ids].clone unless hash[:resource_ids].nil?
196
- hash
91
+ @id = hash['id']
92
+ @name = hash['name']
93
+ @feed = hash['feedId']
94
+ @type = ResourceType.new(hash['type'])
95
+ @parent_id = hash['parentId']
96
+ @properties = hash['properties'] || {}
97
+ @config = hash['config'] || {}
98
+ @metrics = (hash['metrics'] || []).map { |m| Metric.new(m) }
99
+ @children = hash['children'].map { |r| Resource.new(r) } if hash.key? 'children'
100
+ @_hash = hash.dup
197
101
  end
198
102
 
199
- # Move up to the parent path of the resource. resource_ids set to empty array when there is no parent.
200
- # @return CanonicalPath corresponding to the direct ancestor of the resource represented by this path object.
201
- def up
202
- hash = copy_hash
203
- res = hash[:resource_ids] || []
204
- res = res.take(res.length - 1) unless res.empty?
205
- hash[:resource_ids] = res
206
- CanonicalPath.new(hash)
103
+ def children(recursive = false)
104
+ return @children unless recursive == true
105
+ fail Hawkular::ArgumentError 'Resource tree not loaded, load it by calling resource_tree' if @children.nil?
106
+ @children.flat_map do |child|
107
+ [child, *child.children(recursive)]
108
+ end
207
109
  end
208
110
 
209
- # Add resource down to the current path
210
- # @return a new CanonicalPath based on the current one
211
- def down(resource)
212
- hash = copy_hash
213
- hash[:resource_ids] = (hash[:resource_ids] || []) << hawk_escape_id(resource)
214
- CanonicalPath.new(hash)
111
+ def children_by_type(type, recursive = false)
112
+ children(recursive).select { |c| c.type.id == type }
215
113
  end
216
114
 
217
- # Set resource type to the current path
218
- # @return a new CanonicalPath based on the current one
219
- def resource_type(resource_type)
220
- hash = copy_hash
221
- hash[:resource_type_id] = hawk_escape_id(resource_type)
222
- CanonicalPath.new(hash)
115
+ def metrics(recursive = false)
116
+ return @metrics unless recursive == true
117
+ children(recursive).collect(&:metrics).flat_map(&:itself).concat(@metrics)
223
118
  end
224
119
 
225
- # Set metric type to the current path
226
- # @return a new CanonicalPath based on the current one
227
- def metric_type(metric_type)
228
- hash = copy_hash
229
- hash[:metric_type_id] = hawk_escape_id(metric_type)
230
- CanonicalPath.new(hash)
120
+ def metrics_by_type(type)
121
+ @metrics.select { |m| m.type == type }
231
122
  end
232
123
 
233
124
  def ==(other)
234
- self.equal?(other) || other.class == self.class && other.state == state
125
+ self.equal?(other) || other.class == self.class && other.id == @id
235
126
  end
236
127
 
128
+ # Returns a hash representation of the resource
129
+ # @return [Hash<String,Object>] hash of the resource
237
130
  def to_h
238
- {
239
- tenant_id: @tenant_id,
240
- feed_id: @feed_id,
241
- environment_id: environment_id,
242
- resource_type_id: resource_type_id,
243
- metric_type_id: metric_type_id,
244
- resource_ids: resource_ids,
245
- metric_id: @metric_id
246
- }
247
- end
248
-
249
- def to_s
250
- ret = "/t;#{@tenant_id}"
251
- ret += "/f;#{@feed_id}" unless @feed_id.nil?
252
- ret += "/e;#{@environment_id}" unless @environment_id.nil?
253
- ret += "/rt;#{@resource_type_id}" unless @resource_type_id.nil?
254
- ret += "/mt;#{@metric_type_id}" unless @metric_type_id.nil?
255
- ret += resources_chunk.to_s
256
- ret += "/m;#{@metric_id}" unless @metric_id.nil?
257
- ret
258
- end
259
-
260
- def to_tags
261
- fail Hawkular::ArgumentError, 'Missing feed_id' if @feed_id.nil?
262
-
263
- tags = "module:inventory,feed:#{Regexp.quote(@feed_id)}"
264
- tags += ",type:rt,id:#{Regexp.quote(@resource_type_id)}" if @resource_type_id
265
- tags += ",type:mt,id:#{Regexp.quote(@metric_type_id)}" if @metric_type_id
266
- tags += ",type:r,id:#{Regexp.quote(@resource_ids[0])}" if @resource_ids && (!@resource_ids.empty?)
267
- tags
268
- end
269
-
270
- protected
271
-
272
- def state
273
- [@tenant_id, @feed_id, @environment_id, @resource_ids, @metric_id, @metric_type_id, @resource_type_id]
274
- end
275
-
276
- private
277
-
278
- def resources_chunk
279
- @resource_ids.map { |r| "/r;#{r}" }.join unless @resource_ids.nil?
280
- end
281
-
282
- def self.path_to_h(path)
283
- tmp = path.split('/')
284
- hash = {}
285
- tmp.each do |pair|
286
- (key, val) = pair.split(';')
287
- case key
288
- when 't'
289
- hash[:tenant_id] = val
290
- when 'f'
291
- hash[:feed_id] = val
292
- when 'e'
293
- hash[:environment_id] = val
294
- when 'm'
295
- hash[:metric_id] = val
296
- when 'r'
297
- hash[:resource_ids] = [] if hash[:resource_ids].nil?
298
- hash[:resource_ids].push(val)
299
- when 'mt'
300
- hash[:metric_type_id] = val
301
- when 'rt'
302
- hash[:resource_type_id] = val
303
- end
304
- end
305
- hash
131
+ @_hash.dup
306
132
  end
307
133
  end
308
134
  end
@@ -1,16 +1,8 @@
1
1
  require 'hawkular/base_client'
2
- require 'websocket-client-simple'
3
- require 'json'
4
- require 'zlib'
5
- require 'stringio'
6
2
 
7
3
  require 'hawkular/inventory/entities'
8
4
 
9
5
  # Inventory module provides access to the Hawkular Inventory REST API.
10
- # @see http://www.hawkular.org/docs/rest/rest-inventory.html
11
- #
12
- # @note While Inventory supports 'environments', they are not used currently
13
- # and thus set to 'test' as default value.
14
6
  module Hawkular::Inventory
15
7
  # Client class to interact with Hawkular Inventory
16
8
  class Client < Hawkular::BaseClient
@@ -21,12 +13,13 @@ module Hawkular::Inventory
21
13
  # http://localhost:8080/hawkular/inventory
22
14
  # @param credentials [Hash{String=>String}] Hash of username, password, token(optional)
23
15
  # @param options [Hash{String=>String}] Additional rest client options
24
- def initialize(entrypoint = nil, credentials = {}, options = {})
25
- entrypoint = normalize_entrypoint_url entrypoint, 'hawkular/metrics'
16
+ def initialize(entrypoint = nil, credentials = {}, options = {}, page_size = nil)
17
+ entrypoint = normalize_entrypoint_url entrypoint, 'hawkular/inventory'
26
18
  @entrypoint = entrypoint
27
19
  super(entrypoint, credentials, options)
28
20
  version = fetch_version_and_status['Implementation-Version']
29
21
  @version = version.scan(/\d+/).map(&:to_i)
22
+ @page_size = page_size || 100
30
23
  end
31
24
 
32
25
  # Creates a new Inventory Client
@@ -38,271 +31,64 @@ module Hawkular::Inventory
38
31
 
39
32
  hash[:credentials] ||= {}
40
33
  hash[:options] ||= {}
41
- Client.new(hash[:entrypoint], hash[:credentials], hash[:options])
34
+ Client.new(hash[:entrypoint], hash[:credentials], hash[:options], hash[:page_size])
42
35
  end
43
36
 
44
- # List feeds in the system
45
- # @return [Array<String>] List of feed ids
46
- def list_feeds
47
- ret = http_get('/strings/tags/module:inventory,feed:*')
48
- return [] unless ret.key? 'feed'
49
- ret['feed']
37
+ # Get single resource by id
38
+ # @return Resource the resource
39
+ def resource(id)
40
+ hash = http_get(url('/resources/%s', id))
41
+ Resource.new(hash)
50
42
  end
51
43
 
52
- # List resource types for the given feed
53
- # @param [String] feed_id The id of the feed the type lives under
54
- # @return [Array<ResourceType>] List of types, that can be empty
55
- def list_resource_types(feed_id)
56
- fail Hawkular::ArgumentError, 'Feed id must be given' unless feed_id
57
-
58
- feed_path = feed_cp(feed_id)
59
- response = http_post(
60
- '/strings/raw/query',
61
- fromEarliest: true,
62
- order: 'DESC',
63
- tags: "#{feed_path.to_tags},type:rt")
64
- structures = extract_structures_from_body(response)
65
- structures.map do |rt|
66
- root_hash = entity_json_to_hash(-> (id) { feed_path.resource_type(id) }, rt['inventoryStructure'], false)
67
- ResourceType.new(root_hash)
68
- end
44
+ # Get resource by id with its complete subtree
45
+ # @return Resource the resource
46
+ def resource_tree(id)
47
+ hash = http_get(url('/resources/%s/tree', id))
48
+ Resource.new(hash)
69
49
  end
70
50
 
71
- # List metric types for the given feed
72
- # @param [String] feed_id The id of the feed the type lives under
73
- # @return [Array<MetricType>] List of types, that can be empty
74
- def list_metric_types(feed_id)
75
- fail Hawkular::ArgumentError, 'Feed id must be given' unless feed_id
76
-
77
- feed_path = feed_cp(feed_id)
78
- response = http_post(
79
- '/strings/raw/query',
80
- fromEarliest: true,
81
- order: 'DESC',
82
- tags: "#{feed_path.to_tags},type:mt")
83
- structures = extract_structures_from_body(response)
84
- structures.map do |mt|
85
- root_hash = entity_json_to_hash(-> (id) { feed_path.metric_type(id) }, mt['inventoryStructure'], false)
86
- MetricType.new(root_hash)
87
- end
51
+ # Get childrens of a resource
52
+ # @return Children of a resource
53
+ def children_resources(parent_id)
54
+ http_get(url('/resources/%s/children', parent_id))['results'].map { |r| Resource.new(r) }
88
55
  end
89
56
 
90
- # Return all resources for a feed
91
- # @param [String] feed_id Id of the feed that hosts the resources
92
- # @param [Boolean] fetch_properties Should the config data be fetched too
93
- # @return [Array<Resource>] List of resources, which can be empty.
94
- def list_resources_for_feed(feed_id, fetch_properties = false, filter = {})
95
- fail Hawkular::ArgumentError, 'Feed id must be given' unless feed_id
96
-
97
- feed_path = feed_cp(feed_id)
98
- response = http_post(
99
- '/strings/raw/query',
100
- fromEarliest: true,
101
- order: 'DESC',
102
- tags: "#{feed_path.to_tags},type:r")
103
- structures = extract_structures_from_body(response)
104
- to_filter = structures.map do |r|
105
- root_hash = entity_json_to_hash(-> (id) { feed_path.down(id) }, r['inventoryStructure'], fetch_properties)
106
- Resource.new(root_hash)
107
- end
108
- filter_entities(to_filter, filter)
57
+ # Get parent of a resource
58
+ # @return Resource the parent resource, or nil if the provided ID referred to a root resource
59
+ def parent(id)
60
+ hash = http_get(url('/resources/%s/parent', id))
61
+ Resource.new(hash) if hash
109
62
  end
110
63
 
111
- # List the resources for the passed resource type. The representation for
112
- # resources under a feed are sparse and additional data must be retrieved separately.
113
- # It is possible though to also obtain runtime properties by setting #fetch_properties to true.
114
- # @param [String] resource_type_path Canonical path of the resource type. Can be obtained from {ResourceType}.path.
115
- # Must not be nil. The tenant_id in the canonical path doesn't have to be there.
116
- # @param [Boolean] fetch_properties Shall additional runtime properties be fetched?
117
- # @return [Array<Resource>] List of resources. Can be empty
118
- def list_resources_for_type(resource_type_path, fetch_properties = false)
119
- path = CanonicalPath.parse_if_string(resource_type_path)
120
-
121
- fail Hawkular::ArgumentError, 'Feed id must be given' unless path.feed_id
122
- fail Hawkular::ArgumentError, 'Resource type must be given' unless path.resource_type_id
123
-
124
- # Fetch metrics by tag
125
- feed_path = feed_cp(URI.unescape(path.feed_id))
126
- resource_type_id = URI.unescape(path.resource_type_id)
127
- escaped_for_regex = Regexp.quote("|#{resource_type_id}|")
128
- response = http_post(
129
- '/strings/raw/query',
130
- fromEarliest: true,
131
- order: 'DESC',
132
- tags: "#{feed_path.to_tags},type:r,restypes:.*#{escaped_for_regex}.*")
133
- structures = extract_structures_from_body(response)
134
- return [] if structures.empty?
135
-
136
- # Now find each collected resource path in their belonging InventoryStructure
137
- extract_resources_for_type(structures, feed_path, resource_type_id, fetch_properties)
64
+ # List root resources
65
+ # @return [Enumeration<Resource>] Lazy-loaded Enumeration of resources
66
+ def root_resources
67
+ resources root: 'true'
138
68
  end
139
69
 
140
- # Retrieve runtime properties for the passed resource
141
- # @param [String] resource_path Canonical path of the resource to read properties from.
142
- # @return [Hash<String,Object] Hash with additional data
143
- def get_config_data_for_resource(resource_path)
144
- path = CanonicalPath.parse_if_string(resource_path)
145
- raw_hash = get_raw_entity_hash(path)
146
- return {} unless raw_hash
147
- { 'value' => fetch_properties(raw_hash) }
148
- end
70
+ # List resources
71
+ # @param [Hash] filter options to filter the resource list
72
+ # @option filter :root If truthy, only get root resources
73
+ # @option filter :feedId Filter by feed id
74
+ # @option filter :typeId Filter by type id
75
+ # @return [Enumeration<Resource>] Lazy-loaded Enumeration of resources
76
+ def resources(filter = {})
77
+ filter[:root] = !filter[:root].nil? if filter.key? :root
78
+ filter[:maxResults] = @page_size
149
79
 
150
- # Obtain the child resources of the passed resource. In case of a WildFly server,
151
- # those would be Datasources, Deployments and so on.
152
- # @param [String] parent_res_path Canonical path of the resource to obtain children from.
153
- # @param [Boolean] recursive Whether to fetch also all the children of children of ...
154
- # @return [Array<Resource>] List of resources that are children of the given parent resource.
155
- # Can be empty
156
- def list_child_resources(parent_res_path, recursive = false)
157
- path = CanonicalPath.parse_if_string(parent_res_path)
158
- feed_id = path.feed_id
159
-
160
- fail Hawkular::ArgumentError, 'Feed id must be given' unless feed_id
161
-
162
- entity_hash = get_raw_entity_hash(path)
163
- extract_child_resources([], path.to_s, entity_hash, recursive) if entity_hash
164
- end
165
-
166
- # List the metrics for the passed metric type. If feed is not passed in the path,
167
- # all the metrics across all the feeds of a given type will be retrieved
168
- # @param [String] metric_type_path Canonical path of the resource type to look for. Can be obtained from
169
- # {MetricType}.path. Must not be nil. The tenant_id in the canonical path doesn't have to be there.
170
- # @return [Array<Metric>] List of metrics. Can be empty
171
- def list_metrics_for_metric_type(metric_type_path)
172
- path = CanonicalPath.parse_if_string(metric_type_path)
173
-
174
- fail Hawkular::ArgumentError, 'Feed id must be given' unless path.feed_id
175
- fail Hawkular::ArgumentError, 'Metric type id must be given' unless path.metric_type_id
176
-
177
- feed_id = URI.unescape(path.feed_id)
178
- metric_type_id = URI.unescape(path.metric_type_id)
179
-
180
- feed_path = feed_cp(feed_id)
181
- escaped_for_regex = Regexp.quote("|#{metric_type_id}|")
182
- response = http_post(
183
- '/strings/raw/query',
184
- fromEarliest: true,
185
- order: 'DESC',
186
- tags: "#{feed_path.to_tags},type:r,mtypes:.*#{escaped_for_regex}.*")
187
- structures = extract_structures_from_body(response)
188
- return [] if structures.empty?
189
-
190
- # Now find each collected resource path in their belonging InventoryStructure
191
- metric_type = get_metric_type(path)
192
- extract_metrics_for_type(structures, feed_path, metric_type)
193
- end
194
-
195
- # List metric (definitions) for the passed resource. It is possible to filter down the
196
- # result by a filter to only return a subset. The
197
- # @param [String] resource_path Canonical path of the resource.
198
- # @param [Hash{Symbol=>String}] filter for 'type' and 'match'
199
- # Metric type can be one of 'GAUGE', 'COUNTER', 'AVAILABILITY'. If a key is missing
200
- # it will not be used for filtering
201
- # @return [Array<Metric>] List of metrics that can be empty.
202
- # @example
203
- # # Filter by type and match on metrics id
204
- # client.list_metrics_for_resource(wild_fly, type: 'GAUGE', match: 'Metrics~Heap')
205
- # # Filter by type only
206
- # client.list_metrics_for_resource(wild_fly, type: 'COUNTER')
207
- # # Don't filter, return all metric definitions
208
- # client.list_metrics_for_resource(wild_fly)
209
- def list_metrics_for_resource(resource_path, filter = {})
210
- path = CanonicalPath.parse_if_string(resource_path)
211
- raw_hash = get_raw_entity_hash(path)
212
- return [] unless raw_hash
213
- to_filter = []
214
- if (raw_hash.key? 'children') && (raw_hash['children'].key? 'metric') && !raw_hash['children']['metric'].empty?
215
- # Need to merge metric type info that we must grab from another place
216
- metric_types = list_metric_types(URI.unescape(path.feed_id))
217
- metric_types_index = {}
218
- metric_types.each { |mt| metric_types_index[mt.path] = mt }
219
- to_filter = raw_hash['children']['metric'].map do |m|
220
- metric_data = m['data']
221
- metric_data['path'] = "#{path}/m;#{metric_data['id']}"
222
- metric_type = metric_types_index[metric_data['metricTypePath']]
223
- Metric.new(metric_data, metric_type) if metric_type
224
- end
225
- to_filter = to_filter.select { |m| m }
226
- end
227
- filter_entities(to_filter, filter)
228
- end
229
-
230
- # Return the resource object for the passed path
231
- # @param [String] resource_path Canonical path of the resource to fetch.
232
- # @param [Boolean] fetch_properties Should the resource config data be fetched?
233
- def get_resource(resource_path, fetch_properties = true)
234
- path = CanonicalPath.parse_if_string(resource_path)
235
- raw_hash = get_raw_entity_hash(path)
236
-
237
- unless raw_hash
238
- fail Hawkular::Exception, "Resource not found: #{resource_path}"
239
- end
240
-
241
- entity_hash = entity_json_to_hash(-> (_) { path }, raw_hash, fetch_properties)
242
- Resource.new(entity_hash)
243
- end
244
-
245
- # Return the resource type object for the passed path
246
- # @param [String] resource_type_path Canonical path of the resource type to fetch.
247
- def get_resource_type(resource_type_path)
248
- path = CanonicalPath.parse_if_string(resource_type_path)
249
- raw_hash = get_raw_entity_hash(path)
250
-
251
- unless raw_hash
252
- fail Hawkular::Exception, "Resource type not found: #{resource_type_path}"
80
+ fetch_func = lambda do |offset|
81
+ filter[:startOffSet] = offset
82
+ filter_query = '?' + filter.keys.join('=%s&') + '=%s' unless filter.empty?
83
+ http_get(url("/resources#{filter_query}", *filter.values))
253
84
  end
254
-
255
- entity_hash = entity_json_to_hash(-> (_) { path }, raw_hash, false)
256
- ResourceType.new(entity_hash)
85
+ ResultFetcher.new(fetch_func).map { |r| Resource.new(r) }
257
86
  end
258
87
 
259
- # Return the metric type object for the passed path
260
- # @param [String] metric_type_path Canonical path of the metric type to fetch.
261
- def get_metric_type(metric_type_path)
262
- path = CanonicalPath.parse_if_string(metric_type_path)
263
- raw_hash = get_raw_entity_hash(path)
264
-
265
- unless raw_hash
266
- fail Hawkular::Exception, "Metric type not found: #{metric_type_path}"
267
- end
268
-
269
- entity_hash = entity_json_to_hash(-> (_) { path }, raw_hash, false)
270
- MetricType.new(entity_hash)
271
- end
272
-
273
- # List operation definitions (types) for a given resource type
274
- # @param [String] resource_type_path canonical path of the resource type entity
275
- # @return [Array<String>] List of operation type ids
276
- def list_operation_definitions(resource_type_path)
277
- path = CanonicalPath.parse_if_string(resource_type_path)
278
-
279
- fail Hawkular::ArgumentError, 'Missing feed_id in resource_type_path' unless path.feed_id
280
- fail Hawkular::ArgumentError, 'Missing resource_type_id in resource_type_path' unless path.resource_type_id
281
-
282
- response = http_post(
283
- '/strings/raw/query',
284
- fromEarliest: true,
285
- order: 'DESC',
286
- tags: path.to_tags)
287
- structures = extract_structures_from_body(response)
288
- res = {}
289
- structures.map { |rt| rt['inventoryStructure'] }
290
- .select { |rt| rt['children'] && rt['children']['operationType'] }
291
- .flat_map { |rt| rt['children']['operationType'] }
292
- .each do |ot|
293
- hash = optype_json_to_hash(ot)
294
- od = OperationDefinition.new hash
295
- res[od.name] = od
296
- end
297
- res
298
- end
299
-
300
- # List operation definitions (types) for a given resource
301
- # @param [String] resource_path canonical path of the resource entity
302
- # @return [Array<String>] List of operation type ids
303
- def list_operation_definitions_for_resource(resource_path)
304
- resource = get_resource(resource_path, false)
305
- list_operation_definitions(resource.type_path)
88
+ # List resources for type
89
+ # @return [Enumeration<Resource>] Lazy-loaded Enumeration of resources
90
+ def resources_for_type(type)
91
+ resources typeId: type
306
92
  end
307
93
 
308
94
  # Return version and status information for the used version of Hawkular-Inventory
@@ -311,184 +97,25 @@ module Hawkular::Inventory
311
97
  def fetch_version_and_status
312
98
  http_get('/status')
313
99
  end
100
+ end
314
101
 
315
- def feed_cp(feed_id)
316
- CanonicalPath.new(tenant_id: @tenant, feed_id: hawk_escape_id(feed_id))
317
- end
318
-
319
- private
320
-
321
- def filter_entities(entities, filter)
322
- entities.select do |entity|
323
- found = true
324
- if filter.empty?
325
- found = true
326
- else
327
- found = false unless filter[:type] == (entity.type) || filter[:type].nil?
328
- found = false unless filter[:match].nil? || entity.id.include?(filter[:match])
329
- end
330
- found
331
- end
332
- end
333
-
334
- def entity_json_to_hash(path_getter, json, fetch_properties)
335
- data = json['data']
336
- data['path'] = path_getter.call(data['id']).to_s
337
- if fetch_properties
338
- props = fetch_properties(json)
339
- data['properties'].merge! props if props
340
- end
341
- data
342
- end
343
-
344
- def fetch_properties(json)
345
- return unless (json.key? 'children') && (json['children'].key? 'dataEntity')
346
- config = json['children']['dataEntity'].find { |d| d['data']['id'] == 'configuration' }
347
- config['data']['value'] if config
348
- end
349
-
350
- def optype_json_to_hash(json)
351
- data = json['data']
352
- # Fetch parameterTypes
353
- if (json.key? 'children') && (json['children'].key? 'dataEntity')
354
- param_types = json['children']['dataEntity'].find { |d| d['data']['id'] == 'parameterTypes' }
355
- data['parameters'] = param_types['data']['value'] if param_types
356
- end
357
- data
358
- end
359
-
360
- def get_raw_entity_hash(path)
361
- c_path = CanonicalPath.parse_if_string(path)
362
- raw = http_post(
363
- '/strings/raw/query',
364
- fromEarliest: true,
365
- order: 'DESC',
366
- tags: c_path.to_tags
367
- )
368
- structure = extract_structure_from_body(raw)
369
- find_entity_in_tree(c_path, structure)
370
- end
371
-
372
- def find_entity_in_tree(fullpath, inventory_structure)
373
- entity = inventory_structure
374
- if fullpath.resource_ids
375
- relative = fullpath.resource_ids.drop(1)
376
- relative.each do |child|
377
- if (entity.key? 'children') && (entity['children'].key? 'resource')
378
- unescaped = URI.unescape(child)
379
- entity = entity['children']['resource'].find { |r| r['data']['id'] == unescaped }
380
- else
381
- entity = nil
382
- break
383
- end
384
- end
385
- end
386
- if fullpath.metric_id
387
- if (entity.key? 'children') && (entity['children'].key? 'metric')
388
- unescaped = URI.unescape(fullpath.metric_id)
389
- entity = entity['children']['metric'].find { |r| r['data']['id'] == unescaped }
390
- else
391
- entity = nil
392
- end
393
- end
394
- entity
395
- end
396
-
397
- def extract_child_resources(arr, path, parent_hash, recursive)
398
- c_path = CanonicalPath.parse_if_string(path)
399
- if (parent_hash.key? 'children') && (parent_hash['children'].key? 'resource')
400
- parent_hash['children']['resource'].each do |r|
401
- entity = entity_json_to_hash(-> (id) { c_path.down(id) }, r, false)
402
- arr.push(Resource.new(entity))
403
- extract_child_resources(arr, entity['path'], r, true) if recursive
404
- end
405
- end
406
- arr
407
- end
408
-
409
- def extract_resources_for_type(structures, feed_path, resource_type_id, fetch_properties)
410
- matching_resources = []
411
- structures.each do |full_struct|
412
- next unless full_struct.key? 'typesIndex'
413
- next unless full_struct['typesIndex'].key? resource_type_id
414
- inventory_structure = full_struct['inventoryStructure']
415
- root_path = feed_path.down(inventory_structure['data']['id'])
416
- full_struct['typesIndex'][resource_type_id].each do |relative_path|
417
- if relative_path.empty?
418
- # Root resource
419
- resource = entity_json_to_hash(-> (id) { feed_path.down(id) }, inventory_structure, fetch_properties)
420
- matching_resources.push(Resource.new(resource))
421
- else
422
- # Search for child
423
- fullpath = CanonicalPath.parse("#{root_path}/#{relative_path}")
424
- resource_json = find_entity_in_tree(fullpath, inventory_structure)
425
- if resource_json
426
- resource = entity_json_to_hash(-> (_) { fullpath }, resource_json, fetch_properties)
427
- matching_resources.push(Resource.new(resource))
428
- end
429
- end
430
- end
431
- end
432
- matching_resources
433
- end
434
-
435
- def extract_metrics_for_type(structures, feed_path, metric_type)
436
- matching_metrics = []
437
- structures.each do |full_struct|
438
- next unless full_struct.key? 'metricTypesIndex'
439
- next unless full_struct['metricTypesIndex'].key? metric_type.id
440
- inventory_structure = full_struct['inventoryStructure']
441
- root_path = feed_path.down(inventory_structure['data']['id'])
442
- full_struct['metricTypesIndex'][metric_type.id].each do |relative_path|
443
- # Search for child
444
- fullpath = CanonicalPath.parse("#{root_path}/#{relative_path}")
445
- metric_json = find_entity_in_tree(fullpath, inventory_structure)
446
- if metric_json
447
- metric_hash = entity_json_to_hash(-> (_) { fullpath }, metric_json, false)
448
- matching_metrics.push(Metric.new(metric_hash, metric_type))
449
- end
450
- end
451
- end
452
- matching_metrics
453
- end
454
-
455
- def extract_structure_from_body(response_body_array)
456
- # Expecting only 1 structure (but may have several chunks)
457
- structures = extract_structures_from_body(response_body_array)
458
- structures[0]['inventoryStructure'] unless structures.empty?
459
- end
102
+ # Lazy fetching results, based on Inventory "ResultSet" model
103
+ class ResultFetcher
104
+ include Enumerable
460
105
 
461
- def extract_structures_from_body(response_body_array)
462
- response_body_array.map { |element| Client.rebuild_from_chunks(element['data']) }
463
- .select { |full| full } # evict nil
464
- .map { |full| Client.decompress(full) }
106
+ def initialize(fetcher)
107
+ @fetcher = fetcher
465
108
  end
466
109
 
467
- def self.rebuild_from_chunks(data_node)
468
- return if data_node.empty?
469
- master_data = data_node[0]
470
- return Base64.decode64(master_data['value']) unless (master_data.key? 'tags') &&
471
- (master_data['tags'].key? 'chunks')
472
- master_timestamp = master_data['timestamp']
473
- last_chunk = master_data['tags']['chunks'].to_i - 1
474
- all = Base64.decode64(master_data['value'])
475
- return if all.empty?
476
- (1..last_chunk).inject(all) do |full, chunk_id|
477
- slave_data = data_node[chunk_id]
478
- # Race condition: slave_data might be nil if not all chunks have been written yet on DB
479
- # Consider the object is not there yet
480
- return nil unless slave_data
481
- # The same race condition could give us an expirated slave_data; do sanity check to cover that
482
- # Timestamps are useful here, they're in consecutive, decreasing order
483
- slave_timestamp = slave_data['timestamp']
484
- return nil unless slave_timestamp == master_timestamp - chunk_id
485
- full.concat(Base64.decode64(slave_data['value']))
110
+ def each
111
+ offset = 0
112
+ loop do
113
+ result_set = @fetcher.call(offset)
114
+ results = result_set['results']
115
+ results.each { |r| yield(r) }
116
+ offset += results.length
117
+ break if offset >= result_set['resultSize']
486
118
  end
487
119
  end
488
-
489
- def self.decompress(raw)
490
- gz = Zlib::GzipReader.new(StringIO.new(raw))
491
- JSON.parse(gz.read)
492
- end
493
120
  end
494
121
  end
@@ -149,26 +149,26 @@ module Hawkular::Operations
149
149
  # Invokes a generic operation on the WildFly agent
150
150
  # (the operation name must be specified in the hash)
151
151
  # Note: if success and failure callbacks are omitted, the client will not wait for the Response message
152
- # @param hash [Hash{String=>Object}] a hash containing: resourcePath [String] denoting the resource on
153
- # which the operation is about to run, operationName [String]
152
+ # @param hash [Hash{String=>Object}] a hash containing: resourceId [String] denoting the resource on
153
+ # which the operation is about to run, feedId [String], operationName [String]
154
154
  # @param callback [Block] callback that is run after the operation is done
155
155
  def invoke_generic_operation(hash, &callback)
156
- required = [:resourcePath, :operationName]
156
+ required = [:resourceId, :feedId, :operationName]
157
157
  check_pre_conditions hash, required, &callback
158
158
 
159
159
  invoke_operation_helper(hash, &callback)
160
160
  end
161
161
 
162
162
  # Invokes operation on the WildFly agent that has it's own message type
163
- # @param operation_payload [Hash{String=>Object}] a hash containing: resourcePath [String] denoting
164
- # the resource on which the operation is about to run
163
+ # @param operation_payload [Hash{String=>Object}] a hash containing: resourceId [String] denoting
164
+ # the resource on which the operation is about to run, feedId [String]
165
165
  # @param operation_name [String] the name of the operation. This must correspond with the message type, they can be
166
166
  # found here https://git.io/v2h1a (Use only the first part of the name without the Request/Response suffix), e.g.
167
167
  # RemoveDatasource (and not RemoveDatasourceRequest)
168
168
  # @param callback [Block] callback that is run after the operation is done
169
169
  def invoke_specific_operation(operation_payload, operation_name, &callback)
170
170
  fail Hawkular::ArgumentError, 'Operation must be specified' if operation_name.nil?
171
- required = [:resourcePath]
171
+ required = [:resourceId, :feedId]
172
172
  check_pre_conditions operation_payload, required, &callback
173
173
 
174
174
  invoke_operation_helper(operation_payload, operation_name, &callback)
@@ -177,8 +177,9 @@ module Hawkular::Operations
177
177
  # Deploys an archive file into WildFly
178
178
  #
179
179
  # @param [Hash] hash Arguments for deployment
180
- # @option hash [String] :resource_path canonical path of the WildFly server into which we deploy
180
+ # @option hash [String] :resource_id ID of the WildFly server into which we deploy
181
181
  # or of the domain controller if we deploy into a server group (in case of domain mode)
182
+ # @option hash [String] :feed_id feed containing this resource
182
183
  # @option hash [String] :destination_file_name resulting file name
183
184
  # @option hash [String] :binary_content binary content representing the war file
184
185
  # @option hash [String] :enabled whether the deployment should be enabled immediately, or not (default = true)
@@ -189,7 +190,7 @@ module Hawkular::Operations
189
190
  def add_deployment(hash, &callback)
190
191
  hash[:enabled] = hash.key?(:enabled) ? hash[:enabled] : true
191
192
  hash[:force_deploy] = hash.key?(:force_deploy) ? hash[:force_deploy] : false
192
- required = [:resource_path, :destination_file_name, :binary_content]
193
+ required = [:resource_id, :feed_id, :destination_file_name, :binary_content]
193
194
  check_pre_conditions hash, required, &callback
194
195
 
195
196
  operation_payload = prepare_payload_hash([:binary_content], hash)
@@ -199,7 +200,8 @@ module Hawkular::Operations
199
200
  # Undeploy a WildFly deployment
200
201
  #
201
202
  # @param [Hash] hash Arguments for deployment removal
202
- # @option hash [String] :resource_path canonical path of the WildFly server from which to undeploy the deployment
203
+ # @option hash [String] :resource_id ID of the WildFly server from which to undeploy the deployment
204
+ # @option hash [String] :feed_id feed containing this resource
203
205
  # @option hash [String] :deployment_name name of deployment to undeploy
204
206
  # @option hash [String] :remove_content whether to remove the deployment content or not (default = true)
205
207
  # @option hash [String] :server_groups comma-separated list of server groups for the operation (default = ignored)
@@ -207,12 +209,9 @@ module Hawkular::Operations
207
209
  # @param callback [Block] callback that is run after the operation is done
208
210
  def undeploy(hash, &callback)
209
211
  hash[:remove_content] = hash.key?(:remove_content) ? hash[:remove_content] : true
210
- required = [:resource_path, :deployment_name]
212
+ required = [:resource_id, :feed_id, :deployment_name]
211
213
  check_pre_conditions hash, required, &callback
212
214
 
213
- cp = ::Hawkular::Inventory::CanonicalPath.parse hash[:resource_path]
214
- server_path = cp.up.to_s
215
- hash[:resource_path] = server_path
216
215
  hash[:destination_file_name] = hash[:deployment_name]
217
216
 
218
217
  operation_payload = prepare_payload_hash([:deployment_name], hash)
@@ -222,18 +221,16 @@ module Hawkular::Operations
222
221
  # Enable a WildFly deployment
223
222
  #
224
223
  # @param [Hash] hash Arguments for enable deployment
225
- # @option hash [String] :resource_path canonical path of the WildFly server from which to enable the deployment
224
+ # @option hash [String] :resource_id ID of the WildFly server from which to enable the deployment
225
+ # @option hash [String] :feed_id feed containing this resource
226
226
  # @option hash [String] :deployment_name name of deployment to enable
227
227
  # @option hash [String] :server_groups comma-separated list of server groups for the operation (default = ignored)
228
228
  #
229
229
  # @param callback [Block] callback that is run after the operation is done
230
230
  def enable_deployment(hash, &callback)
231
- required = [:resource_path, :deployment_name]
231
+ required = [:resource_id, :feed_id, :deployment_name]
232
232
  check_pre_conditions hash, required, &callback
233
233
 
234
- cp = ::Hawkular::Inventory::CanonicalPath.parse hash[:resource_path]
235
- server_path = cp.up.to_s
236
- hash[:resource_path] = server_path
237
234
  hash[:destination_file_name] = hash[:deployment_name]
238
235
 
239
236
  operation_payload = prepare_payload_hash([:deployment_name], hash)
@@ -243,18 +240,16 @@ module Hawkular::Operations
243
240
  # Disable a WildFly deployment
244
241
  #
245
242
  # @param [Hash] hash Arguments for disable deployment
246
- # @option hash [String] :resource_path canonical path of the WildFly server from which to disable the deployment
243
+ # @option hash [String] :resource_id ID of the WildFly server from which to disable the deployment
244
+ # @option hash [String] :feed_id feed containing this resource
247
245
  # @option hash [String] :deployment_name name of deployment to disable
248
246
  # @option hash [String] :server_groups comma-separated list of server groups for the operation (default = ignored)
249
247
  #
250
248
  # @param callback [Block] callback that is run after the operation is done
251
249
  def disable_deployment(hash, &callback)
252
- required = [:resource_path, :deployment_name]
250
+ required = [:resource_id, :feed_id, :deployment_name]
253
251
  check_pre_conditions hash, required, &callback
254
252
 
255
- cp = ::Hawkular::Inventory::CanonicalPath.parse hash[:resource_path]
256
- server_path = cp.up.to_s
257
- hash[:resource_path] = server_path
258
253
  hash[:destination_file_name] = hash[:deployment_name]
259
254
 
260
255
  operation_payload = prepare_payload_hash([:deployment_name], hash)
@@ -264,18 +259,16 @@ module Hawkular::Operations
264
259
  # Restart a WildFly deployment
265
260
  #
266
261
  # @param [Hash] hash Arguments for restart deployment
267
- # @option hash [String] :resource_path canonical path of the WildFly server from which to restart the deployment
262
+ # @option hash [String] :resource_id ID of the WildFly server from which to restart the deployment
263
+ # @option hash [String] :feed_id feed containing this resource
268
264
  # @option hash [String] :deployment_name name of deployment to restart
269
265
  # @option hash [String] :server_groups comma-separated list of server groups for the operation (default = ignored)
270
266
  #
271
267
  # @param callback [Block] callback that is run after the operation is done
272
268
  def restart_deployment(hash, &callback)
273
- required = [:resource_path, :deployment_name]
269
+ required = [:resource_id, :feed_id, :deployment_name]
274
270
  check_pre_conditions hash, required, &callback
275
271
 
276
- cp = ::Hawkular::Inventory::CanonicalPath.parse hash[:resource_path]
277
- server_path = cp.up.to_s
278
- hash[:resource_path] = server_path
279
272
  hash[:destination_file_name] = hash[:deployment_name]
280
273
 
281
274
  operation_payload = prepare_payload_hash([:deployment_name], hash)
@@ -285,7 +278,8 @@ module Hawkular::Operations
285
278
  # Adds a new datasource
286
279
  #
287
280
  # @param [Hash] hash Arguments for the datasource
288
- # @option hash [String] :resourcePath canonical path of the WildFly server into which we add datasource
281
+ # @option hash [String] :resourceId ID of the WildFly server into which we add datasource
282
+ # @option hash [String] :feedId ID of the feed containing the WildFly server
289
283
  # @option hash [String] :xaDatasource XA DS or normal
290
284
  # @option hash [String] :datasourceName name of the datasource
291
285
  # @option hash [String] :jndiName JNDI name
@@ -298,7 +292,8 @@ module Hawkular::Operations
298
292
  #
299
293
  # @param callback [Block] callback that is run after the operation is done
300
294
  def add_datasource(hash, &callback)
301
- required = [:resourcePath, :xaDatasource, :datasourceName, :jndiName, :driverName, :driverClass, :connectionUrl]
295
+ required = [:resourceId, :feedId, :xaDatasource, :datasourceName, :jndiName, :driverName,
296
+ :driverClass, :connectionUrl]
302
297
  check_pre_conditions hash, required, &callback
303
298
 
304
299
  invoke_specific_operation(hash, 'AddDatasource', &callback)
@@ -307,7 +302,8 @@ module Hawkular::Operations
307
302
  # Adds a new datasource
308
303
  #
309
304
  # @param [Hash] hash Arguments for the datasource
310
- # @option hash [String] :resource_path canonical path of the WildFly server into which we add driver
305
+ # @option hash [String] :resource_id ID of the WildFly server into which we add driver
306
+ # @option hash [String] :feed_id ID of the feed containing the WildFly server
311
307
  # @option hash [String] :driver_jar_name name of the jar file
312
308
  # @option hash [String] :driver_name name of the jdbc driver (when adding datasource, this is the driverName)
313
309
  # @option hash [String] :module_name name of the JBoss module into which the driver will be installed - 'foo.bar'
@@ -316,7 +312,8 @@ module Hawkular::Operations
316
312
  #
317
313
  # @param callback [Block] callback that is run after the operation is done
318
314
  def add_jdbc_driver(hash, &callback)
319
- required = [:resource_path, :driver_jar_name, :driver_name, :module_name, :driver_class, :binary_content]
315
+ required = [:resource_id, :feed_id, :driver_jar_name, :driver_name, :module_name,
316
+ :driver_class, :binary_content]
320
317
  check_pre_conditions hash, required, &callback
321
318
 
322
319
  operation_payload = prepare_payload_hash([:binary_content], hash)
@@ -325,23 +322,28 @@ module Hawkular::Operations
325
322
 
326
323
  # Exports the JDR report
327
324
  #
328
- # @param [String] resource_path canonical path of the WildFly server
325
+ # @param [String] resource_id ID of the WildFly server
326
+ # @param [String] feed_id ID of the feed containing the WildFly server
329
327
  # @param [Boolean] delete_immediately specifies whether the temporary file at the remote
330
328
  # server should be deleted. False, by default.
331
329
  # @param callback [Block] callback that is run after the operation is done
332
- def export_jdr(resource_path, delete_immediately = false, &callback)
333
- fail Hawkular::ArgumentError, 'resource_path must be specified' if resource_path.nil?
330
+ def export_jdr(resource_id, feed_id, delete_immediately = false, sender_request_id = nil, &callback)
331
+ fail Hawkular::ArgumentError, 'resource_id must be specified' if resource_id.nil?
332
+ fail Hawkular::ArgumentError, 'feed_id must be specified' if feed_id.nil?
334
333
  check_pre_conditions(&callback)
335
334
 
336
- invoke_specific_operation({ resourcePath: resource_path,
337
- deleteImmediately: delete_immediately },
335
+ invoke_specific_operation({ resourceId: resource_id,
336
+ feedId: feed_id,
337
+ deleteImmediately: delete_immediately,
338
+ senderRequestId: sender_request_id },
338
339
  'ExportJdr', &callback)
339
340
  end
340
341
 
341
342
  # Updates the collection intervals.
342
343
  #
343
344
  # @param [Hash] hash Arguments for update collection intervals
344
- # @option hash {resourcePath} a resource managed by the target agent
345
+ # @option hash {resourceId} a resource managed by the target agent
346
+ # @option hash {feedId} the related feed ID
345
347
  # @option hash {metricTypes} A map with key=MetricTypeId, value=interval (seconds).
346
348
  # MetricTypeId must be of form MetricTypeSet~MetricTypeName
347
349
  # @option hash {availTypes} A map with key=AvailTypeId, value=interval (seconds).
@@ -349,7 +351,7 @@ module Hawkular::Operations
349
351
  #
350
352
  # @param callback [Block] callback that is run after the operation is done
351
353
  def update_collection_intervals(hash, &callback)
352
- required = [:resourcePath, :metricTypes, :availTypes]
354
+ required = [:resourceId, :feedId, :metricTypes, :availTypes]
353
355
  check_pre_conditions hash, required, &callback
354
356
  invoke_specific_operation(hash, 'UpdateCollectionIntervals', &callback)
355
357
  end
@@ -363,6 +365,9 @@ module Hawkular::Operations
363
365
  operation_name ||= 'ExecuteOperation'
364
366
  add_credentials! operation_payload
365
367
 
368
+ # if unset, set the :senderRequestId
369
+ operation_payload[:senderRequestId] = SecureRandom.uuid unless operation_payload[:senderRequestId]
370
+
366
371
  handle_message(operation_name, operation_payload, &callback) unless callback.nil?
367
372
 
368
373
  # sends a message that will actually run the operation
@@ -404,12 +409,8 @@ module Hawkular::Operations
404
409
 
405
410
  case parsed[:operationName]
406
411
  when "#{operation_name}Response"
407
- same_path = parsed[:data]['resourcePath'] == operation_payload[:resourcePath]
408
- # failed operations don't return the operation name from some strange reason
409
- same_name = operation_payload[:operationName].nil? ||
410
- parsed[:data]['operationName'] == operation_payload[:operationName].to_s
411
- if same_path # using the resource path as a correlation id
412
- success = same_name && parsed[:data]['status'] == 'OK'
412
+ if parsed[:data]['senderRequestId'] == operation_payload[:senderRequestId]
413
+ success = parsed[:data]['status'] == 'OK'
413
414
  success ? callback.perform(:success, parsed[:data]) : callback.perform(:failure, parsed[:data]['message'])
414
415
  client.remove_listener :message
415
416
  end
@@ -4,5 +4,5 @@
4
4
  # @see https://github.com/hawkular
5
5
  module Hawkular
6
6
  # Version of the Hawkular Ruby Gem
7
- VERSION = '4.1.0'.freeze
7
+ VERSION = '5.0.0.pre1'.freeze
8
8
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hawkular-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.0
4
+ version: 5.0.0.pre1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Libor Zoubek
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2017-08-09 00:00:00.000000000 Z
14
+ date: 2017-11-15 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rest-client
@@ -271,12 +271,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
271
271
  requirements:
272
272
  - - ">="
273
273
  - !ruby/object:Gem::Version
274
- version: 2.0.0
274
+ version: 2.2.0
275
275
  required_rubygems_version: !ruby/object:Gem::Requirement
276
276
  requirements:
277
- - - ">="
277
+ - - ">"
278
278
  - !ruby/object:Gem::Version
279
- version: '0'
279
+ version: 1.3.1
280
280
  requirements: []
281
281
  rubyforge_project:
282
282
  rubygems_version: 2.6.11