hawkular-client 0.2.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/.yardopts +1 -0
  4. data/CHANGES.rdoc +17 -4
  5. data/README.rdoc +15 -6
  6. data/api_breaking_changes.rdoc +79 -0
  7. data/hawkularclient.gemspec +6 -5
  8. data/lib/{alerts → hawkular/alerts}/alerts_api.rb +168 -7
  9. data/lib/{hawkular.rb → hawkular/base_client.rb} +7 -44
  10. data/lib/hawkular/hawkular_client.rb +60 -0
  11. data/lib/hawkular/hawkular_client_utils.rb +40 -0
  12. data/lib/{inventory → hawkular/inventory}/inventory_api.rb +167 -142
  13. data/lib/{metrics → hawkular/metrics}/metric_api.rb +1 -0
  14. data/lib/{metrics → hawkular/metrics}/metrics_client.rb +4 -4
  15. data/lib/{metrics → hawkular/metrics}/tenant_api.rb +0 -0
  16. data/lib/{metrics → hawkular/metrics}/types.rb +0 -0
  17. data/lib/{operations → hawkular/operations}/operations_api.rb +11 -8
  18. data/lib/{tokens → hawkular/tokens}/tokens_api.rb +1 -1
  19. data/lib/{version.rb → hawkular/version.rb} +1 -1
  20. data/spec/integration/alerts_spec.rb +200 -0
  21. data/spec/integration/hawkular_client_spec.rb +228 -0
  22. data/spec/integration/inventory_spec.rb +246 -160
  23. data/spec/integration/metric_spec.rb +52 -59
  24. data/spec/integration/operations_spec.rb +53 -29
  25. data/spec/spec_helper.rb +109 -8
  26. data/spec/unit/base_spec.rb +9 -0
  27. data/spec/unit/canonical_path_spec.rb +2 -2
  28. data/spec/vcr/vcr_setup.rb +6 -0
  29. data/spec/vcr_cassettes/Alert/Events/Should_create_an_event.yml +50 -0
  30. data/spec/vcr_cassettes/Alert/Groups/Should_operate_a_complex_group_trigger.yml +1726 -0
  31. data/spec/vcr_cassettes/Counter_metrics/Should_get_metrics_as_bucketed_results.yml +190 -0
  32. data/spec/vcr_cassettes/Counter_metrics/Should_get_metrics_with_limit_and_order.yml +30 -42
  33. data/spec/vcr_cassettes/HawkularClient/and_Inventory_client/Should_both_create_and_delete_feed.yml +287 -0
  34. data/spec/vcr_cassettes/{Inventory/Should_list_URLs.yml → HawkularClient/and_Inventory_client/Should_both_list_WildFlys.yml} +35 -33
  35. data/spec/vcr_cassettes/{Inventory/Should_list_types_with_bad_feed.yml → HawkularClient/and_Inventory_client/Should_both_list_types_with_bad_feed.yml} +16 -19
  36. data/spec/vcr_cassettes/HawkularClient/and_Inventory_client/Should_list_same_types_when_param_is_given.yml +245 -0
  37. data/spec/vcr_cassettes/{Inventory/Should_list_feeds.yml → HawkularClient/and_Inventory_client/Should_list_the_same_feeds.yml} +20 -20
  38. data/spec/vcr_cassettes/HawkularClient/and_Inventory_client/Should_list_the_same_resource_types.yml +249 -0
  39. data/spec/vcr_cassettes/HawkularClient/and_Metrics_client/Should_both_create_and_retrieve_tags_for_Availability.yml +155 -0
  40. data/spec/vcr_cassettes/HawkularClient/and_Metrics_client/Should_both_create_and_return_Availability_using_Hash_parameter.yml +155 -0
  41. data/spec/vcr_cassettes/HawkularClient/and_Metrics_client/Should_both_return_the_version.yml +89 -0
  42. data/spec/vcr_cassettes/HawkularClient/and_Metrics_client/Should_both_work_the_same_way_when_pushing_metric_data_to_non-existing_counter.yml +114 -0
  43. data/spec/vcr_cassettes/{Inventory/Should_list_WildFlys_with_props.yml → HawkularClient/and_Operations_client/Should_both_work_the_same_way.yml} +28 -50
  44. data/spec/vcr_cassettes/HawkularClient/and_Operations_client_Should_both_work_the_same_way.json +44 -0
  45. data/spec/vcr_cassettes/Inventory/Helpers/create_url.yml +48 -0
  46. data/spec/vcr_cassettes/Inventory/Helpers/generate_some_events_for_websocket.yml +4446 -0
  47. data/spec/vcr_cassettes/Inventory/Helpers/get_feeds.yml +54 -0
  48. data/spec/vcr_cassettes/Inventory/Templates/Client_should_listen_on_various_inventory_events.json +47 -0
  49. data/spec/vcr_cassettes/Inventory/{Should_create_a_resourcetype.yml → Templates/Client_should_listen_on_various_inventory_events.yml} +47 -61
  50. data/spec/vcr_cassettes/Inventory/Templates/Helpers/generate_some_events_for_websocket.yml +542 -0
  51. data/spec/vcr_cassettes/Inventory/{Should_List_datasources_with_no_props.yml → Templates/Should_List_datasources_with_no_props.yml} +26 -85
  52. data/spec/vcr_cassettes/Inventory/Templates/Should_create_a_feed.yml +54 -0
  53. data/spec/vcr_cassettes/Inventory/Templates/Should_create_a_feed_again.yml +164 -0
  54. data/spec/vcr_cassettes/Inventory/{Should_create_a_nested_resource_and_metric_on_it.yml → Templates/Should_create_a_nested_resource_and_metric_on_it.yml} +93 -74
  55. data/spec/vcr_cassettes/Inventory/{Should_create_a_resource_.yml → Templates/Should_create_a_resource.yml} +103 -76
  56. data/spec/vcr_cassettes/Inventory/{Should_create_a_resource_with_metric.yml → Templates/Should_create_a_resource_with_metric.yml} +91 -197
  57. data/spec/vcr_cassettes/Inventory/Templates/Should_create_a_resourcetype.yml +154 -0
  58. data/spec/vcr_cassettes/Inventory/Templates/Should_create_and_delete_feed.yml +145 -0
  59. data/spec/vcr_cassettes/Inventory/{Should_create_and_get_a_resource.yml → Templates/Should_create_and_get_a_resource.yml} +35 -20
  60. data/spec/vcr_cassettes/Inventory/Templates/Should_list_URLs.yml +65 -0
  61. data/spec/vcr_cassettes/Inventory/Templates/Should_list_WildFlys.yml +61 -0
  62. data/spec/vcr_cassettes/Inventory/{Should_list_WildFlys.yml → Templates/Should_list_WildFlys_with_props.yml} +36 -33
  63. data/spec/vcr_cassettes/Inventory/Templates/Should_list_all_the_resource_types.yml +126 -0
  64. data/spec/vcr_cassettes/Inventory/{Should_list_children_of_WildFly.yml → Templates/Should_list_children_of_WildFly.yml} +66 -112
  65. data/spec/vcr_cassettes/Inventory/{Should_list_children_of_nested_resource.yml → Templates/Should_list_children_of_nested_resource.yml} +13 -13
  66. data/spec/vcr_cassettes/Inventory/Templates/Should_list_feeds.yml +54 -0
  67. data/spec/vcr_cassettes/Inventory/Templates/Should_list_heap_metrics_for_WildFlys.yml +712 -0
  68. data/spec/vcr_cassettes/Inventory/Templates/Should_list_metrics_for_WildFlys.yml +278 -0
  69. data/spec/vcr_cassettes/Inventory/Templates/Should_list_metrics_of_given_metric_type.yml +530 -0
  70. data/spec/vcr_cassettes/Inventory/Templates/Should_list_metrics_of_given_resource_type.yml +278 -0
  71. data/spec/vcr_cassettes/Inventory/Templates/Should_list_operation_definitions_of_given_resource.yml +185 -0
  72. data/spec/vcr_cassettes/Inventory/Templates/Should_list_operation_definitions_of_given_resource_type.yml +126 -0
  73. data/spec/vcr_cassettes/Inventory/Templates/Should_list_recursive_children_of_WildFly.yml +2369 -0
  74. data/spec/vcr_cassettes/Inventory/Templates/Should_list_relationships_of_WildFly.yml +415 -0
  75. data/spec/vcr_cassettes/Inventory/Templates/Should_list_types_with_bad_feed.yml +51 -0
  76. data/spec/vcr_cassettes/Inventory/Templates/Should_list_types_with_feed.yml +124 -0
  77. data/spec/vcr_cassettes/Inventory/{Should_not_find_an_unknown_resource.yml → Templates/Should_not_find_an_unknown_resource.yml} +14 -13
  78. data/spec/vcr_cassettes/Inventory/{Should_return_config_data_of_given_nested_resource.yml → Templates/Should_return_config_data_of_given_nested_resource.yml} +4 -4
  79. data/spec/vcr_cassettes/Inventory/{Should_return_config_data_of_given_resource.yml → Templates/Should_return_config_data_of_given_resource.yml} +4 -4
  80. data/spec/vcr_cassettes/Inventory/Tenants/Should_Get_Tenant_For_Explicit_Credentials.yml +50 -0
  81. data/spec/vcr_cassettes/Inventory/Tenants/Should_Get_Tenant_For_Implicit_Credentials.yml +50 -0
  82. data/spec/vcr_cassettes/Operation/Helpers/get_feed.yml +54 -0
  83. data/spec/vcr_cassettes/Operation/Helpers/get_tenant.yml +50 -0
  84. data/spec/vcr_cassettes/Operation/Operation/Add_JDBC_driver_should_add_the_driver.json +26 -0
  85. data/spec/vcr_cassettes/Operation/Operation/Add_datasource_should_be_doable.json +26 -0
  86. data/spec/vcr_cassettes/Operation/Operation/Add_deployment_should_be_doable.json +26 -0
  87. data/spec/vcr_cassettes/Operation/Operation/Redeploy_can_be_run_multiple_times_in_parallel.json +40 -0
  88. data/spec/vcr_cassettes/Operation/Operation/Redeploy_should_be_performed_and_eventually_respond_with_success.json +26 -0
  89. data/spec/vcr_cassettes/Operation/Operation/Redeploy_should_not_be_performed_if_resource_path_is_wrong.json +26 -0
  90. data/spec/vcr_cassettes/Operation/Operation/Remove_JDBC_driver_should_be_performed_and_eventually_respond_with_success.json +26 -0
  91. data/spec/vcr_cassettes/Operation/Operation/Remove_datasource_should_be_performed_and_eventually_respond_with_success.json +26 -0
  92. data/spec/vcr_cassettes/Operation/Operation/Remove_deployment_should_be_performed_and_eventually_respond_with_success.json +26 -0
  93. data/spec/vcr_cassettes/Operation/Operation/Undeploy_should_be_performed_and_eventually_respond_with_success.json +26 -0
  94. data/spec/vcr_cassettes/Operation/Operation/should_not_be_possible_to_perform_on_closed_client.json +12 -0
  95. data/spec/vcr_cassettes/Operation/Websocket_connection/should_be_established.json +9 -0
  96. metadata +171 -72
  97. data/lib/hawkular_all.rb +0 -9
  98. data/spec/vcr_cassettes/Inventory/Should_create_a_feed.yml +0 -107
  99. data/spec/vcr_cassettes/Inventory/Should_create_a_feed_again.yml +0 -211
  100. data/spec/vcr_cassettes/Inventory/Should_create_and_delete_feed.yml +0 -201
  101. data/spec/vcr_cassettes/Inventory/Should_list_all_the_resource_types.yml +0 -177
  102. data/spec/vcr_cassettes/Inventory/Should_list_heap_metrics_for_WildFlys.yml +0 -775
  103. data/spec/vcr_cassettes/Inventory/Should_list_metrics_for_WildFlys.yml +0 -333
  104. data/spec/vcr_cassettes/Inventory/Should_list_metrics_of_given_metric_type.yml +0 -613
  105. data/spec/vcr_cassettes/Inventory/Should_list_metrics_of_given_resource_type.yml +0 -333
  106. data/spec/vcr_cassettes/Inventory/Should_list_recursive_children_of_WildFly.yml +0 -2064
  107. data/spec/vcr_cassettes/Inventory/Should_list_relationships_of_WildFly.yml +0 -460
  108. data/spec/vcr_cassettes/Inventory/Should_list_types_with_feed.yml +0 -175
@@ -1,14 +1,14 @@
1
1
  require 'base64'
2
2
  require 'addressable/uri'
3
+ require 'hawkular/hawkular_client_utils'
3
4
 
4
5
  module Hawkular
5
- module Metrics
6
- end
7
-
8
6
  # This is the base functionality for all the clients,
9
7
  # that inherit from it. You should not directly use it,
10
8
  # but through the more specialized clients.
11
9
  class BaseClient
10
+ include HawkularUtilsMixin
11
+
12
12
  # @!visibility private
13
13
  attr_reader :credentials, :entrypoint, :options
14
14
  # @return [Tenants] access tenants API
@@ -29,6 +29,7 @@ module Hawkular
29
29
  verify_ssl: OpenSSL::SSL::VERIFY_PEER,
30
30
  ssl_client_cert: nil,
31
31
  ssl_client_key: nil,
32
+ http_proxy_uri: nil,
32
33
  headers: {}
33
34
  }.merge(options)
34
35
 
@@ -43,45 +44,6 @@ module Hawkular
43
44
  handle_fault $ERROR_INFO
44
45
  end
45
46
 
46
- # Escapes the passed url part. This is necessary,
47
- # as many ids inside Hawkular can contain characters
48
- # that are invalid for an url/uri.
49
- # The passed value is duplicated
50
- # Does not escape the = character
51
- # @param [String] url_part Part of an url to be escaped
52
- # @return [String] escaped url_part as new string
53
- def hawk_escape(url_part)
54
- return url_part.to_s if url_part.is_a?(Numeric)
55
-
56
- if url_part.is_a? Symbol
57
- sub_url = url_part.to_s
58
- else
59
- sub_url = url_part.dup
60
- end
61
- sub_url.gsub!('%', '%25')
62
- sub_url.gsub!(' ', '%20')
63
- sub_url.gsub!('[', '%5b')
64
- sub_url.gsub!(']', '%5d')
65
- sub_url.gsub!('|', '%7c')
66
- sub_url.gsub!('(', '%28')
67
- sub_url.gsub!(')', '%29')
68
- sub_url.gsub!('/', '%2f')
69
- sub_url
70
- end
71
-
72
- # Escapes the passed url part. This is necessary,
73
- # as many ids inside Hawkular can contain characters
74
- # that are invalid for an url/uri.
75
- # The passed value is duplicated
76
- # Does escape the = character
77
- # @param [String] url_part Part of an url to be escaped
78
- # @return [String] escaped url_part as new string
79
- def hawk_escape_id(url_part)
80
- sub_url = hawk_escape url_part
81
- sub_url.gsub!('=', '%3d')
82
- sub_url
83
- end
84
-
85
47
  def http_post(suburl, hash, headers = {})
86
48
  body = JSON.generate(hash)
87
49
  res = rest_client(suburl).post(body, http_headers(headers))
@@ -115,6 +77,7 @@ module Hawkular
115
77
  options[:verify_ssl] = @options[:verify_ssl]
116
78
  options[:ssl_client_cert] = @options[:ssl_client_cert]
117
79
  options[:ssl_client_key] = @options[:ssl_client_key]
80
+ options[:proxy] = @options[:http_proxy_uri]
118
81
  options[:user] = @credentials[:username]
119
82
  options[:password] = @credentials[:password]
120
83
  # strip @endpoint in case suburl is absolute
@@ -183,8 +146,8 @@ module Hawkular
183
146
  end
184
147
 
185
148
  def tenant_header
186
- @options[:tenant].nil? ? {} : { :'Hawkular-Tenant' => @options[:tenant],
187
- 'tenantId' => @options[:tenant] }
149
+ @options[:tenant].nil? ? { 'Hawkular-Tenant' => 'hawkular' } : { :'Hawkular-Tenant' => @options[:tenant],
150
+ 'tenantId' => @options[:tenant] }
188
151
  end
189
152
 
190
153
  def handle_fault(f)
@@ -0,0 +1,60 @@
1
+ require 'hawkular/inventory/inventory_api'
2
+ require 'hawkular/metrics/metrics_client.rb'
3
+ require 'hawkular/alerts/alerts_api'
4
+ require 'hawkular/tokens/tokens_api'
5
+ require 'hawkular/operations/operations_api'
6
+ require 'hawkular/base_client'
7
+
8
+ module Hawkular
9
+ class Client
10
+ attr_reader :inventory, :metrics, :alerts, :operations, :tokens, :state
11
+
12
+ def initialize(hash)
13
+ hash[:entrypoint] ||= 'http://localhost:8080'
14
+ hash[:credentials] ||= {}
15
+ hash[:options] ||= {}
16
+ @state = hash
17
+
18
+ @inventory = Inventory::InventoryClient.create(entrypoint: "#{hash[:entrypoint]}/hawkular/inventory",
19
+ credentials: hash[:credentials])
20
+
21
+ @metrics = Metrics::Client.new("#{hash[:entrypoint]}/hawkular/metrics",
22
+ hash[:credentials],
23
+ hash[:options])
24
+
25
+ @alerts = Alerts::AlertsClient.new("#{hash[:entrypoint]}/hawkular/alerts", hash[:credentials])
26
+
27
+ @tokens = Token::TokenClient.new(hash[:entrypoint], hash[:credentials])
28
+ end
29
+
30
+ def method_missing(name, *args, &block)
31
+ delegate_client = case name
32
+ when /^inventory_/ then @inventory
33
+ when /^metrics_/ then @metrics
34
+ when /^alerts_/ then @alerts
35
+ when /^operations_/ then @operations ||= init_operations_client
36
+ when /^tokens_/ then @tokens
37
+ else
38
+ fail "unknown method prefix `#{name}`, allowed prefixes:"\
39
+ '`inventory_`, `metrics_`,`alerts_`,`operations_`, `tokens_`'
40
+ end
41
+ method = name.to_s.sub(/^[^_]+_/, '')
42
+ delegate_client.__send__(method, *args, &block)
43
+ end
44
+
45
+ # adds a way to explicitly open the new web socket connection (the default is to recycle it)
46
+ # @param open_new [Boolean] if true, opens the new websocket connection
47
+ def operations(open_new = false)
48
+ @operations = init_operations_client if open_new
49
+ @operations ||= init_operations_client
50
+ end
51
+
52
+ private
53
+
54
+ # this is in a dedicated method, because constructor opens the websocket connection to make the handshake
55
+ def init_operations_client
56
+ Operations::OperationsClient.new(entrypoint: @state[:entrypoint].gsub(/^https?/, 'ws'),
57
+ credentials: @state[:credentials])
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,40 @@
1
+ module HawkularUtilsMixin
2
+ # Escapes the passed url part. This is necessary,
3
+ # as many ids inside Hawkular can contain characters
4
+ # that are invalid for an url/uri.
5
+ # The passed value is duplicated
6
+ # Does not escape the = character
7
+ # @param [String] url_part Part of an url to be escaped
8
+ # @return [String] escaped url_part as new string
9
+ def hawk_escape(url_part)
10
+ return url_part.to_s if url_part.is_a?(Numeric)
11
+
12
+ if url_part.is_a? Symbol
13
+ sub_url = url_part.to_s
14
+ else
15
+ sub_url = url_part.dup
16
+ end
17
+ sub_url.gsub!('%', '%25')
18
+ sub_url.gsub!(' ', '%20')
19
+ sub_url.gsub!('[', '%5b')
20
+ sub_url.gsub!(']', '%5d')
21
+ sub_url.gsub!('|', '%7c')
22
+ sub_url.gsub!('(', '%28')
23
+ sub_url.gsub!(')', '%29')
24
+ sub_url.gsub!('/', '%2f')
25
+ sub_url
26
+ end
27
+
28
+ # Escapes the passed url part. This is necessary,
29
+ # as many ids inside Hawkular can contain characters
30
+ # that are invalid for an url/uri.
31
+ # The passed value is duplicated
32
+ # Does escape the = character
33
+ # @param [String] url_part Part of an url to be escaped
34
+ # @return [String] escaped url_part as new string
35
+ def hawk_escape_id(url_part)
36
+ sub_url = hawk_escape url_part
37
+ sub_url.gsub!('=', '%3d')
38
+ sub_url
39
+ end
40
+ end
@@ -1,4 +1,4 @@
1
- require 'hawkular'
1
+ require 'hawkular/base_client'
2
2
  require 'websocket-client-simple'
3
3
  require 'json'
4
4
 
@@ -55,57 +55,57 @@ module Hawkular::Inventory
55
55
  ret.map { |f| f['id'] }
56
56
  end
57
57
 
58
- # List resource types. If no need is given all types are listed
59
- # @param [String] feed The id of the feed the type lives under. Can be nil for feedless types
58
+ # List resource types. If no feed_id is given all types are listed
59
+ # @param [String] feed_id The id of the feed the type lives under. Can be nil for feedless types
60
60
  # @return [Array<ResourceType>] List of types, that can be empty
61
- def list_resource_types(feed = nil)
62
- if feed.nil?
61
+ def list_resource_types(feed_id = nil)
62
+ if feed_id.nil?
63
63
  ret = http_get('/resourceTypes')
64
64
  else
65
- the_feed = hawk_escape_id feed
65
+ the_feed = hawk_escape_id feed_id
66
66
  ret = http_get("/feeds/#{the_feed}/resourceTypes")
67
67
  end
68
68
  ret.map { |rt| ResourceType.new(rt) }
69
69
  end
70
70
 
71
71
  # Return all resources for a feed
72
- # @param [String] feed Id of the feed that hosts the resources
72
+ # @param [String] feed_id Id of the feed that hosts the resources
73
73
  # @param [Boolean] fetch_properties Should the config data be fetched too
74
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
75
+ def list_resources_for_feed(feed_id, fetch_properties = false, filter = {})
76
+ fail 'Feed id must be given' unless feed_id
77
77
  the_feed = hawk_escape_id feed
78
78
  ret = http_get("/feeds/#{the_feed}/resources")
79
- ret.map do |r|
79
+ to_filter = ret.map do |r|
80
80
  if fetch_properties
81
- p = get_config_data_for_resource(r['id'], feed)
81
+ p = get_config_data_for_resource(r['path'])
82
82
  r['properties'] = p['value']
83
83
  end
84
84
  Resource.new(r)
85
85
  end
86
+ filter_entities(to_filter, filter)
86
87
  end
87
88
 
88
- # List the resources for the passed feed and resource type. The representation for
89
- # resources under a feed are sparse and additional data must be retrived separately.
89
+ # List the resources for the passed resource type. The representation for
90
+ # resources under a feed are sparse and additional data must be retrieved separately.
90
91
  # It is possible though to also obtain runtime properties by setting #fetch_properties to true.
91
- # @param [String] feed The id of the feed the type lives under. Can be nil for all feeds
92
- # @param [String] type Name of the type to look for. Can be obtained from {ResourceType}.id.
93
- # Must not be nil
92
+ # @param [String] resource_type_path Canonical path of the resource type. Can be obtained from {ResourceType}.path.
93
+ # Must not be nil. The tenant_id in the canonical path doesn't have to be there.
94
94
  # @param [Boolean] fetch_properties Shall additional runtime properties be fetched?
95
95
  # @return [Array<Resource>] List of resources. Can be empty
96
- def list_resources_for_type(feed, type, fetch_properties = false)
97
- fail 'Type must not be nil' unless type
98
- the_type = hawk_escape_id type
99
- if feed.nil?
100
- ret = http_get("resourceTypes/#{the_type}/resources")
96
+ def list_resources_for_type(resource_type_path, fetch_properties = false)
97
+ path = resource_type_path.is_a?(CanonicalPath) ? resource_type_path : CanonicalPath.parse(resource_type_path)
98
+ resource_type_id = path.resource_type_id
99
+ feed_id = path.feed_id
100
+ if feed_id.nil?
101
+ ret = http_get("resourceTypes/#{resource_type_id}/resources")
101
102
  else
102
103
 
103
- the_feed = hawk_escape_id feed
104
- ret = http_get("/feeds/#{the_feed}/resourceTypes/#{the_type}/resources")
104
+ ret = http_get("/feeds/#{feed_id}/resourceTypes/#{resource_type_id}/resources")
105
105
  end
106
106
  ret.map do |r|
107
- if fetch_properties && !feed.nil?
108
- p = get_config_data_for_resource(r['id'], feed)
107
+ if fetch_properties && !feed_id.nil?
108
+ p = get_config_data_for_resource(r['path'])
109
109
  r['properties'] = p['value']
110
110
  end
111
111
  Resource.new(r)
@@ -113,44 +113,45 @@ module Hawkular::Inventory
113
113
  end
114
114
 
115
115
  # Retrieve runtime properties for the passed resource
116
- # @param [String] feed_id Feed of the resource
117
- # @param [Array<String>] res_ids Ids of the resource to read properties from (parent to child order)
116
+ # @param [String] resource_path Canonical path of the resource to read properties from.
118
117
  # @return [Hash<String,Object] Hash with additional data
119
- def get_config_data_for_resource(res_ids, feed_id)
120
- resource_path = if res_ids.is_a?(Array)
121
- res_ids.map { |id| hawk_escape_id id }.join('/')
122
- else
123
- hawk_escape_id res_ids
124
- end
125
- the_feed = hawk_escape_id feed_id
118
+ def get_config_data_for_resource(resource_path)
119
+ path = resource_path.is_a?(CanonicalPath) ? resource_path : CanonicalPath.parse(resource_path)
120
+ resource_path = path.resource_ids.join('/')
121
+ feed_id = path.feed_id
126
122
  query = generate_query_params dataType: 'configuration'
127
- http_get("feeds/#{the_feed}/resources/#{resource_path}/data#{query}")
123
+ http_get("feeds/#{feed_id}/resources/#{resource_path}/data#{query}")
128
124
  rescue
129
125
  {}
130
126
  end
131
127
 
132
128
  # Obtain the child resources of the passed resource. In case of a WildFly server,
133
129
  # those would be Datasources, Deployments and so on.
134
- # @param [Resource] parent_resource Resource to obtain children from
130
+ # @param [String] parent_res_path Canonical path of the resource to obtain children from.
135
131
  # @param [Boolean] recursive Whether to fetch also all the children of children of ...
136
132
  # @return [Array<Resource>] List of resources that are children of the given parent resource.
137
133
  # Can be empty
138
- def list_child_resources(parent_resource, recursive = false)
139
- the_feed = hawk_escape_id parent_resource.feed
140
- resource_path_escaped = CanonicalPath.parse(parent_resource.path).resource_ids.join('/')
141
-
134
+ def list_child_resources(parent_res_path, recursive = false)
135
+ path = parent_res_path.is_a?(CanonicalPath) ? parent_res_path : CanonicalPath.parse(parent_res_path)
136
+ parent_resource_path = path.resource_ids.join('/')
137
+ feed_id = path.feed_id
142
138
  which_children = (recursive ? '/recursiveChildren' : '/children')
143
- ret = http_get("/feeds/#{the_feed}/resources/#{resource_path_escaped}#{which_children}")
139
+ ret = http_get("/feeds/#{feed_id}/resources/#{parent_resource_path}#{which_children}")
144
140
  ret.map { |r| Resource.new(r) }
145
141
  end
146
142
 
147
143
  # Obtain a list of relationships starting at the passed resource
148
- # @param [Resource] resource One end of the relationship
144
+ # @param [String] entity_path Canonical path of the entity that forms the one end of the relationship
149
145
  # @param [String] named Name of the relationship
150
146
  # @return [Array<Relationship>] List of relationships
151
- def list_relationships(resource, named = nil)
152
- query = named.nil? ? '' : (generate_query_params named: named)
153
- ret = http_get("/path#{resource.path}/relationships#{query}")
147
+ def list_relationships(entity_path, named = nil)
148
+ path = entity_path.is_a?(CanonicalPath) ? entity_path : CanonicalPath.parse(entity_path)
149
+ query_params = {
150
+ sort: '__targetCp'
151
+ }
152
+ query_params[:named] = named unless named.nil?
153
+ query = generate_query_params query_params
154
+ ret = http_get("/path#{path}/relationships#{query}")
154
155
  ret.map { |r| Relationship.new(r) }
155
156
  end
156
157
 
@@ -160,7 +161,11 @@ module Hawkular::Inventory
160
161
  # @return [Array<Relationship>] List of relationships
161
162
  def list_relationships_for_feed(feed_id, named = nil)
162
163
  the_feed = hawk_escape_id feed_id
163
- query = named.nil? ? '' : (generate_query_params named: named)
164
+ query_params = {
165
+ sort: '__targetCp'
166
+ }
167
+ query_params[:named] = named unless named.nil?
168
+ query = generate_query_params query_params
164
169
  ret = http_get("/feeds/#{the_feed}/relationships#{query}")
165
170
  ret.map { |r| Relationship.new(r) }
166
171
  rescue
@@ -168,10 +173,11 @@ module Hawkular::Inventory
168
173
  end
169
174
 
170
175
  # Retrieve a single entity from inventory by its canonical path
171
- # @param [CanonicalPath] path canonical path of the entity
176
+ # @param [String] path canonical path of the entity
172
177
  # @return inventory entity
173
178
  def get_entity(path)
174
- http_get("path#{path}")
179
+ c_path = path.is_a?(CanonicalPath) ? path : CanonicalPath.parse(path)
180
+ http_get("path#{c_path}")
175
181
  end
176
182
 
177
183
  # [15:01:51] <jkremser> pilhuhn, this works for me curl -XPOST
@@ -194,55 +200,54 @@ module Hawkular::Inventory
194
200
  # rel.to_h)
195
201
  # end
196
202
 
197
- # List the metrics for the passed feed and metric type. If feed is not passed,
203
+ # List the metrics for the passed metric type. If feed is not passed in the path,
198
204
  # all the metrics across all the feeds of a given type will be retrieved
199
205
  # This method may perform multiple REST calls.
200
- # @param [String] feed The id of the feed the type lives under. Can be nil for all feeds
201
- # @param [String] type Name of the metric type to look for. Can be obtained from {MetricType}.id.
202
- # Must not be nil
206
+ # @param [String] metric_type_path Canonical path of the resource type to look for. Can be obtained from
207
+ # {MetricType}.path. Must not be nil. The tenant_id in the canonical path doesn't have to be there.
203
208
  # @return [Array<Metric>] List of metrics. Can be empty
204
- def list_metrics_for_metric_type(feed, type)
205
- fail 'Type must not be nil' unless type
206
- the_type = hawk_escape_id type
207
- if feed.nil?
208
- type_hash = http_get("metricTypes/#{the_type}")
209
+ def list_metrics_for_metric_type(metric_type_path)
210
+ path = metric_type_path.is_a?(CanonicalPath) ? metric_type_path : CanonicalPath.parse(metric_type_path)
211
+ metric_type_id = path.metric_type_id
212
+ feed_id = path.feed_id
213
+ if feed_id.nil?
214
+ type_hash = http_get("metricTypes/#{metric_type_id}")
209
215
  else
210
- the_feed = hawk_escape_id feed
211
- type_hash = http_get("/feeds/#{the_feed}/metricTypes/#{the_type}")
216
+ type_hash = http_get("/feeds/#{feed_id}/metricTypes/#{metric_type_id}")
212
217
  end
213
218
 
214
- rels = list_relationships(ResourceType.new(type_hash), 'defines')
215
- rels.map do |rel|
216
- path = CanonicalPath.parse(rel.target_id.to_s)
217
- metric_hash = get_entity path
219
+ relations = list_relationships(type_hash['path'], 'defines')
220
+ relations.map do |rel|
221
+ metric_hash = get_entity rel.target_id.to_s
218
222
  Metric.new(metric_hash)
219
223
  end
220
224
  rescue
221
225
  []
222
226
  end
223
227
 
224
- # List the metrics for the passed feed and all the resources of given resource type.
225
- # If feed is not passed, all the metrics across all the feeds of a resource type will be retrieved
226
- # This method may perform multiple REST calls.
227
- # @param [String] feed The id of the feed the type lives under. Can be nil for all feeds
228
- # @param [String] type Name of the resource type to look for. Can be obtained from {ResourceType}.id.
229
- # Must not be nil
228
+ # List the metrics for all the resources of a given resource type.
229
+ # If feed is not passed in the resource type canonical path, all the metrics across all the feeds of a resource
230
+ # type will be retrieved. This method may perform multiple REST calls.
231
+ # @param [String] resource_type_path Canonical path of the resource type to look for. Can be obtained from
232
+ # {ResourceType}.path. Must not be nil. The tenant_id in the canonical path doesn't have to be there.
230
233
  # @return [Array<Metric>] List of metrics. Can be empty
231
- def list_metrics_for_resource_type(feed, type)
232
- fail 'Type must not be nil' unless type
233
- the_type = hawk_escape_id type
234
- if feed.nil?
235
- ret = http_get("resourceTypes/#{the_type}/resources")
234
+ def list_metrics_for_resource_type(resource_type_path)
235
+ path = resource_type_path.is_a?(CanonicalPath) ? resource_type_path : CanonicalPath.parse(resource_type_path)
236
+ resource_type_id = path.resource_type_id
237
+ feed_id = path.feed_id
238
+
239
+ if feed_id.nil?
240
+ ret = http_get("resourceTypes/#{resource_type_id}/resources")
236
241
  else
237
- the_feed = hawk_escape_id feed
238
- ret = http_get("feeds/#{the_feed}/resourceTypes/#{the_type}/resources")
242
+ ret = http_get("feeds/#{feed_id}/resourceTypes/#{resource_type_id}/resources")
239
243
  end
240
244
  ret.flat_map do |r|
241
245
  path = CanonicalPath.parse(r['path'])
246
+ query = generate_query_params sort: 'id'
242
247
  if !path.feed_id.nil?
243
- nested_ret = http_get("feeds/#{path.feed_id}/resources/#{path.resource_ids.join('/')}/metrics")
248
+ nested_ret = http_get("feeds/#{path.feed_id}/resources/#{path.resource_ids.join('/')}/metrics#{query}")
244
249
  else
245
- nested_ret = http_get("#{path.environment_id}/resources/#{path.resource_ids.join('/')}/metrics")
250
+ nested_ret = http_get("#{path.environment_id}/resources/#{path.resource_ids.join('/')}/metrics#{query}")
246
251
  end
247
252
  nested_ret.map { |m| Metric.new(m) }
248
253
  end
@@ -250,7 +255,7 @@ module Hawkular::Inventory
250
255
 
251
256
  # List metric (definitions) for the passed resource. It is possible to filter down the
252
257
  # result by a filter to only return a subset. The
253
- # @param [Resource] resource
258
+ # @param [String] resource_path Canonical path of the resource.
254
259
  # @param [Hash{Symbol=>String}] filter for 'type' and 'match'
255
260
  # Metric type can be one of 'GAUGE', 'COUNTER', 'AVAILABILITY'. If a key is missing
256
261
  # it will not be used for filtering
@@ -262,17 +267,15 @@ module Hawkular::Inventory
262
267
  # client.list_metrics_for_resource(wild_fly, type: 'COUNTER')
263
268
  # # Don't filter, return all metric definitions
264
269
  # client.list_metrics_for_resource(wild_fly)
265
- def list_metrics_for_resource(resource, filter = {})
266
- the_feed = hawk_escape_id resource.feed
267
- resource_path_escaped = CanonicalPath.parse(resource.path).resource_ids.join('/')
268
-
269
- ret = http_get("/feeds/#{the_feed}/resources/#{resource_path_escaped}/metrics")
270
- with_nils = ret.map do |m|
271
- metric_new = Metric.new(m)
272
- found = should_include?(metric_new, filter)
273
- metric_new if found
274
- end
275
- with_nils.compact
270
+ def list_metrics_for_resource(resource_path, filter = {})
271
+ path = resource_path.is_a?(CanonicalPath) ? resource_path : CanonicalPath.parse(resource_path)
272
+ feed_id = path.feed_id
273
+ resource_path_escaped = path.resource_ids.join('/')
274
+
275
+ query = generate_query_params sort: 'id'
276
+ ret = http_get("/feeds/#{feed_id}/resources/#{resource_path_escaped}/metrics#{query}")
277
+ to_filter = ret.map { |m| Metric.new(m) }
278
+ filter_entities(to_filter, filter)
276
279
  end
277
280
 
278
281
  # Create a new feed
@@ -298,9 +301,9 @@ module Hawkular::Inventory
298
301
  end
299
302
 
300
303
  # Delete the feed with the passed feed id.
301
- # @param feed Id of the feed to be deleted.
302
- def delete_feed(feed)
303
- the_feed = hawk_escape_id feed
304
+ # @param feed_id Id of the feed to be deleted.
305
+ def delete_feed(feed_id)
306
+ the_feed = hawk_escape_id feed_id
304
307
  http_delete("/feeds/#{the_feed}")
305
308
  end
306
309
 
@@ -328,62 +331,61 @@ module Hawkular::Inventory
328
331
  ResourceType.new(res)
329
332
  end
330
333
 
331
- # Create a resource of a given type under a given feed. To retrieve that resource
334
+ # Create a resource of a given type. To retrieve that resource
332
335
  # you need to call {#get_resource}
333
- # @param [String] feed_id Id of the feed to add the resource to
334
- # @param [String] type_path Path of the resource type of this resource
335
- # @param [String] resource_id Id of the resource
336
- # @param [String] resource_name Name of the resource
336
+ # @param [String] resource_type_path Canonical path of the new resource's type.
337
+ # @param [String] resource_id Id of the new resource
338
+ # @param [String] resource_name Name of the new resource
337
339
  # @param [Hash<String,Object>] properties Additional properties. Those are not the config-properties
338
- def create_resource(feed_id, type_path, resource_id, resource_name = nil, properties = {})
339
- create_resource_under_resource(feed_id, type_path, [], resource_id, resource_name, properties)
340
+ def create_resource(resource_type_path, resource_id, resource_name = nil, properties = {})
341
+ create_resource_under_resource(resource_type_path, nil, resource_id, resource_name, properties)
340
342
  end
341
343
 
342
- # Create a resource of a given type under a given feed. To retrieve that resource
344
+ # Create a resource of a given type under a given resource. To retrieve that resource
343
345
  # you need to call {#get_resource}
344
- # @param [String] feed_id Id of the feed to add the resource to
345
- # @param [String] type_path Path of the resource type of this resource
346
- # @param [Array<String>] parent_resource_ids Ids of the resources under which we create this resource
347
- # (parent to child order)
346
+ # @param [String] res_type_path Canonical path of the new resource's type.
347
+ # @param [String] parent_res_path Canonical path of the resource under which we create this resource.
348
+ # If nil, the top-lvl resource will be created.
348
349
  # @param [String] resource_id Id of the resource
349
350
  # @param [String] resource_name Name of the resource
350
351
  # @param [Hash<String,Object>] properties Additional properties. Those are not the config-properties
351
- def create_resource_under_resource(feed_id, type_path, parent_resource_ids, resource_id, resource_name = nil,
352
+ def create_resource_under_resource(res_type_path, parent_res_path, resource_id, resource_name = nil,
352
353
  properties = {})
353
- the_feed = hawk_escape_id feed_id
354
+ type_path = res_type_path.is_a?(CanonicalPath) ? res_type_path : CanonicalPath.parse(res_type_path)
355
+ feed_id = type_path.feed_id
354
356
 
355
357
  res = create_blueprint
356
358
  res[:properties] = properties
357
359
  res[:id] = resource_id
358
360
  res[:name] = resource_name
359
- res[:resourceTypePath] = type_path
361
+ res[:resourceTypePath] = type_path.to_s
360
362
 
361
363
  begin
362
- if parent_resource_ids.empty?
363
- http_post("/feeds/#{the_feed}/resources", res)
364
+ if parent_res_path.nil?
365
+ res = http_post("/feeds/#{feed_id}/resources", res)
364
366
  else
365
- parent_resource_path = parent_resource_ids.map { |id| hawk_escape_id id }.join('/')
366
- http_post("/feeds/#{the_feed}/resources/#{parent_resource_path}", res)
367
+ path = parent_res_path.is_a?(CanonicalPath) ? parent_res_path : CanonicalPath.parse(parent_res_path)
368
+ resource_path = path.resource_ids.join('/')
369
+ res = http_post("/feeds/#{feed_id}/resources/#{resource_path}", res)
367
370
  end
368
371
  rescue HawkularException => error
369
372
  # 409 We already exist -> that is ok
370
373
  raise unless error.status_code == 409
371
374
  end
372
-
373
- get_resource feed_id, parent_resource_ids << resource_id, false
375
+ Resource.new(res)
374
376
  end
375
377
 
376
- # Return the resource object for the passed id
377
- # @param [String] feed_id Id of the feed this resource belongs to
378
- # @param [Array<String>] res_ids Ids of the resource to fetch (parent to child order)
378
+ # Return the resource object for the passed path
379
+ # @param [String] resource_path Canonical path of the resource to fetch.
379
380
  # @param [Boolean] fetch_resource_config Should the resource config data be fetched?
380
- def get_resource(feed_id, res_ids, fetch_resource_config = true)
381
- the_feed = hawk_escape_id feed_id
382
- res_path = res_ids.is_a?(Array) ? (res_ids.map { |id| hawk_escape_id id }.join('/')) : hawk_escape_id(res_ids)
381
+ def get_resource(resource_path, fetch_resource_config = true)
382
+ path = resource_path.is_a?(CanonicalPath) ? resource_path : CanonicalPath.parse(resource_path)
383
+ feed_id = path.feed_id
384
+ res_path = path.resource_ids.join('/')
383
385
 
384
- res = http_get("/feeds/#{the_feed}/resources/#{res_path}")
386
+ res = http_get("/feeds/#{feed_id}/resources/#{res_path}")
385
387
  if fetch_resource_config
386
- p = get_config_data_for_resource(res_ids, feed_id)
388
+ p = get_config_data_for_resource(resource_path)
387
389
  res['properties'] ||= {}
388
390
  res['properties'].merge p['value'] unless p['value'].nil?
389
391
  end
@@ -417,42 +419,60 @@ module Hawkular::Inventory
417
419
  MetricType.new(new_mt)
418
420
  end
419
421
 
422
+ # List operation definitions (types) for a given resource type
423
+ # @param [String] resource_type_path canonical path of the resource type entity
424
+ # @return [Array<String>] List of operation type ids
425
+ def list_operation_definitions(resource_type_path)
426
+ parsed_path = CanonicalPath.parse(resource_type_path.to_s)
427
+ feed_id = parsed_path.feed_id
428
+ resource_type_id = parsed_path.resource_type_id
429
+ ret = http_get("/feeds/#{feed_id}/resourceTypes/#{resource_type_id}/operationTypes")
430
+ ret.map { |ot| ot['id'] }
431
+ end
432
+
433
+ # List operation definitions (types) for a given resource
434
+ # @param [String] resource_path canonical path of the resource entity
435
+ # @return [Array<String>] List of operation type ids
436
+ def list_operation_definitions_for_resource(resource_path)
437
+ resource = get_resource(resource_path.to_s, false)
438
+ list_operation_definitions(resource.type_path)
439
+ end
440
+
420
441
  # Create a Metric and associate it with a resource.
421
- # @param [String] feed_id Id of the feed
442
+ # @param [String] metric_type_path Canonical path of the metric type of the new metric.
443
+ # @param [String] resource_path Canonical path of the resource to which we want to associate the metric.
422
444
  # @param [String] metric_id Id of the metric
423
- # @param [String] type_path Full path of the MetricType
424
- # @param [Array<String>] res_ids Ids of the resource to associate the metric with (from parent to child)
425
445
  # @param [String] metric_name a (display) name for the metric. If nil, #metric_id is used.
426
446
  # @return [Metric] The metric created or if it already existed the version from the server
427
- # rubocop:disable Metrics/CyclomaticComplexity
428
- def create_metric_for_resource(feed_id, metric_id, type_path, res_ids, metric_name = nil)
429
- the_feed = hawk_escape_id feed_id
430
- res_path = res_ids.is_a?(Array) ? (res_ids.map { |id| hawk_escape_id id }.join('/')) : hawk_escape_id(res_ids)
447
+ def create_metric_for_resource(metric_type_path, resource_path, metric_id, metric_name = nil)
448
+ type_path = metric_type_path.is_a?(CanonicalPath) ? metric_type_path : CanonicalPath.parse(metric_type_path)
449
+ feed_id = type_path.feed_id
450
+ res_path = resource_path.is_a?(CanonicalPath) ? resource_path : CanonicalPath.parse(resource_path)
451
+ res_path_str = res_path.resource_ids.join('/')
431
452
 
432
453
  m = {}
433
454
  m['id'] = metric_id
434
455
  m['name'] = metric_name || metric_id
435
- m['metricTypePath'] = type_path
456
+ m['metricTypePath'] = type_path.to_s
436
457
 
437
458
  begin
438
- http_post("/feeds/#{the_feed}/metrics", m)
459
+ http_post("/feeds/#{feed_id}/metrics", m)
439
460
  rescue HawkularException => error
440
461
  # 409 We already exist -> that is ok
441
462
  raise unless error.status_code == 409
442
463
  end
443
464
 
444
- ret = http_get("/feeds/#{the_feed}/metrics/#{metric_id}")
465
+ ret = http_get("/feeds/#{feed_id}/metrics/#{metric_id}")
445
466
  the_metric = Metric.new(ret)
446
467
 
447
468
  begin
448
- http_post("/feeds/#{the_feed}/resources/#{res_path}/metrics", [the_metric.path])
469
+ http_post("/feeds/#{feed_id}/resources/#{res_path_str}/metrics", [the_metric.path])
449
470
  rescue HawkularException => error
450
471
  # 409 We already exist -> that is ok
451
472
  raise unless error.status_code == 409
452
473
  end
453
474
  the_metric
454
475
  end
455
- # rubocop:enable Metrics/CyclomaticComplexity
456
476
 
457
477
  # Listen on inventory changes
458
478
  # @param [String] type Type of entity for which we want the events.
@@ -510,15 +530,17 @@ module Hawkular::Inventory
510
530
  mt
511
531
  end
512
532
 
513
- def should_include?(metric_new, filter)
514
- found = true
515
- if filter.empty?
533
+ def filter_entities(entities, filter)
534
+ entities.select do |entity|
516
535
  found = true
517
- else
518
- found = false unless filter[:type] == (metric_new.type) || filter[:type].nil?
519
- found = false unless filter[:match].nil? || metric_new.id.include?(filter[:match])
536
+ if filter.empty?
537
+ found = true
538
+ else
539
+ found = false unless filter[:type] == (entity.type) || filter[:type].nil?
540
+ found = false unless filter[:match].nil? || entity.id.include?(filter[:match])
541
+ end
542
+ found
520
543
  end
521
- found
522
544
  end
523
545
  end
524
546
 
@@ -558,6 +580,10 @@ module Hawkular::Inventory
558
580
  end
559
581
  end
560
582
 
583
+ def ==(other)
584
+ self.eql?(other) || other.class == self.class && other.id == @id
585
+ end
586
+
561
587
  # Returns a hash representation of the resource type
562
588
  # @return [Hash<String,Object>] hash of the type
563
589
  def to_h
@@ -663,7 +689,6 @@ module Hawkular::Inventory
663
689
  attr_reader :metric_type_id
664
690
 
665
691
  def initialize(hash)
666
- fail 'At least tenant_id must be specified' if hash[:tenant_id].to_s.strip.length == 0
667
692
  @tenant_id = hash[:tenant_id]
668
693
  @feed_id = hash[:feed_id]
669
694
  @environment_id = hash[:environment_id]