topological_inventory-providers-common 1.0.11 → 2.1.2

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 (27) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +31 -0
  3. data/.rubocop.yml +1 -1
  4. data/.yamllint +8 -0
  5. data/CHANGELOG.md +28 -4
  6. data/lib/topological_inventory/providers/common.rb +1 -2
  7. data/lib/topological_inventory/providers/common/logging.rb +6 -3
  8. data/lib/topological_inventory/providers/common/messaging_client.rb +40 -0
  9. data/lib/topological_inventory/providers/common/metrics.rb +84 -0
  10. data/lib/topological_inventory/providers/common/mixins/sources_api.rb +61 -0
  11. data/lib/topological_inventory/providers/common/mixins/statuses.rb +19 -0
  12. data/lib/topological_inventory/providers/common/mixins/topology_api.rb +26 -0
  13. data/lib/topological_inventory/providers/common/mixins/x_rh_headers.rb +24 -0
  14. data/lib/topological_inventory/providers/common/operations/async_worker.rb +61 -0
  15. data/lib/topological_inventory/providers/common/operations/processor.rb +46 -104
  16. data/lib/topological_inventory/providers/common/operations/source.rb +183 -144
  17. data/lib/topological_inventory/providers/common/sources_api_client.rb +92 -0
  18. data/lib/topological_inventory/providers/common/topology_api_client.rb +43 -0
  19. data/lib/topological_inventory/providers/common/version.rb +1 -1
  20. data/spec/support/shared/availability_check.rb +254 -90
  21. data/spec/topological_inventory/providers/common/operations/async_worker_spec.rb +45 -0
  22. data/spec/topological_inventory/providers/common/operations/processor_spec.rb +52 -83
  23. data/topological_inventory-providers-common.gemspec +14 -10
  24. metadata +74 -9
  25. data/lib/topological_inventory/providers/common/operations/endpoint_client.rb +0 -65
  26. data/lib/topological_inventory/providers/common/operations/sources_api_client.rb +0 -94
  27. data/lib/topological_inventory/providers/common/operations/topology_api_client.rb +0 -28
@@ -0,0 +1,92 @@
1
+ require "sources-api-client"
2
+
3
+ module TopologicalInventory
4
+ module Providers
5
+ module Common
6
+ class SourcesApiClient < ::SourcesApiClient::ApiClient
7
+ delegate :update_source, :update_endpoint, :update_application, :to => :api
8
+
9
+ INTERNAL_API_PATH = '//internal/v1.0'.freeze
10
+
11
+ def initialize(identity = nil)
12
+ super(::SourcesApiClient::Configuration.default)
13
+ self.identity = identity
14
+ self.api = init_default_api
15
+ end
16
+
17
+ def init_default_api
18
+ default_headers.merge!(identity) if identity.present?
19
+ ::SourcesApiClient::DefaultApi.new(self)
20
+ end
21
+
22
+ def fetch_default_endpoint(source_id)
23
+ endpoints = api.list_source_endpoints(source_id)&.data || []
24
+ endpoints.find(&:default)
25
+ end
26
+
27
+ def fetch_application(source_id)
28
+ applications = api.list_source_applications(source_id)&.data || []
29
+ applications.first
30
+ end
31
+
32
+ def fetch_authentication(source_id, default_endpoint = nil, authtype = nil)
33
+ endpoint = default_endpoint || fetch_default_endpoint(source_id)
34
+ return if endpoint.nil?
35
+
36
+ endpoint_authentications = api.list_endpoint_authentications(endpoint.id.to_s).data || []
37
+ return if endpoint_authentications.empty?
38
+
39
+ auth_id = if authtype.nil?
40
+ endpoint_authentications.first&.id
41
+ else
42
+ endpoint_authentications.detect { |a| a.authtype = authtype }&.id
43
+ end
44
+ return if auth_id.nil?
45
+
46
+ fetch_authentication_with_password(auth_id)
47
+ end
48
+
49
+ private
50
+
51
+ attr_accessor :identity, :api, :custom_base_path
52
+
53
+ def fetch_authentication_with_password(auth_id)
54
+ on_internal_api do
55
+ local_var_path = "/authentications/#{auth_id}"
56
+
57
+ query_params = "expose_encrypted_attribute[]=password"
58
+
59
+ header_params = {'Accept' => select_header_accept(['application/json'])}
60
+ return_type = 'Authentication'
61
+ data, _, _ = call_api(:GET, local_var_path,
62
+ :header_params => header_params,
63
+ :query_params => query_params,
64
+ :auth_names => ['UserSecurity'],
65
+ :return_type => return_type)
66
+ data
67
+ end
68
+ end
69
+
70
+ def build_request_url(path)
71
+ # Add leading and trailing slashes to path
72
+ path = "/#{path}".gsub(/\/+/, '/')
73
+ URI.encode((custom_base_url || @config.base_url) + path)
74
+ end
75
+
76
+ def custom_base_url
77
+ return nil if custom_base_path.nil?
78
+
79
+ url = "#{@config.scheme}://#{[@config.host, custom_base_path].join('/').gsub(/\/+/, '/')}".sub(/\/+\z/, '')
80
+ URI.encode(url)
81
+ end
82
+
83
+ def on_internal_api
84
+ self.custom_base_path = INTERNAL_API_PATH
85
+ yield
86
+ ensure
87
+ self.custom_base_path = nil
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,43 @@
1
+ require "topological_inventory-api-client"
2
+
3
+ module TopologicalInventory
4
+ module Providers
5
+ module Common
6
+ class TopologyApiClient < ::TopologicalInventoryApiClient::ApiClient
7
+ attr_accessor :api
8
+
9
+ def initialize(identity = nil)
10
+ super(::TopologicalInventoryApiClient::Configuration.default)
11
+
12
+ self.identity = identity
13
+ self.api = init_default_api
14
+ end
15
+
16
+ def init_default_api
17
+ default_headers.merge!(identity) if identity.present?
18
+ ::TopologicalInventoryApiClient::DefaultApi.new(self)
19
+ end
20
+
21
+ def update_task(task_id, source_id: nil, state:, status:, target_type: nil, target_source_ref: nil, context: nil)
22
+ params = {'state' => state,
23
+ 'status' => status}
24
+ params['context'] = context if context
25
+ params['source_id'] = source_id if source_id
26
+ params['target_type'] = target_type if target_type
27
+ params['target_source_ref'] = target_source_ref if target_source_ref
28
+ task = TopologicalInventoryApiClient::Task.new(params)
29
+ api.update_task(task_id, task)
30
+ end
31
+
32
+ def svc_instance_url(service_instance)
33
+ rest_api_path = '/service_instances/{id}'.sub('{' + 'id' + '}', service_instance&.id.to_s)
34
+ build_request(:GET, rest_api_path).url
35
+ end
36
+
37
+ private
38
+
39
+ attr_accessor :identity
40
+ end
41
+ end
42
+ end
43
+ end
@@ -1,7 +1,7 @@
1
1
  module TopologicalInventory
2
2
  module Providers
3
3
  module Common
4
- VERSION = "1.0.11"
4
+ VERSION = "2.1.2".freeze
5
5
  end
6
6
  end
7
7
  end
@@ -7,8 +7,12 @@ RSpec.shared_examples "availability_check" do
7
7
  let(:sources_api_url) { "#{host_url}#{sources_api_path}" }
8
8
 
9
9
  let(:external_tenant) { '11001' }
10
+ let(:kafka_client) { TopologicalInventory::Providers::Common::MessagingClient.default.client }
10
11
  let(:identity) { {'x-rh-identity' => Base64.strict_encode64({'identity' => {'account_number' => external_tenant, 'user' => {'is_org_admin' => true}}}.to_json)} }
11
12
  let(:headers) { {'Content-Type' => 'application/json'}.merge(identity) }
13
+ let(:status_available) { described_class::STATUS_AVAILABLE }
14
+ let(:status_unavailable) { described_class::STATUS_UNAVAILABLE }
15
+ let(:error_message) { 'error_message' }
12
16
  let(:source_id) { '123' }
13
17
  let(:endpoint_id) { '234' }
14
18
  let(:application_id) { '345' }
@@ -32,101 +36,208 @@ RSpec.shared_examples "availability_check" do
32
36
 
33
37
  subject { described_class.new(payload["params"]) }
34
38
 
39
+ def kafka_message(resource_type, resource_id, status, error_message = nil)
40
+ res = {
41
+ :service => described_class::SERVICE_NAME,
42
+ :message => described_class::EVENT_AVAILABILITY_STATUS,
43
+ :payload => {
44
+ :resource_type => resource_type,
45
+ :resource_id => resource_id,
46
+ :status => status
47
+ }
48
+ }
49
+ res[:payload][:error] = error_message if error_message
50
+ res[:payload] = res[:payload].to_json
51
+ res
52
+ end
53
+
54
+ before do
55
+ allow(subject).to receive(:messaging_client).and_return(kafka_client)
56
+ end
57
+
35
58
  context "when not checked recently" do
36
59
  before do
37
60
  allow(subject).to receive(:checked_recently?).and_return(false)
38
61
  end
39
62
 
40
- it "updates Source and Endpoint when available" do
41
- # GET
42
- stub_get(:endpoint, list_endpoints_response)
43
- stub_get(:authentication, list_endpoint_authentications_response)
44
- stub_get(:password, internal_api_authentication_response)
45
- stub_not_found(:application)
63
+ context 'kafka' do
64
+ it 'updates Source and Endpoint when available' do
65
+ stub_get(:endpoint, list_endpoints_response)
66
+ stub_get(:application, list_applications_response)
46
67
 
47
- # PATCH
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
49
- endpoint_patch_body = {'availability_status' => described_class::STATUS_AVAILABLE, 'availability_status_error' => '', 'last_available_at' => subject.send(:check_time), 'last_checked_at' => subject.send(:check_time)}.to_json
68
+ expect(subject).to receive(:connection_status).and_return([status_available, ''])
50
69
 
51
- stub_patch(:source, source_patch_body)
52
- stub_patch(:endpoint, endpoint_patch_body)
70
+ expect(kafka_client).to receive(:publish_message).with(
71
+ kafka_message("Source", source_id, status_available)
72
+ )
53
73
 
54
- # Check ---
55
- expect(subject).to receive(:connection_check).and_return([described_class::STATUS_AVAILABLE, nil])
74
+ expect(kafka_client).to receive(:publish_message).with(
75
+ kafka_message("Endpoint", endpoint_id, status_available, '')
76
+ )
56
77
 
57
- subject.availability_check
78
+ expect(kafka_client).to receive(:publish_message).with(
79
+ kafka_message("Application", application_id, status_available)
80
+ )
58
81
 
59
- assert_patch(:source, source_patch_body)
60
- assert_patch(:endpoint, endpoint_patch_body)
61
- end
82
+ subject.availability_check
83
+ end
62
84
 
63
- it "updates Source and Endpoint when unavailable" do
64
- # GET
65
- stub_get(:endpoint, list_endpoints_response)
66
- stub_get(:authentication, list_endpoint_authentications_response)
67
- stub_get(:password, internal_api_authentication_response)
68
- stub_not_found(:application)
69
85
 
70
- # PATCH
71
- connection_error_message = "Some connection error"
72
- source_patch_body = {'availability_status' => described_class::STATUS_UNAVAILABLE, 'last_checked_at' => subject.send(:check_time)}.to_json
73
- endpoint_patch_body = {'availability_status' => described_class::STATUS_UNAVAILABLE, 'availability_status_error' => connection_error_message, 'last_checked_at' => subject.send(:check_time)}.to_json
86
+ it "updates Source and Endpoint when unavailable" do
87
+ stub_get(:endpoint, list_endpoints_response)
88
+ stub_get(:application, list_applications_response)
74
89
 
75
- stub_patch(:source, source_patch_body)
76
- stub_patch(:endpoint, endpoint_patch_body)
90
+ expect(subject).to receive(:connection_status).and_return([status_unavailable, error_message])
77
91
 
78
- # Check ---
79
- expect(subject).to receive(:connection_check).and_return([described_class::STATUS_UNAVAILABLE, connection_error_message])
92
+ expect(kafka_client).to receive(:publish_message).with(
93
+ kafka_message("Source", source_id, status_unavailable)
94
+ )
80
95
 
81
- subject.availability_check
96
+ expect(kafka_client).to receive(:publish_message).with(
97
+ kafka_message("Endpoint", endpoint_id, status_unavailable, error_message)
98
+ )
82
99
 
83
- assert_patch(:source, source_patch_body)
84
- assert_patch(:endpoint, endpoint_patch_body)
85
- end
100
+ expect(kafka_client).to receive(:publish_message).with(
101
+ kafka_message("Application", application_id, status_unavailable)
102
+ )
86
103
 
87
- it "updates only Source to 'unavailable' status if Endpoint not found" do
88
- # GET
89
- stub_not_found(:endpoint)
90
- stub_not_found(:application)
104
+ subject.availability_check
105
+ end
91
106
 
92
- # PATCH
93
- source_patch_body = {'availability_status' => described_class::STATUS_UNAVAILABLE, 'last_checked_at' => subject.send(:check_time)}.to_json
94
- stub_patch(:source, source_patch_body)
107
+ it "updates only Source to 'unavailable' status if Endpoint not found" do
108
+ stub_not_found(:endpoint)
109
+ stub_not_found(:application)
95
110
 
96
- # Check
97
- api_client = subject.send(:api_client)
98
- expect(api_client).not_to receive(:update_endpoint)
111
+ expect(subject).to receive(:connection_status).and_return([status_unavailable, error_message])
99
112
 
100
- subject.availability_check
113
+ expect(kafka_client).to receive(:publish_message).with(
114
+ kafka_message("Source", source_id, status_unavailable)
115
+ )
116
+
117
+ expect(subject.logger).to receive(:availability_check).with("Updating source [#{source_id}] status [#{status_unavailable}] message [#{error_message}]")
118
+ expect(subject.logger).to receive(:availability_check).with("Completed: Source #{source_id} is #{status_unavailable}")
119
+
120
+ subject.availability_check
121
+ end
122
+
123
+ it "updates Source and Endpoint to 'unavailable' if Authentication not found" do
124
+ stub_get(:endpoint, list_endpoints_response)
125
+ stub_not_found(:application)
126
+
127
+ expect(subject).to receive(:connection_status).and_return([status_unavailable, error_message])
128
+
129
+ expect(kafka_client).to receive(:publish_message).with(
130
+ kafka_message("Source", source_id, status_unavailable)
131
+ )
132
+
133
+ expect(kafka_client).to receive(:publish_message).with(
134
+ kafka_message("Endpoint", endpoint_id, status_unavailable, error_message)
135
+ )
101
136
 
102
- assert_patch(:source, source_patch_body)
137
+ expect(subject.logger).to receive(:availability_check).with("Updating source [#{source_id}] status [#{status_unavailable}] message [#{error_message}]")
138
+ expect(subject.logger).to receive(:availability_check).with("Completed: Source #{source_id} is #{status_unavailable}")
139
+
140
+ subject.availability_check
141
+ end
103
142
  end
104
143
 
105
- it "updates Source and Endpoint to 'unavailable' if Authentication not found" do
106
- # GET
107
- stub_get(:endpoint, list_endpoints_response)
108
- stub_get(:authentication, list_endpoint_authentications_response_empty)
109
- stub_not_found(:application)
144
+ context 'sources_api' do
145
+ before do
146
+ subject.send(:updates_via_kafka=, false)
147
+ end
110
148
 
111
- # PATCH
112
- source_patch_body = {'availability_status' => described_class::STATUS_UNAVAILABLE, 'last_checked_at' => subject.send(:check_time)}.to_json
113
- endpoint_patch_body = {'availability_status' => described_class::STATUS_UNAVAILABLE, 'availability_status_error' => described_class::ERROR_MESSAGES[:authentication_not_found], 'last_checked_at' => subject.send(:check_time)}.to_json
149
+ it "updates Source and Endpoint when available" do
150
+ # GET
151
+ stub_get(:endpoint, list_endpoints_response)
152
+ stub_get(:authentication, list_endpoint_authentications_response)
153
+ stub_get(:password, internal_api_authentication_response)
154
+ stub_not_found(:application)
114
155
 
115
- stub_patch(:source, source_patch_body)
116
- stub_patch(:endpoint, endpoint_patch_body)
156
+ # PATCH
157
+ 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
158
+ endpoint_patch_body = {'availability_status' => described_class::STATUS_AVAILABLE, 'availability_status_error' => '', 'last_available_at' => subject.send(:check_time), 'last_checked_at' => subject.send(:check_time)}.to_json
117
159
 
118
- # Check
119
- expect(subject).not_to receive(:connection_check)
120
- subject.availability_check
160
+ stub_patch(:source, source_patch_body)
161
+ stub_patch(:endpoint, endpoint_patch_body)
162
+
163
+ # Check ---
164
+ expect(subject).to receive(:connection_check).and_return([described_class::STATUS_AVAILABLE, nil])
165
+
166
+ subject.availability_check
167
+
168
+ assert_patch(:source, source_patch_body)
169
+ assert_patch(:endpoint, endpoint_patch_body)
170
+ end
171
+
172
+ it "updates Source and Endpoint when unavailable" do
173
+ # GET
174
+ stub_get(:endpoint, list_endpoints_response)
175
+ stub_get(:authentication, list_endpoint_authentications_response)
176
+ stub_get(:password, internal_api_authentication_response)
177
+ stub_not_found(:application)
178
+
179
+ # PATCH
180
+ connection_error_message = "Some connection error"
181
+ source_patch_body = {'availability_status' => described_class::STATUS_UNAVAILABLE, 'last_checked_at' => subject.send(:check_time)}.to_json
182
+ endpoint_patch_body = {'availability_status' => described_class::STATUS_UNAVAILABLE, 'availability_status_error' => connection_error_message, 'last_checked_at' => subject.send(:check_time)}.to_json
183
+
184
+ stub_patch(:source, source_patch_body)
185
+ stub_patch(:endpoint, endpoint_patch_body)
186
+
187
+ # Check ---
188
+ expect(subject).to receive(:connection_check).and_return([described_class::STATUS_UNAVAILABLE, connection_error_message])
189
+
190
+ subject.availability_check
191
+
192
+ assert_patch(:source, source_patch_body)
193
+ assert_patch(:endpoint, endpoint_patch_body)
194
+ end
195
+
196
+ it "updates only Source to 'unavailable' status if Endpoint not found" do
197
+ # GET
198
+ stub_not_found(:endpoint)
199
+ stub_not_found(:application)
200
+
201
+ # PATCH
202
+ source_patch_body = {'availability_status' => described_class::STATUS_UNAVAILABLE, 'last_checked_at' => subject.send(:check_time)}.to_json
203
+ stub_patch(:source, source_patch_body)
204
+
205
+ # Check
206
+ api_client = subject.send(:sources_api)
207
+ expect(api_client).not_to receive(:update_endpoint)
208
+
209
+ subject.availability_check
210
+
211
+ assert_patch(:source, source_patch_body)
212
+ end
213
+
214
+ it "updates Source and Endpoint to 'unavailable' if Authentication not found" do
215
+ # GET
216
+ stub_get(:endpoint, list_endpoints_response)
217
+ stub_get(:authentication, list_endpoint_authentications_response_empty)
218
+ stub_not_found(:application)
121
219
 
122
- assert_patch(:source, source_patch_body)
123
- assert_patch(:endpoint, endpoint_patch_body)
220
+ # PATCH
221
+ source_patch_body = {'availability_status' => described_class::STATUS_UNAVAILABLE, 'last_checked_at' => subject.send(:check_time)}.to_json
222
+ endpoint_patch_body = {'availability_status' => described_class::STATUS_UNAVAILABLE, 'availability_status_error' => described_class::ERROR_MESSAGES[:authentication_not_found], 'last_checked_at' => subject.send(:check_time)}.to_json
223
+
224
+ stub_patch(:source, source_patch_body)
225
+ stub_patch(:endpoint, endpoint_patch_body)
226
+
227
+ # Check
228
+ expect(subject).not_to receive(:connection_check)
229
+ subject.availability_check
230
+
231
+ assert_patch(:source, source_patch_body)
232
+ assert_patch(:endpoint, endpoint_patch_body)
233
+ end
124
234
  end
125
235
  end
126
236
 
127
237
  context "when checked recently" do
128
238
  before do
129
239
  allow(subject).to receive(:checked_recently?).and_return(true)
240
+ subject.send(:updates_via_kafka=, false)
130
241
  end
131
242
 
132
243
  it "doesn't do connection check" do
@@ -140,44 +251,97 @@ RSpec.shared_examples "availability_check" do
140
251
 
141
252
  context "when there is an application" do
142
253
  context "when it is available" do
143
- it "updates the availability status to available" do
144
- # GET
145
- stub_not_found(:endpoint)
146
- stub_get(:application, list_applications_response)
147
- # PATCH
148
- application_patch_body = {'last_available_at' => subject.send(:check_time), 'last_checked_at' => subject.send(:check_time)}.to_json
149
- 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
254
+ context 'kafka' do
255
+ it "updates the availability status to available" do
256
+ stub_not_found(:endpoint)
257
+ stub_get(:application, list_applications_response)
150
258
 
151
- stub_patch(:source, source_patch_body)
152
- stub_patch(:application, application_patch_body)
259
+ expect(subject).to receive(:connection_status).and_return([status_available, ''])
153
260
 
154
- # Check
155
- expect(subject).not_to receive(:connection_check)
156
- subject.availability_check
261
+ expect(kafka_client).to receive(:publish_message).with(
262
+ kafka_message("Source", source_id, status_available)
263
+ )
157
264
 
158
- assert_patch(:source, source_patch_body)
159
- assert_patch(:application, application_patch_body)
265
+ expect(kafka_client).to receive(:publish_message).with(
266
+ kafka_message("Application", application_id, status_available)
267
+ )
268
+
269
+ expect(subject.logger).to receive(:availability_check).with("Updating source [#{source_id}] status [#{status_available}] message []")
270
+ expect(subject.logger).to receive(:availability_check).with("Completed: Source #{source_id} is #{status_available}")
271
+
272
+ subject.availability_check
273
+ end
274
+ end
275
+
276
+ context 'sources_api' do
277
+ before do
278
+ subject.send(:updates_via_kafka=, false)
279
+ end
280
+
281
+ it "updates the availability status to available" do
282
+ # GET
283
+ stub_not_found(:endpoint)
284
+ stub_get(:application, list_applications_response)
285
+ # PATCH
286
+ application_patch_body = {'last_available_at' => subject.send(:check_time), 'last_checked_at' => subject.send(:check_time)}.to_json
287
+ 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
288
+
289
+ stub_patch(:source, source_patch_body)
290
+ stub_patch(:application, application_patch_body)
291
+
292
+ # Check
293
+ expect(subject).not_to receive(:connection_check)
294
+ subject.availability_check
295
+
296
+ assert_patch(:source, source_patch_body)
297
+ assert_patch(:application, application_patch_body)
298
+ end
160
299
  end
161
300
  end
162
301
 
163
302
  context "when it is unavailable" do
164
- it "updates the availability status to unavailable" do
165
- # GET
166
- stub_not_found(:endpoint)
167
- stub_get(:application, list_applications_unavailable_response)
168
- # PATCH
169
- application_patch_body = {'last_checked_at' => subject.send(:check_time)}.to_json
170
- source_patch_body = {'availability_status' => described_class::STATUS_UNAVAILABLE, 'last_checked_at' => subject.send(:check_time)}.to_json
303
+ context 'kafka' do
304
+ it "updates the availability status to unavailable" do
305
+ stub_not_found(:endpoint)
306
+ stub_get(:application, list_applications_unavailable_response)
171
307
 
172
- stub_patch(:source, source_patch_body)
173
- stub_patch(:application, application_patch_body)
308
+ expect(subject).to receive(:connection_status).and_return([status_unavailable, error_message])
174
309
 
175
- # Check
176
- expect(subject).not_to receive(:connection_check)
177
- subject.availability_check
310
+ expect(kafka_client).to receive(:publish_message).with(
311
+ kafka_message("Source", source_id, status_unavailable)
312
+ )
178
313
 
179
- assert_patch(:source, source_patch_body)
180
- assert_patch(:application, application_patch_body)
314
+ expect(kafka_client).to receive(:publish_message).with(
315
+ kafka_message("Application", application_id, status_unavailable)
316
+ )
317
+
318
+ subject.availability_check
319
+ end
320
+ end
321
+
322
+ context 'sources_api' do
323
+ before do
324
+ subject.send(:updates_via_kafka=, false)
325
+ end
326
+
327
+ it "updates the availability status to unavailable" do
328
+ # GET
329
+ stub_not_found(:endpoint)
330
+ stub_get(:application, list_applications_unavailable_response)
331
+ # PATCH
332
+ application_patch_body = {'last_checked_at' => subject.send(:check_time)}.to_json
333
+ source_patch_body = {'availability_status' => described_class::STATUS_UNAVAILABLE, 'last_checked_at' => subject.send(:check_time)}.to_json
334
+
335
+ stub_patch(:source, source_patch_body)
336
+ stub_patch(:application, application_patch_body)
337
+
338
+ # Check
339
+ expect(subject).not_to receive(:connection_check)
340
+ subject.availability_check
341
+
342
+ assert_patch(:source, source_patch_body)
343
+ assert_patch(:application, application_patch_body)
344
+ end
181
345
  end
182
346
  end
183
347
  end