topological_inventory-providers-common 1.0.7 → 1.0.12

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
  SHA256:
3
- metadata.gz: 868c8f764cd11d9888ed99698a309cc199fdf92823963f4e5cae71208d506ff7
4
- data.tar.gz: 39c352e8b1306bdb87675bf0ccc1fe08f02b0c13555b2466c4c38d7a76979aca
3
+ metadata.gz: b81c523169c3ca87e678e3e7d046b4daee863200cf4eadd695e9022d17a11e5a
4
+ data.tar.gz: 1fc2a47cedf6f8d3b41f0df728a5ac8ceceaea03b58d43ef67da90680861c0eb
5
5
  SHA512:
6
- metadata.gz: c2a8af390114548a89c7dc5bb43f1a6e3784a5a59ebd2ce1c7451c15726015df1353e3dcbc3755d7637d696707b0d6db93e5d4907920a1c4b09d3f6410130a77
7
- data.tar.gz: 46e6596954367336de4049f8024da8b5e63e5be4c60636c77f91f22c3e407229b38aca604137907d1f5cd6411201d9c3b57e4ad5bab2cfb749b2c04e9ca8eeab
6
+ metadata.gz: 9afb8ba326d632ba59245d93837f32bd8edbcb34b3d82e029c351f904bb75f196592eb4724116a48caf0b7df8fc7f4101f5b59bd0e23b65d6fca25ada3ac4cb6
7
+ data.tar.gz: '00924d04d1fc4623cd4e0f0a719c5471dbd39635820375b4957278db1c6e3ecbdf2b58c25758bca22e91e979511286708279922919f6303118401e58ac9cc5c4'
@@ -4,6 +4,22 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [1.0.12] - 2020-10-01
8
+ Add Operations Async Worker class #55
9
+
10
+ ## [1.0.11]
11
+ Make Collector Poll Time a parameter so we can tweak the collection interval #51
12
+
13
+ ## [1.0.10]
14
+ Add HealthCheck class for operations workers #48
15
+ Set the LOG_LEVEL if present #50
16
+
17
+ ## [1.0.9]
18
+ Added refresh-type to save and sweep inventory #45
19
+
20
+ ## [1.0.8] - 2020-08-12
21
+ Add => to error messages that rubocop missed #44
22
+
7
23
  ## [1.0.7] - 2020-07-27
8
24
  Update operations/source model for receptor-enabled availability checks #36
9
25
  Add check for Application subresource under a Source during Availability check #40
@@ -43,8 +59,13 @@ manageiq-loggers to >= 0.4.2 #20
43
59
  ## [1.0.0] - 2020-03-19
44
60
  ### Initial release to rubygems.org
45
61
 
46
- [Unreleased]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v1.0.7...HEAD
47
- [1.0.6]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v1.0.6...v1.0.7
62
+ [Unreleased]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v1.0.12...HEAD
63
+ [1.0.12]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v1.0.11...v1.0.12
64
+ [1.0.11]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v1.0.10...v1.0.11
65
+ [1.0.10]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v1.0.9...v1.0.10
66
+ [1.0.9]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v1.0.8...v1.0.9
67
+ [1.0.8]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v1.0.7...v1.0.8
68
+ [1.0.7]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v1.0.6...v1.0.7
48
69
  [1.0.6]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v1.0.5...v1.0.6
49
70
  [1.0.5]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v1.0.4...v1.0.5
50
71
  [1.0.4]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v1.0.3...v1.0.4
@@ -2,6 +2,7 @@ require "topological_inventory/providers/common/version"
2
2
  require "topological_inventory/providers/common/logging"
3
3
  require "topological_inventory/providers/common/operations/processor"
4
4
  require "topological_inventory/providers/common/operations/endpoint_client"
5
+ require "topological_inventory/providers/common/operations/health_check"
5
6
  require "topological_inventory/providers/common/collectors_pool"
6
7
  require "topological_inventory/providers/common/collector"
7
8
 
@@ -104,7 +104,8 @@ module TopologicalInventory
104
104
  refresh_state_uuid = nil,
105
105
  refresh_state_part_uuid = nil,
106
106
  refresh_state_part_collected_at = nil,
107
- refresh_state_part_sent_at = Time.now.utc)
107
+ refresh_state_part_sent_at = Time.now.utc,
108
+ refresh_type = default_refresh_type)
108
109
  return 0 if collections.empty?
109
110
 
110
111
  SaveInventory::Saver.new(:client => ingress_api_client, :logger => logger).save(
@@ -116,7 +117,8 @@ module TopologicalInventory
116
117
  :refresh_state_uuid => refresh_state_uuid,
117
118
  :refresh_state_part_uuid => refresh_state_part_uuid,
118
119
  :refresh_state_part_collected_at => refresh_state_part_collected_at,
119
- :refresh_state_part_sent_at => refresh_state_part_sent_at
120
+ :refresh_state_part_sent_at => refresh_state_part_sent_at,
121
+ :refresh_type => refresh_type
120
122
  )
121
123
  )
122
124
  rescue => e
@@ -134,7 +136,8 @@ module TopologicalInventory
134
136
  total_parts,
135
137
  sweep_scope,
136
138
  refresh_state_started_at = nil,
137
- refresh_state_sent_at = Time.now.utc)
139
+ refresh_state_sent_at = Time.now.utc,
140
+ refresh_type = default_refresh_type)
138
141
  return if !total_parts || sweep_scope.empty?
139
142
 
140
143
  SaveInventory::Saver.new(:client => ingress_api_client, :logger => logger).save(
@@ -147,7 +150,8 @@ module TopologicalInventory
147
150
  :total_parts => total_parts,
148
151
  :sweep_scope => sweep_scope,
149
152
  :refresh_state_started_at => refresh_state_started_at,
150
- :refresh_state_sent_at => refresh_state_sent_at
153
+ :refresh_state_sent_at => refresh_state_sent_at,
154
+ :refresh_type => refresh_type
151
155
  )
152
156
  )
153
157
  rescue => e
@@ -165,6 +169,10 @@ module TopologicalInventory
165
169
  "Default"
166
170
  end
167
171
 
172
+ def default_refresh_type
173
+ 'full-refresh'
174
+ end
175
+
168
176
  def ingress_api_client
169
177
  TopologicalInventoryIngressApiClient::DefaultApi.new
170
178
  end
@@ -5,8 +5,9 @@ module TopologicalInventory
5
5
  module Common
6
6
  class CollectorsPool
7
7
  SECRET_FILENAME = "credentials".freeze
8
+ COLLECTOR_POLL_TIME = ENV['COLLECTOR_POLL_TIME']&.to_i || 300
8
9
 
9
- def initialize(config_name, metrics, collector_poll_time: 60, thread_pool_size: 2)
10
+ def initialize(config_name, metrics, collector_poll_time: COLLECTOR_POLL_TIME, thread_pool_size: 2)
10
11
  self.config_name = config_name
11
12
  self.collector_status = Concurrent::Map.new
12
13
  self.metrics = metrics
@@ -33,7 +33,10 @@ module TopologicalInventory
33
33
 
34
34
  class Logger < ManageIQ::Loggers::CloudWatch
35
35
  def self.new(*args)
36
- super.tap { |logger| logger.extend(TopologicalInventory::Providers::Common::LoggingFunctions) }
36
+ super.tap do |logger|
37
+ logger.extend(TopologicalInventory::Providers::Common::LoggingFunctions)
38
+ logger.level = ENV['LOG_LEVEL'] if ENV['LOG_LEVEL']
39
+ end
37
40
  end
38
41
  end
39
42
 
@@ -0,0 +1,56 @@
1
+ require "topological_inventory/providers/common/logging"
2
+ require "topological_inventory/providers/common/operations/health_check"
3
+
4
+ module TopologicalInventory
5
+ module Providers
6
+ module Common
7
+ module Operations
8
+ class AsyncWorker
9
+ include Logging
10
+
11
+ def initialize(processor, queue = nil)
12
+ @processor = processor
13
+ @queue = queue || Queue.new
14
+ end
15
+
16
+ def start
17
+ return if thread.present?
18
+
19
+ @thread = Thread.new { listen }
20
+ end
21
+
22
+ def stop
23
+ thread&.exit
24
+ end
25
+
26
+ def enqueue(msg)
27
+ queue << msg
28
+ end
29
+
30
+ def listen
31
+ loop do
32
+ # the queue thread waits for a message to come during `Queue#pop`
33
+ msg = queue.pop
34
+ process_message(msg)
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ attr_reader :thread, :queue, :processor
41
+
42
+ def process_message(msg)
43
+ processor.process!(msg)
44
+ rescue => err
45
+ model, method = msg.message.to_s.split(".")
46
+ logger.error("#{model}##{method}: async worker failure: #{err.cause}\n#{err}\n#{err.backtrace.join("\n")}")
47
+ ensure
48
+ msg.ack
49
+ TopologicalInventory::Providers::Common::Operations::HealthCheck.touch_file
50
+ logger.debug("Operations::AsyncWorker queue length: #{queue.length}") if queue.length >= 20 && queue.length % 5 == 0
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,15 @@
1
+ module TopologicalInventory
2
+ module Providers
3
+ module Common
4
+ module Operations
5
+ class HealthCheck
6
+ HEARTBEAT_FILE = '/tmp/healthy'.freeze
7
+
8
+ def self.touch_file
9
+ FileUtils.touch(HEARTBEAT_FILE)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -153,8 +153,9 @@ module TopologicalInventory
153
153
 
154
154
  def endpoint
155
155
  @endpoint ||= api_client.fetch_default_endpoint(source_id)
156
- rescue e
156
+ rescue => e
157
157
  logger.availability_check("Failed to fetch Endpoint for Source #{source_id}: #{e.message}", :error)
158
+ nil
158
159
  end
159
160
 
160
161
  def authentication
@@ -163,14 +164,16 @@ module TopologicalInventory
163
164
  else
164
165
  api_client.fetch_authentication(source_id, endpoint)
165
166
  end
166
- rescue e
167
+ rescue => e
167
168
  logger.availability_check("Failed to fetch Authentication for Source #{source_id}: #{e.message}", :error)
169
+ nil
168
170
  end
169
171
 
170
172
  def application
171
173
  @application ||= api_client.fetch_application(source_id)
172
- rescue e
174
+ rescue => e
173
175
  logger.availability_check("Failed to fetch Application for Source #{source_id}: #{e.message}", :error)
176
+ nil
174
177
  end
175
178
 
176
179
  def check_time
@@ -1,7 +1,7 @@
1
1
  module TopologicalInventory
2
2
  module Providers
3
3
  module Common
4
- VERSION = "1.0.7"
4
+ VERSION = "1.0.12"
5
5
  end
6
6
  end
7
7
  end
@@ -42,7 +42,7 @@ RSpec.shared_examples "availability_check" do
42
42
  stub_get(:endpoint, list_endpoints_response)
43
43
  stub_get(:authentication, list_endpoint_authentications_response)
44
44
  stub_get(:password, internal_api_authentication_response)
45
- stub_get(:application, "[]")
45
+ stub_not_found(:application)
46
46
 
47
47
  # PATCH
48
48
  source_patch_body = {'availability_status' => described_class::STATUS_AVAILABLE, 'last_available_at' => subject.send(:check_time), 'last_checked_at' => subject.send(:check_time)}.to_json
@@ -65,7 +65,7 @@ RSpec.shared_examples "availability_check" do
65
65
  stub_get(:endpoint, list_endpoints_response)
66
66
  stub_get(:authentication, list_endpoint_authentications_response)
67
67
  stub_get(:password, internal_api_authentication_response)
68
- stub_get(:application, "[]")
68
+ stub_not_found(:application)
69
69
 
70
70
  # PATCH
71
71
  connection_error_message = "Some connection error"
@@ -86,8 +86,8 @@ RSpec.shared_examples "availability_check" do
86
86
 
87
87
  it "updates only Source to 'unavailable' status if Endpoint not found" do
88
88
  # GET
89
- stub_get(:endpoint, '')
90
- stub_get(:application, "[]")
89
+ stub_not_found(:endpoint)
90
+ stub_not_found(:application)
91
91
 
92
92
  # PATCH
93
93
  source_patch_body = {'availability_status' => described_class::STATUS_UNAVAILABLE, 'last_checked_at' => subject.send(:check_time)}.to_json
@@ -106,7 +106,7 @@ RSpec.shared_examples "availability_check" do
106
106
  # GET
107
107
  stub_get(:endpoint, list_endpoints_response)
108
108
  stub_get(:authentication, list_endpoint_authentications_response_empty)
109
- stub_get(:application, "[]")
109
+ stub_not_found(:application)
110
110
 
111
111
  # PATCH
112
112
  source_patch_body = {'availability_status' => described_class::STATUS_UNAVAILABLE, 'last_checked_at' => subject.send(:check_time)}.to_json
@@ -142,7 +142,7 @@ RSpec.shared_examples "availability_check" do
142
142
  context "when it is available" do
143
143
  it "updates the availability status to available" do
144
144
  # GET
145
- stub_get(:endpoint, "[]")
145
+ stub_not_found(:endpoint)
146
146
  stub_get(:application, list_applications_response)
147
147
  # PATCH
148
148
  application_patch_body = {'last_available_at' => subject.send(:check_time), 'last_checked_at' => subject.send(:check_time)}.to_json
@@ -163,7 +163,7 @@ RSpec.shared_examples "availability_check" do
163
163
  context "when it is unavailable" do
164
164
  it "updates the availability status to unavailable" do
165
165
  # GET
166
- stub_get(:endpoint, "[]")
166
+ stub_not_found(:endpoint)
167
167
  stub_get(:application, list_applications_unavailable_response)
168
168
  # PATCH
169
169
  application_patch_body = {'last_checked_at' => subject.send(:check_time)}.to_json
@@ -203,6 +203,27 @@ RSpec.shared_examples "availability_check" do
203
203
  end
204
204
  end
205
205
 
206
+ def stub_not_found(object_type)
207
+ case object_type
208
+ when :endpoint
209
+ stub_request(:get, "#{sources_api_url}/sources/#{source_id}/endpoints")
210
+ .with(:headers => headers)
211
+ .to_return(:status => 404, :body => {}.to_json, :headers => {})
212
+ when :authentication
213
+ stub_request(:get, "#{sources_api_url}/endpoints/#{endpoint_id}/authentications")
214
+ .with(:headers => headers)
215
+ .to_return(:status => 404, :body => {}.to_json, :headers => {})
216
+ when :password
217
+ stub_request(:get, "#{host_url}#{sources_internal_api_path}/authentications/#{authentication_id}?expose_encrypted_attribute%5B%5D=password")
218
+ .with(:headers => headers)
219
+ .to_return(:status => 404, :body => {}.to_json, :headers => {})
220
+ when :application
221
+ stub_request(:get, "#{sources_api_url}/sources/#{source_id}/applications")
222
+ .with(:headers => headers)
223
+ .to_return(:status => 404, :body => {}.to_json, :headers => {})
224
+ end
225
+ end
226
+
206
227
  def stub_patch(object_type, data)
207
228
  case object_type
208
229
  when :source
@@ -0,0 +1,36 @@
1
+ require "topological_inventory/providers/common/operations/async_worker"
2
+
3
+ describe TopologicalInventory::Providers::Common::Operations::AsyncWorker do
4
+ let(:queue) { double }
5
+ let(:impl) { double }
6
+ let(:msg) { double }
7
+ subject { described_class.new(impl, queue) }
8
+
9
+ before do
10
+ allow(queue).to receive(:length).and_return(0)
11
+ allow(msg).to receive(:message).and_return("Source.availability_check")
12
+ end
13
+
14
+ context "when the message is able to be processed" do
15
+ before do
16
+ allow(impl).to receive(:process!).with(msg)
17
+ allow(msg).to receive(:ack)
18
+ end
19
+
20
+ it "drains messages that are added to the queue" do
21
+ expect(impl).to receive(:process!).with(msg).once
22
+ subject.send(:process_message, msg)
23
+ end
24
+ end
25
+
26
+ context "when the message results in an error" do
27
+ before do
28
+ allow(impl).to receive(:process!).with(msg).and_raise(StandardError.new("boom!"))
29
+ end
30
+
31
+ it "ack's the message on failure" do
32
+ expect(msg).to receive(:ack).once
33
+ subject.send(:process_message, msg)
34
+ end
35
+ end
36
+ end
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
29
29
  spec.add_runtime_dependency "manageiq-loggers", ">= 0.4.2"
30
30
  spec.add_runtime_dependency "sources-api-client", "~> 3.0"
31
31
  spec.add_runtime_dependency "topological_inventory-api-client", "~> 3.0", ">= 3.0.1"
32
- spec.add_runtime_dependency "topological_inventory-ingress_api-client", "~> 1.0"
32
+ spec.add_runtime_dependency "topological_inventory-ingress_api-client", "~> 1.0", ">= 1.0.3"
33
33
 
34
34
  spec.add_development_dependency "bundler", "~> 2.0"
35
35
  spec.add_development_dependency "rake", ">= 12.3.3"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: topological_inventory-providers-common
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.7
4
+ version: 1.0.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Slemr
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-07-28 00:00:00.000000000 Z
11
+ date: 2020-10-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -113,6 +113,9 @@ dependencies:
113
113
  - - "~>"
114
114
  - !ruby/object:Gem::Version
115
115
  version: '1.0'
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: 1.0.3
116
119
  type: :runtime
117
120
  prerelease: false
118
121
  version_requirements: !ruby/object:Gem::Requirement
@@ -120,6 +123,9 @@ dependencies:
120
123
  - - "~>"
121
124
  - !ruby/object:Gem::Version
122
125
  version: '1.0'
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: 1.0.3
123
129
  - !ruby/object:Gem::Dependency
124
130
  name: bundler
125
131
  requirement: !ruby/object:Gem::Requirement
@@ -246,7 +252,9 @@ files:
246
252
  - lib/topological_inventory/providers/common/collector/parser.rb
247
253
  - lib/topological_inventory/providers/common/collectors_pool.rb
248
254
  - lib/topological_inventory/providers/common/logging.rb
255
+ - lib/topological_inventory/providers/common/operations/async_worker.rb
249
256
  - lib/topological_inventory/providers/common/operations/endpoint_client.rb
257
+ - lib/topological_inventory/providers/common/operations/health_check.rb
250
258
  - lib/topological_inventory/providers/common/operations/processor.rb
251
259
  - lib/topological_inventory/providers/common/operations/source.rb
252
260
  - lib/topological_inventory/providers/common/operations/sources_api_client.rb
@@ -262,6 +270,7 @@ files:
262
270
  - spec/topological_inventory/providers/common/collectors/inventory_collection_wrapper_spec.rb
263
271
  - spec/topological_inventory/providers/common/collectors_pool_spec.rb
264
272
  - spec/topological_inventory/providers/common/logger_spec.rb
273
+ - spec/topological_inventory/providers/common/operations/async_worker_spec.rb
265
274
  - spec/topological_inventory/providers/common/operations/processor_spec.rb
266
275
  - spec/topological_inventory/providers/common/operations/source_spec.rb
267
276
  - spec/topological_inventory/providers/common/save_inventory/saver_spec.rb