topological_inventory-providers-common 2.0.0 → 2.1.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 134e945b201072b8bdd7fc6af73b04a6f60698da831ef3989ab973453a1a5159
4
- data.tar.gz: 20e4f260c411551572b557f4e4454fdc03c9e3b2ac9c8f5997e6600780298c1a
3
+ metadata.gz: 9c17638d4fd82db196de0019069a765bf1c6becdb20498765507ae35a02727eb
4
+ data.tar.gz: a395cd7243591bc3dab9f841e491bb978a2502d2ba1cfec3fdb004de784523dd
5
5
  SHA512:
6
- metadata.gz: 0a847566f6fb20e9518faef660c626788e6afd20d26cec28a5899e645c68cedd7c017974d0cb1c3c2524253007386b9728a1bb67a0f0a9101fe62bd388f03ccb
7
- data.tar.gz: 6e786659b1bf913fe1e22d9c0618986d03dc4bc169d782e446ecd089b97a136b639f83be85c562006dccde83a8d025b102863b565aa571746767fa292e4dae89
6
+ metadata.gz: ba2b33ec9748ef58b4ca7dc30f14d34443c17026e7915fb2bd9aef2a4ec95c4c287a8149a371b91cab88974a0341f7dfd362a987ca55ea644a5b67646adafde6
7
+ data.tar.gz: 41edf911fa71ef7dcdaa220a417a236e8a593a01e227ab4f0f88e70318141f8736ad8bd9bff7e642d6cef1134d017baa8aea0c1c194987b08770a721a7a2ff00
@@ -0,0 +1,31 @@
1
+ ---
2
+ version: '2'
3
+ prepare:
4
+ fetch:
5
+ - url: https://raw.githubusercontent.com/RedHatInsights/insights-api-common-rails/master/.rubocop_base.yml
6
+ path: ".rubocop_base.yml"
7
+ - url: https://raw.githubusercontent.com/RedHatInsights/insights-api-common-rails/master/.rubocop_cc_base.yml
8
+ path: ".rubocop_cc_base.yml"
9
+ checks:
10
+ argument-count:
11
+ enabled: false
12
+ complex-logic:
13
+ enabled: false
14
+ file-lines:
15
+ enabled: false
16
+ method-complexity:
17
+ config:
18
+ threshold: 11
19
+ method-count:
20
+ enabled: false
21
+ method-lines:
22
+ enabled: false
23
+ nested-control-flow:
24
+ enabled: false
25
+ return-statements:
26
+ enabled: false
27
+ plugins:
28
+ rubocop:
29
+ enabled: true
30
+ config: ".rubocop_cc.yml"
31
+ channel: rubocop-1-0
@@ -1,3 +1,3 @@
1
1
  inherit_from:
2
- - https://raw.githubusercontent.com/ManageIQ/guides/master/.rubocop_base.yml
2
+ - https://raw.githubusercontent.com/RedHatInsights/insights-api-common-rails/master/.rubocop_base.yml
3
3
  - .rubocop_local.yml
@@ -0,0 +1,8 @@
1
+ ---
2
+ ignore: |
3
+
4
+ extends: relaxed
5
+
6
+ rules:
7
+ line-length:
8
+ max: 120
@@ -3,11 +3,30 @@ All notable changes to this project will be documented in this file.
3
3
 
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
+ ## [2.1.4] - 2020-12-14
7
+ Common Counter metrics init #71
6
8
 
7
- ## [2.0.0]
9
+ ## [2.1.3] - 2020-12-14
10
+ Update travis URL in README file #67
11
+ Kafka availability_checks fix #68
12
+
13
+ ## [2.1.2] - 2020-11-24
14
+ Custom Metrics for AsyncWorker #60
15
+ Change error metric name to errors_total #64
16
+
17
+ ## [2.1.1] - 2020-11-04
18
+ MessagingClient and Source fix #61
19
+ Fix availability_check in app check #62
20
+
21
+ ## [2.1.0] - 2020-11-02
22
+ Add Availability checks for sources via Kafka #54
23
+ Common Metrics exporter #57
24
+ Rubocop rules from insights-api-common + yamllint #59
25
+
26
+ ## [2.0.0] - 2020-10-20
8
27
  Operations/API clients refactoring
9
28
 
10
- ## [1.0.12] - 2020-10-01
29
+ ## [1.0.12] - 2020-10-05
11
30
  Add Operations Async Worker class #55
12
31
 
13
32
  ## [1.0.11] - 2020-09-04
@@ -62,7 +81,11 @@ manageiq-loggers to >= 0.4.2 #20
62
81
  ## [1.0.0] - 2020-03-19
63
82
  ### Initial release to rubygems.org
64
83
 
65
- [Unreleased]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v2.0.0...HEAD
84
+ [Unreleased]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v2.1.3...HEAD
85
+ [2.1.3]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v2.1.2...v2.1.3
86
+ [2.1.2]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v2.1.1...v2.1.2
87
+ [2.1.1]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v2.1.0...v2.1.1
88
+ [2.1.0]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v2.0.0...v2.1.0
66
89
  [2.0.0]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v1.0.12...v2.0.0
67
90
  [1.0.12]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v1.0.11...v1.0.12
68
91
  [1.0.11]: https://github.com/RedHatInsights/topological_inventory-providers-common/compare/v1.0.10...v1.0.11
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # TopologicalInventory::Providers::Common
2
2
 
3
- [![Build Status](https://travis-ci.org/RedHatInsights/topological_inventory-providers-common.svg?branch=master)](https://travis-ci.org/RedHatInsights/topological_inventory-providers-common)
3
+ [![Build Status](https://travis-ci.com/RedHatInsights/topological_inventory-providers-common.svg?branch=master)](https://travis-ci.com/RedHatInsights/topological_inventory-providers-common)
4
4
  [![Maintainability](https://api.codeclimate.com/v1/badges/df747492b802bfea3c83/maintainability)](https://codeclimate.com/github/RedHatInsights/topological_inventory-providers-common/maintainability)
5
5
  [![Test Coverage](https://api.codeclimate.com/v1/badges/df747492b802bfea3c83/test_coverage)](https://codeclimate.com/github/RedHatInsights/topological_inventory-providers-common/test_coverage)
6
6
  [![security](https://hakiri.io/github/RedHatInsights/topological_inventory-providers-common/master.svg)](https://hakiri.io/github/RedHatInsights/topological_inventory-providers-common/master)
@@ -3,6 +3,7 @@ require "topological_inventory/providers/common/logging"
3
3
  require "topological_inventory/providers/common/operations/health_check"
4
4
  require "topological_inventory/providers/common/collectors_pool"
5
5
  require "topological_inventory/providers/common/collector"
6
+ require "topological_inventory/providers/common/metrics"
6
7
 
7
8
  module TopologicalInventory
8
9
  module Providers
@@ -0,0 +1,40 @@
1
+ require "more_core_extensions/core_ext/module/cache_with_timeout"
2
+ require "manageiq-messaging"
3
+
4
+ module TopologicalInventory
5
+ module Providers
6
+ module Common
7
+ class MessagingClient
8
+ # Kafka host name
9
+ attr_accessor :queue_host
10
+ # Kafka port
11
+ attr_accessor :queue_port
12
+
13
+ def initialize
14
+ self.queue_host = ENV['QUEUE_HOST'] || 'localhost'
15
+ self.queue_port = (ENV['QUEUE_PORT'] || 9092).to_i
16
+ end
17
+
18
+ def self.default
19
+ @@default ||= new
20
+ end
21
+
22
+ def self.configure
23
+ if block_given?
24
+ yield(default)
25
+ else
26
+ default
27
+ end
28
+ end
29
+
30
+ cache_with_timeout(:client) do
31
+ ManageIQ::Messaging::Client.open(:protocol => :Kafka, :host => default.queue_host, :port => default.queue_port)
32
+ end
33
+
34
+ def client
35
+ self.class.client
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,109 @@
1
+ require "benchmark"
2
+ require "prometheus_exporter"
3
+ require "prometheus_exporter/server"
4
+ require "prometheus_exporter/client"
5
+ require "prometheus_exporter/instrumentation"
6
+ require "topological_inventory/providers/common/mixins/statuses"
7
+
8
+ module TopologicalInventory
9
+ module Providers
10
+ module Common
11
+ class Metrics
12
+ include TopologicalInventory::Providers::Common::Mixins::Statuses
13
+
14
+ ERROR_COUNTER_MESSAGE = "total number of errors".freeze
15
+ ERROR_TYPES = %i[general].freeze
16
+ OPERATIONS = %w[].freeze
17
+
18
+ def initialize(port = 9394)
19
+ return if port == 0
20
+
21
+ configure_server(port)
22
+ configure_metrics
23
+
24
+ init_counters
25
+ end
26
+
27
+ def stop_server
28
+ @server&.stop
29
+ end
30
+
31
+ def record_error(type = :general)
32
+ @error_counter&.observe(1, :type => type.to_s)
33
+ end
34
+
35
+ def record_refresh_timing(labels = {}, &block)
36
+ record_time(@refresh_timer, labels, &block)
37
+ end
38
+
39
+ def record_operation(name, labels = {})
40
+ @status_counter&.observe(1, (labels || {}).merge(:name => name))
41
+ end
42
+
43
+ def record_operation_time(name, labels = {}, &block)
44
+ record_time(@duration_seconds, (labels || {}).merge(:name => name), &block)
45
+ end
46
+
47
+ # Common method for gauge
48
+ def record_gauge(metric, opt, value: nil, labels: {})
49
+ case opt
50
+ when :set then
51
+ metric&.observe(value.to_i, labels)
52
+ when :add then
53
+ metric&.increment(labels)
54
+ when :remove then
55
+ metric&.decrement(labels)
56
+ end
57
+ end
58
+
59
+ # Common method for histogram
60
+ def record_time(metric, labels = {})
61
+ result = nil
62
+ time = Benchmark.realtime { result = yield }
63
+ metric&.observe(time, labels)
64
+ result
65
+ end
66
+
67
+ private
68
+
69
+ # Set all values to 0 (otherwise the counter is undefined)
70
+ def init_counters
71
+ self.class::ERROR_TYPES.each do |err_type|
72
+ @error_counter&.observe(0, :type => err_type)
73
+ end
74
+
75
+ self.class::OPERATIONS.each do |op|
76
+ operation_status.each_key do |status|
77
+ @status_counter&.observe(0, :name => op, :status => status.to_s)
78
+ end
79
+ end
80
+ end
81
+
82
+ def configure_server(port)
83
+ @server = PrometheusExporter::Server::WebServer.new(:port => port)
84
+ @server.start
85
+
86
+ PrometheusExporter::Client.default = PrometheusExporter::LocalClient.new(:collector => @server.collector)
87
+ end
88
+
89
+ def configure_metrics
90
+ PrometheusExporter::Instrumentation::Process.start
91
+ PrometheusExporter::Metric::Base.default_prefix = default_prefix
92
+
93
+ @duration_seconds = PrometheusExporter::Metric::Histogram.new('duration_seconds', 'Duration of processed operation')
94
+ @refresh_timer = PrometheusExporter::Metric::Histogram.new('refresh_time', 'Duration of full refresh')
95
+ @error_counter = PrometheusExporter::Metric::Counter.new('errors_total', ERROR_COUNTER_MESSAGE)
96
+ @status_counter = PrometheusExporter::Metric::Counter.new('status_counter', 'number of processed operations')
97
+
98
+ [@duration_seconds, @refresh_timer, @error_counter, @status_counter].each do |metric|
99
+ @server.collector.register_metric(metric)
100
+ end
101
+ end
102
+
103
+ def default_prefix
104
+ raise NotImplementedError, "#{__method__} must be implemented in a subclass"
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
@@ -14,6 +14,7 @@ module TopologicalInventory
14
14
  def endpoint
15
15
  @endpoint ||= sources_api.fetch_default_endpoint(source_id)
16
16
  rescue => e
17
+ metrics&.record_error(:sources_api)
17
18
  logger.error_ext(operation, "Failed to fetch Endpoint for Source #{source_id}: #{e.message}")
18
19
  nil
19
20
  end
@@ -25,6 +26,7 @@ module TopologicalInventory
25
26
  sources_api.fetch_authentication(source_id, endpoint)
26
27
  end
27
28
  rescue => e
29
+ metrics&.record_error(:sources_api)
28
30
  logger.error_ext(operation, "Failed to fetch Authentication for Source #{source_id}: #{e.message}")
29
31
  nil
30
32
  end
@@ -32,6 +34,7 @@ module TopologicalInventory
32
34
  def application
33
35
  @application ||= sources_api.fetch_application(source_id)
34
36
  rescue => e
37
+ metrics&.record_error(:sources_api)
35
38
  logger.error_ext(operation, "Failed to fetch Application for Source #{source_id}: #{e.message}")
36
39
  nil
37
40
  end
@@ -0,0 +1,19 @@
1
+ module TopologicalInventory
2
+ module Providers
3
+ module Common
4
+ module Mixins
5
+ module Statuses
6
+ def operation_status
7
+ return @statuses if @statuses.present?
8
+
9
+ @statuses = {}
10
+ %i[success error skipped not_implemented].each do |status|
11
+ @statuses[status] = status.to_s
12
+ end
13
+ @statuses
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -1,4 +1,5 @@
1
1
  require "topological_inventory/providers/common/logging"
2
+ require "topological_inventory/providers/common/mixins/statuses"
2
3
  require "topological_inventory/providers/common/operations/health_check"
3
4
 
4
5
  module TopologicalInventory
@@ -7,10 +8,12 @@ module TopologicalInventory
7
8
  module Operations
8
9
  class AsyncWorker
9
10
  include Logging
11
+ include TopologicalInventory::Providers::Common::Mixins::Statuses
10
12
 
11
- def initialize(processor, queue = nil)
13
+ def initialize(processor, queue: nil, metrics: nil)
12
14
  @processor = processor
13
- @queue = queue || Queue.new
15
+ @queue = queue || Queue.new
16
+ @metrics = metrics
14
17
  end
15
18
 
16
19
  def start
@@ -37,15 +40,17 @@ module TopologicalInventory
37
40
 
38
41
  private
39
42
 
40
- attr_reader :thread, :queue, :processor
43
+ attr_reader :thread, :queue, :processor, :metrics
41
44
 
42
- def process_message(msg)
43
- processor.process!(msg)
45
+ def process_message(message)
46
+ result = processor.process!(message, metrics)
47
+ metrics&.record_operation(message.message, :status => result)
44
48
  rescue => err
45
- model, method = msg.message.to_s.split(".")
49
+ model, method = message.message.to_s.split(".")
46
50
  logger.error("#{model}##{method}: async worker failure: #{err.cause}\n#{err}\n#{err.backtrace.join("\n")}")
51
+ metrics&.record_operation(message.message, :status => operation_status[:error])
47
52
  ensure
48
- msg.ack
53
+ message.ack
49
54
  TopologicalInventory::Providers::Common::Operations::HealthCheck.touch_file
50
55
  logger.debug("Operations::AsyncWorker queue length: #{queue.length}") if queue.length >= 20 && queue.length % 5 == 0
51
56
  end
@@ -0,0 +1,77 @@
1
+ require "topological_inventory/providers/common/logging"
2
+ require "topological_inventory/providers/common/mixins/statuses"
3
+ require "topological_inventory/providers/common/mixins/topology_api"
4
+
5
+ module TopologicalInventory
6
+ module Providers
7
+ module Common
8
+ module Operations
9
+ class Processor
10
+ include Logging
11
+ include Mixins::Statuses
12
+ include Mixins::TopologyApi
13
+
14
+ def self.process!(message, metrics)
15
+ new(message, metrics).process
16
+ end
17
+
18
+ def initialize(message, metrics)
19
+ self.message = message
20
+ self.metrics = metrics
21
+ self.model, self.method = message.message.split(".")
22
+
23
+ self.params = message.payload["params"]
24
+ self.identity = message.payload["request_context"]
25
+ end
26
+
27
+ def process
28
+ logger.info(status_log_msg)
29
+ impl = operation_class&.new(params, identity, metrics)
30
+ if impl&.respond_to?(method)
31
+ with_time_measure do
32
+ result = impl.send(method)
33
+
34
+ logger.info(status_log_msg("Complete"))
35
+ result
36
+ end
37
+ else
38
+ logger.warn(status_log_msg("Not Implemented!"))
39
+ complete_task("not implemented") if params["task_id"]
40
+ operation_status[:not_implemented]
41
+ end
42
+ rescue StandardError, NotImplementedError => e
43
+ complete_task(e.message) if params["task_id"]
44
+ raise
45
+ end
46
+
47
+ private
48
+
49
+ attr_accessor :message, :identity, :model, :method, :metrics, :params
50
+
51
+ def operation_class
52
+ raise NotImplementedError, "#{__method__} must be implemented in a subclass"
53
+ end
54
+
55
+ def with_time_measure
56
+ if metrics.present?
57
+ metrics.record_operation_time(message.message) { yield }
58
+ else
59
+ yield
60
+ end
61
+ end
62
+
63
+ def complete_task(msg, status = "error")
64
+ update_task(params["task_id"],
65
+ :state => "completed",
66
+ :status => status,
67
+ :context => {:error => "#{model}##{method} - #{msg}"})
68
+ end
69
+
70
+ def status_log_msg(status = nil)
71
+ "Processing #{model}##{method} [#{params}]...#{status}"
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -1,7 +1,9 @@
1
1
  require "topological_inventory/providers/common/logging"
2
2
  require "active_support/core_ext/numeric/time"
3
3
  require "topological_inventory/providers/common/mixins/sources_api"
4
+ require "topological_inventory/providers/common/mixins/statuses"
4
5
  require "topological_inventory/providers/common/mixins/x_rh_headers"
6
+ require "topological_inventory/providers/common/messaging_client"
5
7
 
6
8
  module TopologicalInventory
7
9
  module Providers
@@ -11,8 +13,11 @@ module TopologicalInventory
11
13
  include Logging
12
14
  include Mixins::SourcesApi
13
15
  include Mixins::XRhHeaders
16
+ include Mixins::Statuses
14
17
 
15
18
  STATUS_AVAILABLE, STATUS_UNAVAILABLE = %w[available unavailable].freeze
19
+ EVENT_AVAILABILITY_STATUS = "availability_status".freeze
20
+ SERVICE_NAME = "platform.sources.status".freeze
16
21
 
17
22
  ERROR_MESSAGES = {
18
23
  :authentication_not_found => "Authentication not found in Sources API",
@@ -20,36 +25,41 @@ module TopologicalInventory
20
25
  }.freeze
21
26
 
22
27
  LAST_CHECKED_AT_THRESHOLD = 5.minutes.freeze
23
- AUTH_NOT_NECESSARY = "n/a".freeze
28
+ AUTH_NOT_NECESSARY = "n/a".freeze
24
29
 
25
30
  attr_accessor :identity, :operation, :params, :request_context, :source_id, :account_number
26
31
 
27
- def initialize(params = {}, request_context = nil)
28
- self.operation = 'Source'
29
- self.params = params
30
- self.request_context = request_context
31
- self.source_id = params['source_id']
32
-
33
- self.account_number = params['external_tenant']
34
- self.identity = identity_by_account_number(account_number)
32
+ def initialize(params = {}, request_context = nil, metrics = nil)
33
+ self.metrics = metrics
34
+ self.operation = 'Source'
35
+ self.params = params
36
+ self.request_context = request_context
37
+ self.source_id = params['source_id']
38
+ self.account_number = params['external_tenant']
39
+ self.updates_via_kafka = ENV['UPDATE_SOURCES_VIA_API'].blank?
40
+ self.identity = identity_by_account_number(account_number)
35
41
  end
36
42
 
37
43
  def availability_check
38
44
  self.operation += '#availability_check'
39
45
 
40
- return if params_missing?
46
+ return operation_status[:error] if params_missing?
41
47
 
42
- return if checked_recently?
48
+ return operation_status[:skipped] if checked_recently?
43
49
 
44
50
  status, error_message = connection_status
45
51
 
46
52
  update_source_and_subresources(status, error_message)
47
53
 
48
54
  logger.availability_check("Completed: Source #{source_id} is #{status}")
55
+
56
+ operation_status[:success]
49
57
  end
50
58
 
51
59
  private
52
60
 
61
+ attr_accessor :metrics, :updates_via_kafka
62
+
53
63
  def required_params
54
64
  %w[source_id]
55
65
  end
@@ -73,7 +83,7 @@ module TopologicalInventory
73
83
  application.last_checked_at.present? && application.last_checked_at >= LAST_CHECKED_AT_THRESHOLD.ago
74
84
  end
75
85
 
76
- logger.availability_check("Skipping, last check at #{endpoint.last_checked_at || application.last_checked_at} [Source ID: #{source_id}] ") if checked_recently
86
+ logger.availability_check("Skipping, last check at #{endpoint&.last_checked_at || application&.last_checked_at} [Source ID: #{source_id}] ") if checked_recently
77
87
 
78
88
  checked_recently
79
89
  end
@@ -114,10 +124,15 @@ module TopologicalInventory
114
124
  def update_source_and_subresources(status, error_message = nil)
115
125
  logger.availability_check("Updating source [#{source_id}] status [#{status}] message [#{error_message}]")
116
126
 
117
- update_source(status)
118
-
119
- update_endpoint(status, error_message) if endpoint
120
- update_application(status) if application
127
+ if updates_via_kafka
128
+ update_source_by_kafka(status)
129
+ update_endpoint_by_kafka(status, error_message) if endpoint
130
+ update_application_by_kafka(status) if application
131
+ else
132
+ update_source(status)
133
+ update_endpoint(status, error_message) if endpoint
134
+ update_application(status) if application
135
+ end
121
136
  end
122
137
 
123
138
  def update_source(status)
@@ -128,9 +143,18 @@ module TopologicalInventory
128
143
 
129
144
  sources_api.update_source(source_id, source)
130
145
  rescue ::SourcesApiClient::ApiError => e
146
+ metrics&.record_error(:sources_api)
131
147
  logger.availability_check("Failed to update Source id:#{source_id} - #{e.message}", :error)
132
148
  end
133
149
 
150
+ def update_source_by_kafka(status)
151
+ availability_status_message(
152
+ :resource_type => "Source",
153
+ :resource_id => source_id,
154
+ :status => status
155
+ )
156
+ end
157
+
134
158
  def update_endpoint(status, error_message)
135
159
  if endpoint.nil?
136
160
  logger.availability_check("Failed to update Endpoint for Source id:#{source_id}. Endpoint not found", :error)
@@ -146,19 +170,59 @@ module TopologicalInventory
146
170
 
147
171
  sources_api.update_endpoint(endpoint.id, endpoint_update)
148
172
  rescue ::SourcesApiClient::ApiError => e
173
+ metrics&.record_error(:sources_api)
149
174
  logger.availability_check("Failed to update Endpoint(ID: #{endpoint.id}) - #{e.message}", :error)
150
175
  end
151
176
 
177
+ def update_endpoint_by_kafka(status, error_message)
178
+ if endpoint.nil?
179
+ logger.availability_check("Failed to update Endpoint for Source id:#{source_id}. Endpoint not found", :error)
180
+ return
181
+ end
182
+
183
+ availability_status_message(
184
+ :resource_type => "Endpoint",
185
+ :resource_id => endpoint.id,
186
+ :status => status,
187
+ :error => error_message
188
+ )
189
+ end
190
+
152
191
  def update_application(status)
153
- application_update = ::SourcesApiClient::Application.new
154
- application_update.last_checked_at = check_time
155
- application_update.last_available_at = check_time if status == STATUS_AVAILABLE
192
+ application_update = ::SourcesApiClient::Application.new
193
+ application_update.last_checked_at = check_time
194
+ application_update.last_available_at = check_time if status == STATUS_AVAILABLE
156
195
 
157
196
  sources_api.update_application(application.id, application_update)
158
197
  rescue ::SourcesApiClient::ApiError => e
198
+ metrics&.record_error(:sources_api)
159
199
  logger.availability_check("Failed to update Application id: #{application.id} - #{e.message}", :error)
160
200
  end
161
201
 
202
+ def update_application_by_kafka(status)
203
+ availability_status_message(
204
+ :resource_type => "Application",
205
+ :resource_id => application.id,
206
+ :status => status
207
+ )
208
+ end
209
+
210
+ def availability_status_message(payload)
211
+ messaging_client.publish_topic(
212
+ :service => SERVICE_NAME,
213
+ :event => EVENT_AVAILABILITY_STATUS,
214
+ :payload => payload.to_json
215
+ )
216
+ rescue => err
217
+ logger.availability_check("Failed to update #{payload[:resource_type]} id: #{payload[:resource_id]} - #{err.message}", :error)
218
+ ensure
219
+ messaging_client&.close
220
+ end
221
+
222
+ def messaging_client
223
+ TopologicalInventory::Providers::Common::MessagingClient.default.client
224
+ end
225
+
162
226
  def check_time
163
227
  @check_time ||= Time.now.utc
164
228
  end