hawkular-client 4.1.0 → 5.0.0.pre1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml 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