hawkular-client 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.coveralls.yml +1 -0
- data/.gitignore +2 -1
- data/.rubocop.yml +19 -6
- data/CHANGES.rdoc +13 -3
- data/README.rdoc +9 -3
- data/hawkularclient.gemspec +8 -4
- data/lib/alerts/alerts_api.rb +202 -32
- data/lib/hawkular.rb +35 -67
- data/lib/hawkular_all.rb +2 -0
- data/lib/inventory/inventory_api.rb +459 -130
- data/lib/metrics/metric_api.rb +14 -9
- data/lib/operations/operations_api.rb +247 -0
- data/lib/tokens/tokens_api.rb +33 -0
- data/lib/version.rb +1 -1
- data/spec/integration/alerts_spec.rb +272 -20
- data/spec/integration/hello-world-definitions.json +46 -0
- data/spec/integration/inventory_spec.rb +253 -89
- data/spec/integration/metric_spec.rb +36 -0
- data/spec/integration/operations_spec.rb +420 -0
- data/spec/integration/tokens_spec.rb +45 -0
- data/spec/resources/driver.jar +0 -0
- data/spec/resources/sample.war +0 -0
- data/spec/spec_helper.rb +30 -6
- data/spec/unit/base_spec.rb +22 -1
- data/spec/unit/canonical_path_spec.rb +92 -0
- data/spec/vcr/vcr_setup.rb +3 -4
- data/spec/vcr_cassettes/Alert/EndToEnd/Should_create_and_fire_a_trigger.yml +1187 -0
- data/spec/vcr_cassettes/Alert/Events/Should_list_events.yml +101 -0
- data/spec/vcr_cassettes/Alert/Events/Should_list_events_using_criteria.yml +79 -0
- data/spec/vcr_cassettes/Alert/Events/Should_not_list_events_using_criteria.yml +49 -0
- data/spec/vcr_cassettes/Alert/Triggers/Should_bulk_load_triggers.yml +225 -0
- data/spec/vcr_cassettes/Alert/Triggers/Should_create_a_basic_trigger_with_action.yml +355 -0
- data/spec/vcr_cassettes/Alert/Triggers/Should_create_an_action.yml +134 -0
- data/spec/vcr_cassettes/Alert/Triggers/Should_create_an_action_for_webhooks.yml +220 -0
- data/spec/vcr_cassettes/Alert/Triggers/Should_get_the_action_definitions.yml +218 -0
- data/spec/vcr_cassettes/Alert/Triggers/Should_not_create_an_action_for_unknown_plugin.yml +46 -0
- data/spec/vcr_cassettes/Alert/Triggers/Should_not_create_an_action_for_unknown_properties.yml +134 -0
- data/spec/vcr_cassettes/Counter_metrics/Should_get_metrics_with_limit_and_order.yml +270 -0
- data/spec/vcr_cassettes/Inventory/Client_should_listen_on_various_inventory_events.json +47 -0
- data/spec/vcr_cassettes/Inventory/Client_should_listen_on_various_inventory_events.yml +191 -0
- data/spec/vcr_cassettes/Inventory/Helpers/generate_some_events_for_websocket.yml +507 -0
- data/spec/vcr_cassettes/Inventory/Should_List_datasources_with_no_props.yml +74 -69
- data/spec/vcr_cassettes/Inventory/{Should_list_types_without_feed.yml → Should_create_a_feed.yml} +29 -32
- data/spec/vcr_cassettes/Inventory/Should_create_a_feed_again.yml +211 -0
- data/spec/vcr_cassettes/Inventory/Should_create_a_resource_.yml +355 -0
- data/spec/vcr_cassettes/Inventory/Should_create_a_resource_with_metric.yml +786 -0
- data/spec/vcr_cassettes/Inventory/Should_create_a_resourcetype.yml +205 -0
- data/spec/vcr_cassettes/Inventory/Should_create_and_delete_feed.yml +201 -0
- data/spec/vcr_cassettes/Inventory/Should_create_and_get_a_resource.yml +419 -0
- data/spec/vcr_cassettes/Inventory/Should_list_URLs.yml +39 -27
- data/spec/vcr_cassettes/Inventory/Should_list_WildFlys.yml +37 -29
- data/spec/vcr_cassettes/Inventory/Should_list_WildFlys_with_props.yml +53 -45
- data/spec/vcr_cassettes/Inventory/Should_list_all_the_resource_types.yml +177 -0
- data/spec/vcr_cassettes/Inventory/Should_list_children_of_WildFly.yml +230 -56
- data/spec/vcr_cassettes/Inventory/Should_list_feeds.yml +27 -24
- data/spec/vcr_cassettes/Inventory/Should_list_heap_metrics_for_WildFlys.yml +586 -119
- data/spec/vcr_cassettes/Inventory/Should_list_metrics_for_WildFlys.yml +220 -59
- data/spec/vcr_cassettes/Inventory/Should_list_metrics_of_given_metric_type.yml +613 -0
- data/spec/vcr_cassettes/Inventory/Should_list_metrics_of_given_resource_type.yml +333 -0
- data/spec/vcr_cassettes/Inventory/Should_list_recursive_children_of_WildFly.yml +2064 -0
- data/spec/vcr_cassettes/Inventory/Should_list_relationships_of_WildFly.yml +460 -0
- data/spec/vcr_cassettes/Inventory/Should_list_types_with_bad_feed.yml +26 -25
- data/spec/vcr_cassettes/Inventory/Should_list_types_with_feed.yml +102 -36
- data/spec/vcr_cassettes/Inventory/Should_not_find_an_unknown_resource.yml +54 -0
- data/spec/vcr_cassettes/Inventory/Tenants/Should_Get_Tenant_For_Explicit_Credentials.yml +50 -0
- data/spec/vcr_cassettes/Inventory/Tenants/Should_Get_Tenant_For_Implicit_Credentials.yml +50 -0
- data/spec/vcr_cassettes/Operation/Helpers/get_tenant.yml +50 -0
- data/spec/vcr_cassettes/Operation/Operation/Add_JDBC_driver_should_add_the_driver.json +26 -0
- data/spec/vcr_cassettes/Operation/Operation/Add_datasource_should_be_doable.json +26 -0
- data/spec/vcr_cassettes/Operation/Operation/Add_deployment_should_be_doable.json +26 -0
- data/spec/vcr_cassettes/Operation/Operation/Redeploy_can_be_run_multiple_times_in_parallel.json +40 -0
- data/spec/vcr_cassettes/Operation/Operation/Redeploy_should_be_performed_and_eventually_respond_with_success.json +26 -0
- data/spec/vcr_cassettes/Operation/Operation/Redeploy_should_not_be_performed_if_resource_path_is_wrong.json +26 -0
- data/spec/vcr_cassettes/Operation/Operation/Remove_JDBC_driver_should_be_performed_and_eventually_respond_with_success.json +26 -0
- data/spec/vcr_cassettes/Operation/Operation/Remove_datasource_should_be_performed_and_eventually_respond_with_success.json +26 -0
- data/spec/vcr_cassettes/Operation/Operation/Remove_deployment_should_be_performed_and_eventually_respond_with_success.json +26 -0
- data/spec/vcr_cassettes/Operation/Operation/Undeploy_should_be_performed_and_eventually_respond_with_success.json +26 -0
- data/spec/vcr_cassettes/Operation/Operation/should_not_be_possible_to_perform_on_closed_client.json +12 -0
- data/spec/vcr_cassettes/Operation/Websocket_connection/should_be_established.json +9 -0
- data/spec/vcr_cassettes/Tokens/Should_be_able_to_create_a_new_token_for_an_actual_user.yml +57 -0
- data/spec/vcr_cassettes/Tokens/Should_be_able_to_list_the_available_tokens.yml +49 -0
- data/spec/vcr_cassettes/Tokens/Should_get_a_401_when_attempting_to_create_a_token_with_a_wrong_password.yml +56 -0
- data/spec/vcr_cassettes/Tokens/Should_get_a_401_when_attempting_to_create_a_token_without_a_password.yml +55 -0
- metadata +175 -11
- data/lib/metrics/version.rb +0 -7
data/lib/hawkular.rb
CHANGED
|
@@ -21,7 +21,7 @@ module Hawkular
|
|
|
21
21
|
@credentials = {
|
|
22
22
|
username: nil,
|
|
23
23
|
password: nil,
|
|
24
|
-
token:
|
|
24
|
+
token: nil
|
|
25
25
|
}.merge(credentials)
|
|
26
26
|
@options = {
|
|
27
27
|
tenant: nil,
|
|
@@ -50,7 +50,13 @@ module Hawkular
|
|
|
50
50
|
# @param [String] url_part Part of an url to be escaped
|
|
51
51
|
# @return [String] escaped url_part as new string
|
|
52
52
|
def hawk_escape(url_part)
|
|
53
|
-
|
|
53
|
+
return url_part.to_s if url_part.is_a?(Numeric)
|
|
54
|
+
|
|
55
|
+
if url_part.is_a? Symbol
|
|
56
|
+
sub_url = url_part.to_s
|
|
57
|
+
else
|
|
58
|
+
sub_url = url_part.dup
|
|
59
|
+
end
|
|
54
60
|
sub_url.gsub!('%', '%25')
|
|
55
61
|
sub_url.gsub!(' ', '%20')
|
|
56
62
|
sub_url.gsub!('[', '%5b')
|
|
@@ -91,28 +97,17 @@ module Hawkular
|
|
|
91
97
|
# @!visibility private
|
|
92
98
|
def rest_client(suburl)
|
|
93
99
|
options[:timeout] = ENV['HAWKULARCLIENT_REST_TIMEOUT'] if ENV['HAWKULARCLIENT_REST_TIMEOUT']
|
|
94
|
-
options[:ssl_ca_file]
|
|
95
|
-
options[:verify_ssl]
|
|
100
|
+
options[:ssl_ca_file] = @options[:ssl_ca_file]
|
|
101
|
+
options[:verify_ssl] = @options[:verify_ssl]
|
|
96
102
|
options[:ssl_client_cert] = @options[:ssl_client_cert]
|
|
97
|
-
options[:ssl_client_key]
|
|
98
|
-
options[:user]
|
|
99
|
-
options[:password]
|
|
103
|
+
options[:ssl_client_key] = @options[:ssl_client_key]
|
|
104
|
+
options[:user] = @credentials[:username]
|
|
105
|
+
options[:password] = @credentials[:password]
|
|
100
106
|
# strip @endpoint in case suburl is absolute
|
|
101
107
|
suburl = suburl[@entrypoint.length, suburl.length] if suburl.match(/^http/)
|
|
102
108
|
RestClient::Resource.new(@entrypoint, options)[suburl]
|
|
103
109
|
end
|
|
104
110
|
|
|
105
|
-
# @!visibility private
|
|
106
|
-
def base_url
|
|
107
|
-
url = URI.parse(@entrypoint)
|
|
108
|
-
"#{url.scheme}://#{url.host}:#{url.port}"
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
# @!visibility private
|
|
112
|
-
def self.parse_response(response)
|
|
113
|
-
JSON.parse(response)
|
|
114
|
-
end
|
|
115
|
-
|
|
116
111
|
# @!visibility private
|
|
117
112
|
def http_headers(headers = {})
|
|
118
113
|
{}.merge(tenant_header)
|
|
@@ -140,50 +135,34 @@ module Hawkular
|
|
|
140
135
|
encoded.rstrip!
|
|
141
136
|
end
|
|
142
137
|
|
|
143
|
-
# Generate a query string from the passed hash
|
|
144
|
-
# This string starts with a `?` if the hash is
|
|
145
|
-
# not empty.
|
|
138
|
+
# Generate a query string from the passed hash, starting with '?'
|
|
146
139
|
# Values may be an array, in which case the array values are joined together by `,`.
|
|
147
|
-
# @param
|
|
148
|
-
# @return [String] complete query string to append to a base url
|
|
149
|
-
def generate_query_params(
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
param_hash.each do |k, v|
|
|
158
|
-
next if not_suitable?(v)
|
|
159
|
-
|
|
160
|
-
if v.instance_of? Array
|
|
161
|
-
part = "#{k}=#{v.join(',')}"
|
|
162
|
-
else
|
|
163
|
-
part = "#{k}=#{v}"
|
|
164
|
-
end
|
|
165
|
-
|
|
166
|
-
ret += hawk_escape part
|
|
167
|
-
|
|
168
|
-
i += 1
|
|
169
|
-
ret += '&' if i < num
|
|
140
|
+
# @param params [Hash] key-values pairs
|
|
141
|
+
# @return [String] complete query string to append to a base url, '' if no valid params
|
|
142
|
+
def generate_query_params(params = {})
|
|
143
|
+
params = params.select { |_k, v| !(v.nil? || ((v.instance_of? Array) && v.empty?)) }
|
|
144
|
+
return '' if params.empty?
|
|
145
|
+
|
|
146
|
+
params.inject('?') do |ret, (k, v)|
|
|
147
|
+
ret += '&' unless ret == '?'
|
|
148
|
+
part = (v.instance_of? Array) ? "#{k}=#{v.join(',')}" : "#{k}=#{v}"
|
|
149
|
+
ret + hawk_escape(part)
|
|
170
150
|
end
|
|
171
|
-
ret
|
|
172
151
|
end
|
|
173
152
|
|
|
174
|
-
|
|
153
|
+
# Specialized exception to be thrown
|
|
154
|
+
# when the interaction with Hawkular fails
|
|
155
|
+
class HawkularException < StandardError
|
|
156
|
+
def initialize(message, status_code = 0)
|
|
157
|
+
@message = message
|
|
158
|
+
@status_code = status_code
|
|
159
|
+
super(message)
|
|
160
|
+
end
|
|
175
161
|
|
|
176
|
-
|
|
177
|
-
v.nil? || (v.instance_of? Array) && v.size == 0
|
|
162
|
+
attr_reader :message, :status_code
|
|
178
163
|
end
|
|
179
164
|
|
|
180
|
-
|
|
181
|
-
num = 0
|
|
182
|
-
param_hash.each do |_k, v|
|
|
183
|
-
num += 1 unless not_suitable?(v)
|
|
184
|
-
end
|
|
185
|
-
num
|
|
186
|
-
end
|
|
165
|
+
private
|
|
187
166
|
|
|
188
167
|
def token_header
|
|
189
168
|
@credentials[:token].nil? ? {} : { 'Authorization' => "Bearer #{@credentials[:token]}" }
|
|
@@ -202,21 +181,10 @@ module Hawkular
|
|
|
202
181
|
rescue JSON::ParserError
|
|
203
182
|
fault_message = f.http_body
|
|
204
183
|
end
|
|
205
|
-
fail HawkularException,
|
|
184
|
+
fail HawkularException.new(fault_message, (f.respond_to?(:http_code) ? f.http_code : 0))
|
|
206
185
|
else
|
|
207
186
|
fail f
|
|
208
187
|
end
|
|
209
188
|
end
|
|
210
189
|
end
|
|
211
|
-
|
|
212
|
-
# Specialized exception to be thrown
|
|
213
|
-
# when the interction with Hawkular fails
|
|
214
|
-
class HawkularException < StandardError
|
|
215
|
-
def initialize(message)
|
|
216
|
-
@message = message
|
|
217
|
-
super
|
|
218
|
-
end
|
|
219
|
-
|
|
220
|
-
attr_reader :message
|
|
221
|
-
end
|
|
222
190
|
end
|
data/lib/hawkular_all.rb
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
require 'hawkular'
|
|
2
|
+
require 'websocket-client-simple'
|
|
3
|
+
require 'json'
|
|
2
4
|
|
|
3
5
|
# Inventory module provides access to the Hawkular Inventory REST API.
|
|
4
6
|
# @see http://www.hawkular.org/docs/rest/rest-inventory.html
|
|
@@ -14,10 +16,19 @@ module Hawkular::Inventory
|
|
|
14
16
|
# @param credentials [Hash{String=>String}] Hash of username, password, token(optional)
|
|
15
17
|
def initialize(entrypoint = nil, credentials = {})
|
|
16
18
|
@entrypoint = entrypoint
|
|
17
|
-
|
|
18
19
|
super(entrypoint, credentials)
|
|
19
20
|
end
|
|
20
21
|
|
|
22
|
+
# Creates a new Inventory Client
|
|
23
|
+
# @param hash [Hash{String=>Object}] a hash containing base url of Hawkular-inventory - e.g
|
|
24
|
+
# entrypoint: http://localhost:8080/hawkular/inventory
|
|
25
|
+
# and another sub-hash containing the hash with username[String], password[String], token(optional)
|
|
26
|
+
def self.create(hash)
|
|
27
|
+
hash[:entrypoint] ||= 'http://localhost:8080/hawkular/inventory'
|
|
28
|
+
hash[:credentials] ||= {}
|
|
29
|
+
InventoryClient.new(hash[:entrypoint], hash[:credentials])
|
|
30
|
+
end
|
|
31
|
+
|
|
21
32
|
# Retrieve the tenant id for the passed credentials.
|
|
22
33
|
# If no credentials are passed, the ones from the constructor are used
|
|
23
34
|
# @param credentials [Hash{String=>String}] Hash of username, password, token(optional)
|
|
@@ -32,7 +43,7 @@ module Hawkular::Inventory
|
|
|
32
43
|
end
|
|
33
44
|
|
|
34
45
|
# TODO: revisit and potentially move to Base ?
|
|
35
|
-
def impersonate(credentials = {})
|
|
46
|
+
def impersonate!(credentials = {})
|
|
36
47
|
@tenant = get_tenant(credentials)
|
|
37
48
|
@options[:tenant] = @tenant
|
|
38
49
|
end
|
|
@@ -41,9 +52,7 @@ module Hawkular::Inventory
|
|
|
41
52
|
# @return [Array<String>] List of feed ids
|
|
42
53
|
def list_feeds(_environment = 'test')
|
|
43
54
|
ret = http_get('feeds')
|
|
44
|
-
|
|
45
|
-
ret.each { |f| val.push(f['id']) }
|
|
46
|
-
val
|
|
55
|
+
ret.map { |f| f['id'] }
|
|
47
56
|
end
|
|
48
57
|
|
|
49
58
|
# List resource types. If no need is given all types are listed
|
|
@@ -54,17 +63,32 @@ module Hawkular::Inventory
|
|
|
54
63
|
ret = http_get('/resourceTypes')
|
|
55
64
|
else
|
|
56
65
|
the_feed = hawk_escape feed
|
|
57
|
-
ret = http_get(
|
|
66
|
+
ret = http_get("/feeds/#{the_feed}/resourceTypes")
|
|
67
|
+
end
|
|
68
|
+
ret.map { |rt| ResourceType.new(rt) }
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Return all resources for a feed
|
|
72
|
+
# @param [String] feed Id of the feed that hosts the resources
|
|
73
|
+
# @param [Boolean] fetch_properties Should the config data be fetched too
|
|
74
|
+
# @return [Array<Resource>] List of resources, which can be empty.
|
|
75
|
+
def list_resources_for_feed(feed, fetch_properties = false)
|
|
76
|
+
fail 'Feed must be given' unless feed
|
|
77
|
+
the_feed = hawk_escape feed
|
|
78
|
+
ret = http_get("/feeds/#{the_feed}/resources")
|
|
79
|
+
ret.map do |r|
|
|
80
|
+
if fetch_properties
|
|
81
|
+
p = get_config_data_for_resource(r['id'], feed)
|
|
82
|
+
r['properties'] = p['value']
|
|
83
|
+
end
|
|
84
|
+
Resource.new(r)
|
|
58
85
|
end
|
|
59
|
-
val = []
|
|
60
|
-
ret.each { |rt| val.push(ResourceType.new(rt)) }
|
|
61
|
-
val
|
|
62
86
|
end
|
|
63
87
|
|
|
64
88
|
# List the resources for the passed feed and resource type. The representation for
|
|
65
89
|
# resources under a feed are sparse and additional data must be retrived separately.
|
|
66
90
|
# It is possible though to also obtain runtime properties by setting #fetch_properties to true.
|
|
67
|
-
# @param [String] feed The id of the feed the type lives under. Can be nil for
|
|
91
|
+
# @param [String] feed The id of the feed the type lives under. Can be nil for all feeds
|
|
68
92
|
# @param [String] type Name of the type to look for. Can be obtained from {ResourceType}.id.
|
|
69
93
|
# Must not be nil
|
|
70
94
|
# @param [Boolean] fetch_properties Shall additional runtime properties be fetched?
|
|
@@ -73,21 +97,19 @@ module Hawkular::Inventory
|
|
|
73
97
|
fail 'Type must not be nil' unless type
|
|
74
98
|
the_type = hawk_escape type
|
|
75
99
|
if feed.nil?
|
|
76
|
-
ret = http_get(
|
|
100
|
+
ret = http_get("resourceTypes/#{the_type}/resources")
|
|
77
101
|
else
|
|
78
102
|
|
|
79
103
|
the_feed = hawk_escape feed
|
|
80
|
-
ret = http_get(
|
|
104
|
+
ret = http_get("/feeds/#{the_feed}/resourceTypes/#{the_type}/resources")
|
|
81
105
|
end
|
|
82
|
-
|
|
83
|
-
ret.each do |r|
|
|
106
|
+
ret.map do |r|
|
|
84
107
|
if fetch_properties && !feed.nil?
|
|
85
108
|
p = get_config_data_for_resource(r['id'], feed)
|
|
86
109
|
r['properties'] = p['value']
|
|
87
110
|
end
|
|
88
|
-
|
|
111
|
+
Resource.new(r)
|
|
89
112
|
end
|
|
90
|
-
val
|
|
91
113
|
end
|
|
92
114
|
|
|
93
115
|
# Retrieve runtime properties for the passed resource
|
|
@@ -97,7 +119,8 @@ module Hawkular::Inventory
|
|
|
97
119
|
def get_config_data_for_resource(resource_id, feed)
|
|
98
120
|
the_id = hawk_escape resource_id
|
|
99
121
|
the_feed = hawk_escape feed
|
|
100
|
-
|
|
122
|
+
query = generate_query_params dataType: 'configuration'
|
|
123
|
+
http_get("feeds/#{the_feed}/resources/#{the_id}/data#{query}")
|
|
101
124
|
rescue
|
|
102
125
|
{}
|
|
103
126
|
end
|
|
@@ -105,47 +128,48 @@ module Hawkular::Inventory
|
|
|
105
128
|
# Obtain the child resources of the passed resource. In case of a WildFly server,
|
|
106
129
|
# those would be Datasources, Deployments and so on.
|
|
107
130
|
# @param [Resource] parent_resource Resource to obtain children from
|
|
131
|
+
# @param [Boolean] recursive Whether to fetch also all the children of children of ...
|
|
108
132
|
# @return [Array<Resource>] List of resources that are children of the given parent resource.
|
|
109
133
|
# Can be empty
|
|
110
|
-
def list_child_resources(parent_resource)
|
|
134
|
+
def list_child_resources(parent_resource, recursive = false)
|
|
111
135
|
the_feed = hawk_escape parent_resource.feed
|
|
112
136
|
the_id = hawk_escape parent_resource.id
|
|
113
137
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
ret.each { |r| val.push(Resource.new(r)) }
|
|
118
|
-
val
|
|
138
|
+
which_children = (recursive ? '/recursiveChildren' : '/children')
|
|
139
|
+
ret = http_get("/feeds/#{the_feed}/resources/#{the_id}#{which_children}")
|
|
140
|
+
ret.map { |r| Resource.new(r) }
|
|
119
141
|
end
|
|
120
142
|
|
|
121
143
|
# Obtain a list of relationships starting at the passed resource
|
|
122
144
|
# @param [Resource] resource One end of the relationship
|
|
145
|
+
# @param [String] named Name of the relationship
|
|
123
146
|
# @return [Array<Relationship>] List of relationships
|
|
124
|
-
def list_relationships(resource)
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
ret = http_get('/feeds/' + the_feed + '/resources/' + the_id + '/relationships')
|
|
129
|
-
val = []
|
|
130
|
-
ret.each { |r| val.push(Relationship.new(r)) }
|
|
131
|
-
val
|
|
132
|
-
rescue
|
|
133
|
-
[]
|
|
147
|
+
def list_relationships(resource, named = nil)
|
|
148
|
+
query = named.nil? ? '' : (generate_query_params named: named)
|
|
149
|
+
ret = http_get("/path#{resource.path}/relationships#{query}")
|
|
150
|
+
ret.map { |r| Relationship.new(r) }
|
|
134
151
|
end
|
|
135
152
|
|
|
136
153
|
# Obtain a list of relationships for the passed feed
|
|
137
154
|
# @param [String] feed_id Id of the feed
|
|
155
|
+
# @param [String] named Name of the relationship
|
|
138
156
|
# @return [Array<Relationship>] List of relationships
|
|
139
|
-
def list_relationships_for_feed(feed_id)
|
|
157
|
+
def list_relationships_for_feed(feed_id, named = nil)
|
|
140
158
|
the_feed = hawk_escape feed_id
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
ret.
|
|
144
|
-
val
|
|
159
|
+
query = named.nil? ? '' : (generate_query_params named: named)
|
|
160
|
+
ret = http_get("/feeds/#{the_feed}/relationships#{query}")
|
|
161
|
+
ret.map { |r| Relationship.new(r) }
|
|
145
162
|
rescue
|
|
146
163
|
[]
|
|
147
164
|
end
|
|
148
165
|
|
|
166
|
+
# Retrieve a single entity from inventory by its canonical path
|
|
167
|
+
# @param [CanonicalPath] path canonical path of the entity
|
|
168
|
+
# @return inventory entity
|
|
169
|
+
def get_entity(path)
|
|
170
|
+
http_get("path#{path}")
|
|
171
|
+
end
|
|
172
|
+
|
|
149
173
|
# [15:01:51] <jkremser> pilhuhn, this works for me curl -XPOST
|
|
150
174
|
# -H "Content-Type: application/json"
|
|
151
175
|
# -u jdoe:password -d
|
|
@@ -166,9 +190,59 @@ module Hawkular::Inventory
|
|
|
166
190
|
# rel.to_h)
|
|
167
191
|
# end
|
|
168
192
|
|
|
169
|
-
#
|
|
170
|
-
#
|
|
171
|
-
#
|
|
193
|
+
# List the metrics for the passed feed and metric type. If feed is not passed,
|
|
194
|
+
# all the metrics across all the feeds of a given type will be retrieved
|
|
195
|
+
# This method may perform multiple REST calls.
|
|
196
|
+
# @param [String] feed The id of the feed the type lives under. Can be nil for all feeds
|
|
197
|
+
# @param [String] type Name of the metric type to look for. Can be obtained from {MetricType}.id.
|
|
198
|
+
# Must not be nil
|
|
199
|
+
# @return [Array<Metric>] List of metrics. Can be empty
|
|
200
|
+
def list_metrics_for_metric_type(feed, type)
|
|
201
|
+
fail 'Type must not be nil' unless type
|
|
202
|
+
the_type = hawk_escape type
|
|
203
|
+
if feed.nil?
|
|
204
|
+
type_hash = http_get("metricTypes/#{the_type}")
|
|
205
|
+
else
|
|
206
|
+
the_feed = hawk_escape feed
|
|
207
|
+
type_hash = http_get("/feeds/#{the_feed}/metricTypes/#{the_type}")
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
rels = list_relationships(ResourceType.new(type_hash), 'defines')
|
|
211
|
+
rels.map do |rel|
|
|
212
|
+
path = CanonicalPath.parse(rel.target_id.to_s)
|
|
213
|
+
metric_hash = get_entity path
|
|
214
|
+
Metric.new(metric_hash)
|
|
215
|
+
end
|
|
216
|
+
rescue
|
|
217
|
+
[]
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
# List the metrics for the passed feed and all the resources of given resource type.
|
|
221
|
+
# If feed is not passed, all the metrics across all the feeds of a resource type will be retrieved
|
|
222
|
+
# This method may perform multiple REST calls.
|
|
223
|
+
# @param [String] feed The id of the feed the type lives under. Can be nil for all feeds
|
|
224
|
+
# @param [String] type Name of the resource type to look for. Can be obtained from {ResourceType}.id.
|
|
225
|
+
# Must not be nil
|
|
226
|
+
# @return [Array<Metric>] List of metrics. Can be empty
|
|
227
|
+
def list_metrics_for_resource_type(feed, type)
|
|
228
|
+
fail 'Type must not be nil' unless type
|
|
229
|
+
the_type = hawk_escape type
|
|
230
|
+
if feed.nil?
|
|
231
|
+
ret = http_get("resourceTypes/#{the_type}/resources")
|
|
232
|
+
else
|
|
233
|
+
the_feed = hawk_escape feed
|
|
234
|
+
ret = http_get("feeds/#{the_feed}/resourceTypes/#{the_type}/resources")
|
|
235
|
+
end
|
|
236
|
+
ret.flat_map do |r|
|
|
237
|
+
path = CanonicalPath.parse(r['path'])
|
|
238
|
+
if !path.feed_id.nil?
|
|
239
|
+
nested_ret = http_get("feeds/#{path.feed_id}/resources/#{path.resource_ids.join('/')}/metrics")
|
|
240
|
+
else
|
|
241
|
+
nested_ret = http_get("#{path.environment_id}/resources/#{path.resource_ids.join('/')}/metrics")
|
|
242
|
+
end
|
|
243
|
+
nested_ret.map { |m| Metric.new(m) }
|
|
244
|
+
end
|
|
245
|
+
end
|
|
172
246
|
|
|
173
247
|
# List metric (definitions) for the passed resource. It is possible to filter down the
|
|
174
248
|
# result by a filter to only return a subset. The
|
|
@@ -176,7 +250,7 @@ module Hawkular::Inventory
|
|
|
176
250
|
# @param [Hash{Symbol=>String}] filter for 'type' and 'match'
|
|
177
251
|
# Metric type can be one of 'GAUGE', 'COUNTER', 'AVAILABILITY'. If a key is missing
|
|
178
252
|
# it will not be used for filtering
|
|
179
|
-
# @return [
|
|
253
|
+
# @return [Array<Metric>] List of metrics that can be empty.
|
|
180
254
|
# @example
|
|
181
255
|
# # Filter by type and match on metrics id
|
|
182
256
|
# client.list_metrics_for_resource(wild_fly, type: 'GAUGE', match: 'Metrics~Heap')
|
|
@@ -188,20 +262,229 @@ module Hawkular::Inventory
|
|
|
188
262
|
the_feed = hawk_escape resource.feed
|
|
189
263
|
the_id = hawk_escape resource.id
|
|
190
264
|
|
|
191
|
-
ret = http_get(
|
|
192
|
-
|
|
193
|
-
the_id + '/metrics')
|
|
194
|
-
val = []
|
|
195
|
-
ret.each do |m|
|
|
265
|
+
ret = http_get("/feeds/#{the_feed}/resources/#{the_id}/metrics")
|
|
266
|
+
with_nils = ret.map do |m|
|
|
196
267
|
metric_new = Metric.new(m)
|
|
197
268
|
found = should_include?(metric_new, filter)
|
|
198
|
-
|
|
269
|
+
metric_new if found
|
|
270
|
+
end
|
|
271
|
+
with_nils.compact
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
# Create a new feed
|
|
275
|
+
# @param [String] feed_id Id of a feed - required
|
|
276
|
+
# @param [String] feed_name A display name for the feed
|
|
277
|
+
# @return [Object]
|
|
278
|
+
def create_feed(feed_id, feed_name = nil)
|
|
279
|
+
feed = create_blueprint
|
|
280
|
+
feed[:id] = feed_id
|
|
281
|
+
feed[:name] = feed_name
|
|
282
|
+
|
|
283
|
+
begin
|
|
284
|
+
return http_post('/feeds/', feed)
|
|
285
|
+
rescue HawkularException => error
|
|
286
|
+
# 409 We already exist -> that is ok
|
|
287
|
+
if error.status_code == 409
|
|
288
|
+
the_feed = hawk_escape feed_id
|
|
289
|
+
http_get("/feeds/#{the_feed}")
|
|
290
|
+
else
|
|
291
|
+
raise
|
|
292
|
+
end
|
|
293
|
+
end
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
# Delete the feed with the passed feed id.
|
|
297
|
+
# @param feed Id of the feed to be deleted.
|
|
298
|
+
def delete_feed(feed)
|
|
299
|
+
the_feed = hawk_escape feed
|
|
300
|
+
http_delete("/feeds/#{the_feed}")
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
# Create a new resource type
|
|
304
|
+
# @param [String] feed_id Id of the feed to add the type to
|
|
305
|
+
# @param [String] type_id Id of the new type
|
|
306
|
+
# @param [String] type_name Name of the type
|
|
307
|
+
# @return [ResourceType] ResourceType object just created
|
|
308
|
+
def create_resource_type(feed_id, type_id, type_name)
|
|
309
|
+
the_feed = hawk_escape feed_id
|
|
310
|
+
|
|
311
|
+
type = create_blueprint
|
|
312
|
+
type[:id] = type_id
|
|
313
|
+
type[:name] = type_name
|
|
314
|
+
|
|
315
|
+
begin
|
|
316
|
+
http_post("/feeds/#{the_feed}/resourceTypes", type)
|
|
317
|
+
rescue HawkularException => error
|
|
318
|
+
# 409 We already exist -> that is ok
|
|
319
|
+
raise unless error.status_code == 409
|
|
320
|
+
ensure
|
|
321
|
+
the_type = hawk_escape type_id
|
|
322
|
+
res = http_get("/feeds/#{the_feed}/resourceTypes/#{the_type}")
|
|
199
323
|
end
|
|
200
|
-
|
|
324
|
+
ResourceType.new(res)
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
# Create a resource of a given type under a given feed. To retrieve that resource
|
|
328
|
+
# you need to call {#get_resource}
|
|
329
|
+
# @param [String] feed_id Id of the feed to add the resource to
|
|
330
|
+
# @param [String] type_path Path of the resource type of this resource
|
|
331
|
+
# @param [String] resource_id Id of the resource
|
|
332
|
+
# @param [String] resource_name Name of the resource
|
|
333
|
+
# @param [Hash<String,Object>] properties Additional properties. Those are not the config-properties
|
|
334
|
+
# TODO allow to create this as child of another resource
|
|
335
|
+
def create_resource(feed_id, type_path, resource_id, resource_name = nil, properties = {})
|
|
336
|
+
the_feed = hawk_escape feed_id
|
|
337
|
+
|
|
338
|
+
res = create_blueprint
|
|
339
|
+
res[:properties] = properties
|
|
340
|
+
res[:id] = resource_id
|
|
341
|
+
res[:name] = resource_name
|
|
342
|
+
res[:resourceTypePath] = type_path
|
|
343
|
+
|
|
344
|
+
begin
|
|
345
|
+
http_post("/feeds/#{the_feed}/resources", res)
|
|
346
|
+
rescue HawkularException => error
|
|
347
|
+
# 409 We already exist -> that is ok
|
|
348
|
+
raise unless error.status_code == 409
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
get_resource feed_id, resource_id, false
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
# Return the resource object for the passed id
|
|
355
|
+
# @param [String] feed_id Id of the feed this resource belongs to
|
|
356
|
+
# @param [String] res_id Id of the resource to fetch
|
|
357
|
+
# @param [Boolean] fetch_resource_config Should the resource config data be fetched?
|
|
358
|
+
def get_resource(feed_id, res_id, fetch_resource_config = true)
|
|
359
|
+
the_feed = hawk_escape feed_id
|
|
360
|
+
the_resource = hawk_escape res_id
|
|
361
|
+
|
|
362
|
+
res = http_get("/feeds/#{the_feed}/resources/#{the_resource}")
|
|
363
|
+
if fetch_resource_config
|
|
364
|
+
p = get_config_data_for_resource(res_id, feed_id)
|
|
365
|
+
res['properties'].merge p['value'] unless p['value'].nil?
|
|
366
|
+
end
|
|
367
|
+
Resource.new(res)
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
# Create a new metric type for a feed
|
|
371
|
+
# @param [String] feed_id Id of the feed
|
|
372
|
+
# @param [String] metric_type_id Id of the metric type to create
|
|
373
|
+
# @param [String] type Type of the Metric. Allowed are GAUGE,COUNTER, AVAILABILITY
|
|
374
|
+
# @param [String] unit Unit of the metric
|
|
375
|
+
# @param [Numeric] collection_interval
|
|
376
|
+
# @return [MetricType] Type just created or the one from the server if it already existed.
|
|
377
|
+
def create_metric_type(feed_id, metric_type_id, type = 'GAUGE', unit = 'NONE', collection_interval = 60)
|
|
378
|
+
the_feed = hawk_escape feed_id
|
|
379
|
+
|
|
380
|
+
metric_kind = type.nil? ? 'GAUGE' : type.upcase
|
|
381
|
+
fail "Unknown type #{metric_kind}" unless %w(GAUGE COUNTER AVAILABILITY').include?(metric_kind)
|
|
382
|
+
|
|
383
|
+
mt = build_metric_type_hash(collection_interval, metric_kind, metric_type_id, unit)
|
|
384
|
+
|
|
385
|
+
begin
|
|
386
|
+
http_post("/feeds/#{the_feed}/metricTypes", mt)
|
|
387
|
+
rescue HawkularException => error
|
|
388
|
+
# 409 We already exist -> that is ok
|
|
389
|
+
raise unless error.status_code == 409
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
new_mt = http_get("/feeds/#{the_feed}/metricTypes/#{metric_type_id}")
|
|
393
|
+
|
|
394
|
+
MetricType.new(new_mt)
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
# Create a Metric and associate it with a resource.
|
|
398
|
+
# @param [String] feed_id Id of the feed
|
|
399
|
+
# @param [String] metric_id Id of the metric
|
|
400
|
+
# @param [String] type_path Full path of the MetricType
|
|
401
|
+
# @param [String] resource_id Id of the resource to associate the metric with
|
|
402
|
+
# @param [String] metric_name a (display) name for the metric. If nil, #metric_id is used.
|
|
403
|
+
# @return [Metric] The metric created or if it already existed the version from the server
|
|
404
|
+
def create_metric_for_resource(feed_id, metric_id, type_path, resource_id, metric_name = nil)
|
|
405
|
+
the_feed = hawk_escape feed_id
|
|
406
|
+
the_resource = hawk_escape resource_id
|
|
407
|
+
|
|
408
|
+
m = {}
|
|
409
|
+
m['id'] = metric_id
|
|
410
|
+
m['name'] = (metric_name.nil?) ? metric_id : metric_name
|
|
411
|
+
m['metricTypePath'] = type_path
|
|
412
|
+
|
|
413
|
+
begin
|
|
414
|
+
http_post("/feeds/#{the_feed}/metrics", m)
|
|
415
|
+
rescue HawkularException => error
|
|
416
|
+
# 409 We already exist -> that is ok
|
|
417
|
+
raise unless error.status_code == 409
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
ret = http_get("/feeds/#{the_feed}/metrics/#{metric_id}")
|
|
421
|
+
the_metric = Metric.new(ret)
|
|
422
|
+
|
|
423
|
+
begin
|
|
424
|
+
http_post("/feeds/#{the_feed}/resources/#{the_resource}/metrics", [the_metric.path])
|
|
425
|
+
rescue HawkularException => error
|
|
426
|
+
# 409 We already exist -> that is ok
|
|
427
|
+
raise unless error.status_code == 409
|
|
428
|
+
end
|
|
429
|
+
the_metric
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
# Listen on inventory changes
|
|
433
|
+
# @param [String] type Type of entity for which we want the events.
|
|
434
|
+
# Allowed values: resource, metric, resourcetype, metrictype, feed, environment, operationtype, metadatapack
|
|
435
|
+
# @param [String] action What types of events are we interested in.
|
|
436
|
+
# Allowed values: created, updated, deleted, copied, registered
|
|
437
|
+
def events(type = 'resource', action = 'created')
|
|
438
|
+
tenant_id = get_tenant
|
|
439
|
+
url = "#{entrypoint.gsub(/https?/, 'ws')}/ws/events?tenantId=#{tenant_id}&type=#{type}&action=#{action}"
|
|
440
|
+
@ws = WebSocket::Client::Simple.connect url do |client|
|
|
441
|
+
client.on :message do |msg|
|
|
442
|
+
parsed_message = JSON.parse(msg.data)
|
|
443
|
+
entity = case type
|
|
444
|
+
when 'resource'
|
|
445
|
+
Resource.new(parsed_message)
|
|
446
|
+
when 'resourcetype'
|
|
447
|
+
ResourceType.new(parsed_message)
|
|
448
|
+
when 'metric'
|
|
449
|
+
Metric.new(parsed_message)
|
|
450
|
+
when 'metrictype'
|
|
451
|
+
MetricType.new(parsed_message)
|
|
452
|
+
else
|
|
453
|
+
BaseEntity.new(parsed_message)
|
|
454
|
+
end
|
|
455
|
+
yield entity
|
|
456
|
+
end
|
|
457
|
+
end
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
# Stop listening on inventory events.
|
|
461
|
+
# this method closes the web socket connection
|
|
462
|
+
def no_more_events!
|
|
463
|
+
@ws.close
|
|
201
464
|
end
|
|
202
465
|
|
|
203
466
|
private
|
|
204
467
|
|
|
468
|
+
# Creates a hash with the fields required by the Blueprint api in Hawkular-Inventory
|
|
469
|
+
def create_blueprint
|
|
470
|
+
res = {}
|
|
471
|
+
res[:properties] = {}
|
|
472
|
+
res[:id] = nil
|
|
473
|
+
res[:name] = nil
|
|
474
|
+
res[:outgoing] = {}
|
|
475
|
+
res[:incoming] = {}
|
|
476
|
+
res
|
|
477
|
+
end
|
|
478
|
+
|
|
479
|
+
def build_metric_type_hash(collection_interval, metric_kind, metric_type_id, unit)
|
|
480
|
+
mt = {}
|
|
481
|
+
mt['id'] = metric_type_id
|
|
482
|
+
mt['type'] = metric_kind
|
|
483
|
+
mt['unit'] = unit.nil? ? 'NONE' : unit.upcase
|
|
484
|
+
mt['collectionInterval'] = collection_interval.nil? ? 60 : collection_interval
|
|
485
|
+
mt
|
|
486
|
+
end
|
|
487
|
+
|
|
205
488
|
def should_include?(metric_new, filter)
|
|
206
489
|
found = true
|
|
207
490
|
if filter.empty?
|
|
@@ -214,32 +497,31 @@ module Hawkular::Inventory
|
|
|
214
497
|
end
|
|
215
498
|
end
|
|
216
499
|
|
|
217
|
-
# A
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
# (more or less) the same.
|
|
221
|
-
class ResourceType
|
|
222
|
-
# @return [String] Full path of the type
|
|
500
|
+
# A Basic inventory entity with id, name, path and optional properties
|
|
501
|
+
class BaseEntity
|
|
502
|
+
# @return [String] Full path of the entity
|
|
223
503
|
attr_reader :path
|
|
224
|
-
# @return [String] Name of the
|
|
504
|
+
# @return [String] Name of the entity
|
|
225
505
|
attr_reader :name
|
|
226
|
-
# @return [String] Name of the
|
|
506
|
+
# @return [String] Name of the entity
|
|
227
507
|
attr_reader :id
|
|
228
|
-
# @return [String] Feed this
|
|
508
|
+
# @return [String] Feed this entity belongs to (or nil in case of a feedless entity)
|
|
229
509
|
attr_reader :feed
|
|
230
|
-
# @return [String]
|
|
510
|
+
# @return [String] Name of the environment for this entity
|
|
231
511
|
attr_reader :env
|
|
232
|
-
# @return [String] Properties of this
|
|
512
|
+
# @return [String] Properties of this entity
|
|
233
513
|
attr_reader :properties
|
|
234
514
|
|
|
235
|
-
def initialize(
|
|
236
|
-
@id =
|
|
237
|
-
@path =
|
|
238
|
-
@name =
|
|
239
|
-
@properties =
|
|
240
|
-
@_hash =
|
|
515
|
+
def initialize(hash)
|
|
516
|
+
@id = hash['id']
|
|
517
|
+
@path = hash['path']
|
|
518
|
+
@name = hash['name'] || @id
|
|
519
|
+
@properties = hash['properties'] || {}
|
|
520
|
+
@_hash = hash.dup
|
|
241
521
|
|
|
242
|
-
|
|
522
|
+
return if @path.nil?
|
|
523
|
+
|
|
524
|
+
tmp = @path.split('/')
|
|
243
525
|
tmp.each do |pair|
|
|
244
526
|
(key, val) = pair.split(';')
|
|
245
527
|
case key
|
|
@@ -258,89 +540,59 @@ module Hawkular::Inventory
|
|
|
258
540
|
end
|
|
259
541
|
end
|
|
260
542
|
|
|
543
|
+
# A ResourceType is like a class definition for {Resource}s
|
|
544
|
+
# ResourceTypes are currently unique per feed, but one can assume
|
|
545
|
+
# that a two types with the same name of two different feeds are
|
|
546
|
+
# (more or less) the same.
|
|
547
|
+
class ResourceType < BaseEntity
|
|
548
|
+
def initialize(rt_hash)
|
|
549
|
+
super(rt_hash)
|
|
550
|
+
end
|
|
551
|
+
end
|
|
552
|
+
|
|
261
553
|
# A Resource is an instantiation of a {ResourceType}
|
|
262
|
-
class Resource
|
|
263
|
-
# @return [String] Full path of the resource including feed id
|
|
264
|
-
attr_reader :path
|
|
265
|
-
# @return [String] Name of the resource
|
|
266
|
-
attr_reader :name
|
|
267
|
-
# @return [String] Name of the resource
|
|
268
|
-
attr_reader :id
|
|
269
|
-
# @return [String] Name of the feed for this resource
|
|
270
|
-
attr_reader :feed
|
|
271
|
-
# @return [String] Name of the environment for this resource -- currently unused
|
|
272
|
-
attr_reader :env
|
|
554
|
+
class Resource < BaseEntity
|
|
273
555
|
# @return [String] Full path of the {ResourceType}
|
|
274
556
|
attr_reader :type_path
|
|
275
|
-
# @return [Hash<String,Object>] Hash with additional, resource specific properties
|
|
276
|
-
attr_reader :properties
|
|
277
557
|
|
|
278
558
|
def initialize(res_hash)
|
|
279
|
-
|
|
280
|
-
@
|
|
281
|
-
@properties = res_hash['properties'] || {}
|
|
559
|
+
super(res_hash)
|
|
560
|
+
@type = res_hash['type']
|
|
282
561
|
@type_path = res_hash['type']['path']
|
|
283
|
-
@_hash = res_hash
|
|
284
|
-
|
|
285
|
-
tmp = @path.split('/')
|
|
286
|
-
tmp.each do |pair|
|
|
287
|
-
(key, val) = pair.split(';')
|
|
288
|
-
case key
|
|
289
|
-
when 'f'
|
|
290
|
-
@feed = val
|
|
291
|
-
when 'e'
|
|
292
|
-
@env = val
|
|
293
|
-
when 'n'
|
|
294
|
-
@name = val.nil? ? id : val
|
|
295
|
-
end
|
|
296
|
-
end
|
|
297
|
-
self
|
|
298
562
|
end
|
|
563
|
+
end
|
|
299
564
|
|
|
300
|
-
|
|
301
|
-
|
|
565
|
+
class MetricType < BaseEntity
|
|
566
|
+
# @return [String] GAUGE, COUNTER, etc.
|
|
567
|
+
attr_reader :type
|
|
568
|
+
# @return [String] metric unit such as NONE, BYTES, etc.
|
|
569
|
+
attr_reader :unit
|
|
570
|
+
# @return [Long] collection interval in seconds
|
|
571
|
+
attr_reader :collection_interval
|
|
572
|
+
|
|
573
|
+
def initialize(type_hash)
|
|
574
|
+
super(type_hash)
|
|
575
|
+
@type = type_hash['type']
|
|
576
|
+
@unit = type_hash['unit']
|
|
577
|
+
@collection_interval = type_hash['collectionInterval']
|
|
302
578
|
end
|
|
303
579
|
end
|
|
304
580
|
|
|
305
581
|
# Definition of a Metric inside the inventory.
|
|
306
|
-
class Metric
|
|
307
|
-
# @return [String]
|
|
308
|
-
attr_reader :path
|
|
309
|
-
# @return [String] Name of the metric
|
|
310
|
-
attr_reader :name
|
|
311
|
-
attr_reader :id
|
|
312
|
-
attr_reader :feed
|
|
313
|
-
attr_reader :env
|
|
582
|
+
class Metric < BaseEntity
|
|
583
|
+
# @return [String] GAUGE, COUNTER, etc.
|
|
314
584
|
attr_reader :type
|
|
585
|
+
# @return [String] metric unit such as NONE, BYTES, etc.
|
|
315
586
|
attr_reader :unit
|
|
316
587
|
# @return [Long] collection interval in seconds
|
|
317
588
|
attr_reader :collection_interval
|
|
318
589
|
|
|
319
590
|
def initialize(metric_hash)
|
|
320
|
-
|
|
321
|
-
@path = metric_hash['path']
|
|
322
|
-
@name = metric_hash['name'] || @id
|
|
323
|
-
@_hash = metric_hash.dup
|
|
324
|
-
|
|
325
|
-
tmp = path.split('/')
|
|
326
|
-
tmp.each do |pair|
|
|
327
|
-
(key, val) = pair.split(';')
|
|
328
|
-
case key
|
|
329
|
-
when 'f'
|
|
330
|
-
@feed = val
|
|
331
|
-
when 'e'
|
|
332
|
-
@env = val
|
|
333
|
-
when 'n'
|
|
334
|
-
@name = val.nil? ? id : val
|
|
335
|
-
end
|
|
336
|
-
end
|
|
591
|
+
super(metric_hash)
|
|
337
592
|
@type = metric_hash['type']['type']
|
|
593
|
+
@type_path = metric_hash['type']['path']
|
|
338
594
|
@unit = metric_hash['type']['unit']
|
|
339
|
-
@collection_interval = metric_hash['collectionInterval']
|
|
340
|
-
end
|
|
341
|
-
|
|
342
|
-
def to_h
|
|
343
|
-
@_hash.dup
|
|
595
|
+
@collection_interval = metric_hash['type']['collectionInterval']
|
|
344
596
|
end
|
|
345
597
|
end
|
|
346
598
|
|
|
@@ -375,4 +627,81 @@ module Hawkular::Inventory
|
|
|
375
627
|
hash
|
|
376
628
|
end
|
|
377
629
|
end
|
|
630
|
+
|
|
631
|
+
class CanonicalPath
|
|
632
|
+
attr_reader :tenant_id
|
|
633
|
+
attr_reader :feed_id
|
|
634
|
+
attr_reader :environment_id
|
|
635
|
+
attr_reader :resource_ids
|
|
636
|
+
attr_reader :metric_id
|
|
637
|
+
attr_reader :resource_type_id
|
|
638
|
+
attr_reader :metric_type_id
|
|
639
|
+
|
|
640
|
+
def initialize(hash)
|
|
641
|
+
fail 'At least tenant_id must be specified' if hash[:tenant_id].to_s.strip.length == 0
|
|
642
|
+
@tenant_id = hash[:tenant_id]
|
|
643
|
+
@feed_id = hash[:feed_id]
|
|
644
|
+
@environment_id = hash[:environment_id]
|
|
645
|
+
@resource_type_id = hash[:resource_type_id]
|
|
646
|
+
@metric_type_id = hash[:metric_type_id]
|
|
647
|
+
@resource_ids = hash[:resource_ids]
|
|
648
|
+
@metric_id = hash[:metric_id]
|
|
649
|
+
end
|
|
650
|
+
|
|
651
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
|
652
|
+
def self.parse(path)
|
|
653
|
+
fail 'CanonicalPath must not be nil or emtpy' if path.to_s.strip.length == 0
|
|
654
|
+
tmp = path.split('/')
|
|
655
|
+
hash = {}
|
|
656
|
+
tmp.each do |pair|
|
|
657
|
+
(key, val) = pair.split(';')
|
|
658
|
+
case key
|
|
659
|
+
when 't'
|
|
660
|
+
hash[:tenant_id] = val
|
|
661
|
+
when 'f'
|
|
662
|
+
hash[:feed_id] = val
|
|
663
|
+
when 'e'
|
|
664
|
+
hash[:environment_id] = val
|
|
665
|
+
when 'm'
|
|
666
|
+
hash[:metric_id] = val
|
|
667
|
+
when 'r'
|
|
668
|
+
hash[:resource_ids] = [] if hash[:resource_ids].nil?
|
|
669
|
+
hash[:resource_ids].push(val)
|
|
670
|
+
when 'mt'
|
|
671
|
+
hash[:metric_type_id] = val
|
|
672
|
+
when 'rt'
|
|
673
|
+
hash[:resource_type_id] = val
|
|
674
|
+
end
|
|
675
|
+
end
|
|
676
|
+
CanonicalPath.new(hash)
|
|
677
|
+
end
|
|
678
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
|
679
|
+
|
|
680
|
+
def ==(other)
|
|
681
|
+
self.eql?(other) || other.class == self.class && other.state == state
|
|
682
|
+
end
|
|
683
|
+
|
|
684
|
+
def to_s
|
|
685
|
+
ret = "/t;#{@tenant_id}"
|
|
686
|
+
ret += "/f;#{@feed_id}" unless @feed_id.nil?
|
|
687
|
+
ret += "/e;#{@environment_id}" unless @environment_id.nil?
|
|
688
|
+
ret += "/rt;#{@resource_type_id}" unless @resource_type_id.nil?
|
|
689
|
+
ret += "/mt;#{@metric_type_id}" unless @metric_type_id.nil?
|
|
690
|
+
ret += "/m;#{@metric_id}" unless @metric_id.nil?
|
|
691
|
+
ret += resources_chunk.to_s
|
|
692
|
+
ret
|
|
693
|
+
end
|
|
694
|
+
|
|
695
|
+
protected
|
|
696
|
+
|
|
697
|
+
def state
|
|
698
|
+
[@tenant_id, @feed_id, @environment_id, @resource_ids, @metric_id, @metric_type_id, @resource_type_id]
|
|
699
|
+
end
|
|
700
|
+
|
|
701
|
+
private
|
|
702
|
+
|
|
703
|
+
def resources_chunk
|
|
704
|
+
@resource_ids.map { |r| "/r;#{r}" }.join unless @resource_ids.nil?
|
|
705
|
+
end
|
|
706
|
+
end
|
|
378
707
|
end
|