rsmp 0.1.21 → 0.1.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitmodules +0 -4
- data/Gemfile.lock +13 -11
- data/config/supervisor.yaml +9 -15
- data/config/tlc.yaml +9 -8
- data/documentation/message_distribution.md +8 -8
- data/lib/rsmp.rb +5 -0
- data/lib/rsmp/archive.rb +7 -4
- data/lib/rsmp/cli.rb +133 -102
- data/lib/rsmp/collector.rb +42 -30
- data/lib/rsmp/component.rb +2 -0
- data/lib/rsmp/components.rb +1 -1
- data/lib/rsmp/convert/export/json_schema.rb +204 -0
- data/lib/rsmp/convert/import/yaml.rb +38 -0
- data/lib/rsmp/deep_merge.rb +11 -0
- data/lib/rsmp/inspect.rb +46 -0
- data/lib/rsmp/listener.rb +4 -14
- data/lib/rsmp/logger.rb +3 -1
- data/lib/rsmp/logging.rb +1 -1
- data/lib/rsmp/message.rb +22 -31
- data/lib/rsmp/node.rb +11 -1
- data/lib/rsmp/notifier.rb +7 -2
- data/lib/rsmp/proxy.rb +95 -39
- data/lib/rsmp/rsmp.rb +34 -23
- data/lib/rsmp/site.rb +30 -32
- data/lib/rsmp/site_proxy.rb +103 -22
- data/lib/rsmp/site_proxy_wait.rb +63 -38
- data/lib/rsmp/supervisor.rb +82 -47
- data/lib/rsmp/supervisor_proxy.rb +21 -13
- data/lib/rsmp/tlc.rb +61 -35
- data/lib/rsmp/version.rb +1 -1
- data/rsmp.gemspec +3 -14
- metadata +13 -113
- data/config/site.yaml +0 -40
data/lib/rsmp/rsmp.rb
CHANGED
@@ -1,31 +1,42 @@
|
|
1
|
-
#
|
1
|
+
# Get the current time in UTC, with optional adjustment
|
2
|
+
# Convertion to string uses the RSMP format 2015-06-08T12:01:39.654Z
|
3
|
+
# Note that using to_s on a my_clock.to_s will not produce an RSMP formatted timestamp,
|
4
|
+
# you need to use Clock.to_s my_clock
|
5
|
+
|
6
|
+
require 'time'
|
2
7
|
|
3
8
|
module RSMP
|
4
|
-
WRAPPING_DELIMITER = "\f"
|
5
9
|
|
6
|
-
|
7
|
-
|
8
|
-
Time.now.utc
|
9
|
-
end
|
10
|
+
class Clock
|
11
|
+
attr_reader :adjustment
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
time ||= now.utc
|
15
|
-
time.strftime("%FT%T.%3NZ")
|
16
|
-
end
|
13
|
+
def initialize
|
14
|
+
@adjustment = 0
|
15
|
+
end
|
17
16
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
end
|
17
|
+
def set target
|
18
|
+
@adjustment = target - Time.now
|
19
|
+
end
|
22
20
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
def self.log_prefix ip
|
28
|
-
"#{now_string} #{ip.ljust(20)}"
|
29
|
-
end
|
21
|
+
def reset
|
22
|
+
@adjustment = 0
|
23
|
+
end
|
30
24
|
|
25
|
+
def now
|
26
|
+
Time.now.utc + @adjustment
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_s
|
30
|
+
Clock.to_s now
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.now
|
34
|
+
Time.now.utc
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.to_s time=nil
|
38
|
+
(time || now).strftime("%FT%T.%3NZ")
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
31
42
|
end
|
data/lib/rsmp/site.rb
CHANGED
@@ -20,43 +20,41 @@ module RSMP
|
|
20
20
|
@site_settings['site_id']
|
21
21
|
end
|
22
22
|
|
23
|
-
def handle_site_settings options
|
24
|
-
|
23
|
+
def handle_site_settings options={}
|
24
|
+
defaults = {
|
25
25
|
'site_id' => 'RN+SI0001',
|
26
26
|
'supervisors' => [
|
27
27
|
{ 'ip' => '127.0.0.1', 'port' => 12111 }
|
28
28
|
],
|
29
|
-
'rsmp_versions' =>
|
30
|
-
'sxl' => '
|
31
|
-
'sxl_version' => '1.0.
|
32
|
-
'
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
'
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
'reconnect_interval' => 0.1,
|
29
|
+
'rsmp_versions' => 'all',
|
30
|
+
'sxl' => 'tlc',
|
31
|
+
'sxl_version' => '1.0.15',
|
32
|
+
'intervals' => {
|
33
|
+
'timer' => 0.1,
|
34
|
+
'watchdog' => 1,
|
35
|
+
'reconnect' => 0.1
|
36
|
+
},
|
37
|
+
'timeouts' => {
|
38
|
+
'watchdog' => 2,
|
39
|
+
'acknowledgement' => 2
|
40
|
+
},
|
42
41
|
'send_after_connect' => true,
|
43
42
|
'components' => {
|
44
43
|
'C1' => {}
|
45
44
|
}
|
46
45
|
}
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
@site_settings.merge! converted
|
51
|
-
end
|
52
|
-
|
53
|
-
required = [:supervisors,:rsmp_versions,:site_id,:watchdog_interval,:watchdog_timeout,
|
54
|
-
:acknowledgement_timeout,:command_response_timeout]
|
55
|
-
check_required_settings @site_settings, required
|
56
|
-
|
46
|
+
|
47
|
+
@site_settings = defaults.deep_merge options[:site_settings]
|
48
|
+
check_sxl_version
|
57
49
|
setup_components @site_settings['components']
|
58
50
|
end
|
59
51
|
|
52
|
+
def check_sxl_version
|
53
|
+
sxl = @site_settings['sxl']
|
54
|
+
version = @site_settings['sxl_version']
|
55
|
+
RSMP::Schemer::find_schema! sxl, version
|
56
|
+
end
|
57
|
+
|
60
58
|
def reconnect
|
61
59
|
@sleep_condition.signal
|
62
60
|
end
|
@@ -64,8 +62,10 @@ module RSMP
|
|
64
62
|
def start_action
|
65
63
|
@site_settings["supervisors"].each do |supervisor_settings|
|
66
64
|
@task.async do |task|
|
67
|
-
task.annotate "
|
65
|
+
task.annotate "site proxy"
|
68
66
|
connect_to_supervisor task, supervisor_settings
|
67
|
+
rescue StandardError => e
|
68
|
+
notify_error e, level: :internal
|
69
69
|
end
|
70
70
|
end
|
71
71
|
end
|
@@ -101,16 +101,14 @@ module RSMP
|
|
101
101
|
proxy.run # run until disconnected
|
102
102
|
rescue IOError => e
|
103
103
|
log "Stream error: #{e}", level: :warning
|
104
|
-
rescue SystemCallError => e # all ERRNO errors
|
105
|
-
log "Reader exception: #{e.to_s}", level: :error
|
106
104
|
rescue StandardError => e
|
107
|
-
|
105
|
+
notify_error e, level: :internal
|
108
106
|
ensure
|
109
107
|
begin
|
110
|
-
if @site_settings[
|
108
|
+
if @site_settings['intervals']['watchdog'] != :no
|
111
109
|
# sleep until waken by reconnect() or the reconnect interval passed
|
112
110
|
proxy.set_state :wait_for_reconnect
|
113
|
-
task.with_timeout(@site_settings[
|
111
|
+
task.with_timeout(@site_settings['intervals']['watchdog']) do
|
114
112
|
@sleep_condition.wait
|
115
113
|
end
|
116
114
|
else
|
@@ -135,7 +133,7 @@ module RSMP
|
|
135
133
|
def starting
|
136
134
|
log "Starting site #{@site_settings["site_id"]}",
|
137
135
|
level: :info,
|
138
|
-
timestamp:
|
136
|
+
timestamp: @clock.now
|
139
137
|
end
|
140
138
|
|
141
139
|
def alarm
|
data/lib/rsmp/site_proxy.rb
CHANGED
@@ -15,6 +15,11 @@ module RSMP
|
|
15
15
|
@site_id = nil
|
16
16
|
end
|
17
17
|
|
18
|
+
def inspect
|
19
|
+
"#<#{self.class.name}:#{self.object_id}, #{inspector(
|
20
|
+
:@acknowledgements,:@settings,:@site_settings,:@components
|
21
|
+
)}>"
|
22
|
+
end
|
18
23
|
def node
|
19
24
|
supervisor
|
20
25
|
end
|
@@ -31,7 +36,7 @@ module RSMP
|
|
31
36
|
|
32
37
|
def connection_complete
|
33
38
|
super
|
34
|
-
log "Connection to site #{@site_id} established", level: :info
|
39
|
+
log "Connection to site #{@site_id} established, using core #{@rsmp_version}, #{@sxl} #{@site_sxl_version}", level: :info
|
35
40
|
end
|
36
41
|
|
37
42
|
def process_message message
|
@@ -43,6 +48,8 @@ module RSMP
|
|
43
48
|
will_not_handle message
|
44
49
|
when AggregatedStatus
|
45
50
|
process_aggregated_status message
|
51
|
+
when AggregatedStatusRequest
|
52
|
+
will_not_handle message
|
46
53
|
when Alarm
|
47
54
|
process_alarm message
|
48
55
|
when CommandResponse
|
@@ -66,18 +73,34 @@ module RSMP
|
|
66
73
|
end
|
67
74
|
|
68
75
|
def version_accepted message
|
69
|
-
log "Received Version message for site #{@site_id}
|
76
|
+
log "Received Version message for site #{@site_id}", message: message, level: :log
|
70
77
|
start_timer
|
71
78
|
acknowledge message
|
72
|
-
send_version @site_id,
|
79
|
+
send_version @site_id, rsmp_versions
|
73
80
|
@version_determined = true
|
74
81
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
82
|
+
end
|
83
|
+
|
84
|
+
def request_aggregated_status component, options={}
|
85
|
+
raise NotReady unless ready?
|
86
|
+
m_id = options[:m_id] || RSMP::Message.make_m_id
|
87
|
+
|
88
|
+
message = RSMP::AggregatedStatusRequest.new({
|
89
|
+
"ntsOId" => '',
|
90
|
+
"xNId" => '',
|
91
|
+
"cId" => component,
|
92
|
+
"mId" => m_id
|
93
|
+
})
|
94
|
+
if options[:collect]
|
95
|
+
result = nil
|
96
|
+
task = @task.async do |task|
|
97
|
+
wait_for_aggregated_status task, options[:collect]
|
80
98
|
end
|
99
|
+
send_message message, validate: options[:validate]
|
100
|
+
return message, task.wait
|
101
|
+
else
|
102
|
+
send_message message, validate: options[:validate]
|
103
|
+
message
|
81
104
|
end
|
82
105
|
end
|
83
106
|
|
@@ -159,10 +182,16 @@ module RSMP
|
|
159
182
|
collect_options = options[:collect].merge status_list: status_list
|
160
183
|
collect_status_responses task, collect_options, m_id
|
161
184
|
end
|
162
|
-
send_message message
|
163
|
-
|
185
|
+
send_message message, validate: options[:validate]
|
186
|
+
|
187
|
+
# task.wait return the result of the task. if the task raised an exception
|
188
|
+
# it will be reraised. but that mechanish does not work if multiple values
|
189
|
+
# are returned. so manually raise if first element is an exception
|
190
|
+
result = task.wait
|
191
|
+
raise result.first if result.first.is_a? Exception
|
192
|
+
return message, *result
|
164
193
|
else
|
165
|
-
send_message message
|
194
|
+
send_message message, validate: options[:validate]
|
166
195
|
message
|
167
196
|
end
|
168
197
|
end
|
@@ -193,15 +222,21 @@ module RSMP
|
|
193
222
|
collect_options = options[:collect].merge status_list: status_list
|
194
223
|
collect_status_updates task, collect_options, m_id
|
195
224
|
end
|
196
|
-
send_message message
|
197
|
-
|
225
|
+
send_message message, validate: options[:validate]
|
226
|
+
|
227
|
+
# task.wait return the result of the task. if the task raised an exception
|
228
|
+
# it will be reraised. but that mechanish does not work if multiple values
|
229
|
+
# are returned. so manually raise if first element is an exception
|
230
|
+
result = task.wait
|
231
|
+
raise result.first if result.first.is_a? Exception
|
232
|
+
return message, *result
|
198
233
|
else
|
199
|
-
send_message message
|
234
|
+
send_message message, validate: options[:validate]
|
200
235
|
message
|
201
236
|
end
|
202
237
|
end
|
203
238
|
|
204
|
-
def unsubscribe_to_status component, status_list
|
239
|
+
def unsubscribe_to_status component, status_list, options={}
|
205
240
|
raise NotReady unless ready?
|
206
241
|
message = RSMP::StatusUnsubscribe.new({
|
207
242
|
"ntsOId" => '',
|
@@ -209,7 +244,7 @@ module RSMP
|
|
209
244
|
"cId" => component,
|
210
245
|
"sS" => status_list
|
211
246
|
})
|
212
|
-
send_message message
|
247
|
+
send_message message, validate: options[:validate]
|
213
248
|
message
|
214
249
|
end
|
215
250
|
|
@@ -218,7 +253,7 @@ module RSMP
|
|
218
253
|
acknowledge message
|
219
254
|
end
|
220
255
|
|
221
|
-
def send_alarm_acknowledgement component, alarm_code
|
256
|
+
def send_alarm_acknowledgement component, alarm_code, options={}
|
222
257
|
message = RSMP::AlarmAcknowledged.new({
|
223
258
|
"ntsOId" => '',
|
224
259
|
"xNId" => '',
|
@@ -228,7 +263,7 @@ module RSMP
|
|
228
263
|
"xNACId" => '',
|
229
264
|
"aSp" => 'Acknowledge'
|
230
265
|
})
|
231
|
-
send_message message
|
266
|
+
send_message message, validate: options[:validate]
|
232
267
|
message
|
233
268
|
end
|
234
269
|
|
@@ -248,19 +283,33 @@ module RSMP
|
|
248
283
|
collect_options = options[:collect].merge command_list: command_list
|
249
284
|
collect_command_responses task, collect_options, m_id
|
250
285
|
end
|
251
|
-
send_message message
|
252
|
-
|
286
|
+
send_message message, validate: options[:validate]
|
287
|
+
|
288
|
+
# task.wait return the result of the task. if the task raised an exception
|
289
|
+
# it will be reraised. but that mechanish does not work if multiple values
|
290
|
+
# are returned. so manually raise if first element is an exception
|
291
|
+
result = task.wait
|
292
|
+
raise result.first if result.first.is_a? Exception
|
293
|
+
return message, *result
|
253
294
|
else
|
254
|
-
send_message message
|
295
|
+
send_message message, validate: options[:validate]
|
255
296
|
message
|
256
297
|
end
|
257
298
|
end
|
258
299
|
|
259
300
|
def set_watchdog_interval interval
|
260
|
-
@settings[
|
301
|
+
@settings['intervals']['watchdog'] = interval
|
261
302
|
end
|
262
303
|
|
263
304
|
def check_sxl_version message
|
305
|
+
|
306
|
+
# check that we have a schema for specified sxl type and version
|
307
|
+
# note that the type comes from the site config, while the version
|
308
|
+
# comes from the Version message send by the site
|
309
|
+
type = 'tlc'
|
310
|
+
version = message.attribute 'SXL'
|
311
|
+
RSMP::Schemer::find_schema! type, version
|
312
|
+
|
264
313
|
# store sxl version requested by site
|
265
314
|
# TODO should check agaist site settings
|
266
315
|
@site_sxl_version = message.attribute 'SXL'
|
@@ -278,6 +327,8 @@ module RSMP
|
|
278
327
|
check_rsmp_version message
|
279
328
|
check_sxl_version message
|
280
329
|
version_accepted message
|
330
|
+
rescue RSMP::Schemer::UnknownSchemaError => e
|
331
|
+
dont_acknowledge message, "Rejected #{message.type} message,", "#{e}"
|
281
332
|
end
|
282
333
|
|
283
334
|
def check_site_ids message
|
@@ -285,8 +336,38 @@ module RSMP
|
|
285
336
|
site_id = message.attribute("siteId").map { |item| item["sId"] }.first
|
286
337
|
@supervisor.check_site_id site_id
|
287
338
|
@site_id = site_id
|
339
|
+
setup_site_settings
|
288
340
|
site_ids_changed
|
289
341
|
end
|
290
342
|
|
343
|
+
def find_site_settings site_id
|
344
|
+
if @settings['sites'] && @settings['sites'][@site_id]
|
345
|
+
log "Using site settings for site id #{@site_id}", level: :debug
|
346
|
+
return @settings['sites'][@site_id]
|
347
|
+
end
|
348
|
+
|
349
|
+
settings = @settings['guest']
|
350
|
+
if @settings['guest']
|
351
|
+
log "Using site settings for guest", level: :debug
|
352
|
+
return @settings['guest']
|
353
|
+
end
|
354
|
+
|
355
|
+
nil
|
356
|
+
end
|
357
|
+
|
358
|
+
def setup_site_settings
|
359
|
+
@site_settings = find_site_settings @site_id
|
360
|
+
if @site_settings
|
361
|
+
@sxl = @site_settings['sxl']
|
362
|
+
setup_components @site_settings['components']
|
363
|
+
else
|
364
|
+
dont_acknowledge message, 'Rejected', "No config found for site #{@site_id}"
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
def notify_error e, options={}
|
369
|
+
@supervisor.notify_error e, options if @supervisor
|
370
|
+
end
|
371
|
+
|
291
372
|
end
|
292
373
|
end
|
data/lib/rsmp/site_proxy_wait.rb
CHANGED
@@ -20,12 +20,12 @@ module RSMP
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
def wait_for_alarm options={}
|
23
|
+
def wait_for_alarm parent_task, options={}
|
24
24
|
matching_alarm = nil
|
25
|
-
|
25
|
+
message = collect(parent_task,options.merge(type: "Alarm", with_message: true, num: 1)) do |message|
|
26
26
|
# TODO check components
|
27
27
|
matching_alarm = nil
|
28
|
-
alarm =
|
28
|
+
alarm = message
|
29
29
|
next if options[:aCId] && options[:aCId] != alarm.attribute("aCId")
|
30
30
|
next if options[:aSp] && options[:aSp] != alarm.attribute("aSp")
|
31
31
|
next if options[:aS] && options[:aS] != alarm.attribute("aS")
|
@@ -33,7 +33,7 @@ module RSMP
|
|
33
33
|
break
|
34
34
|
end
|
35
35
|
if item
|
36
|
-
{ message:
|
36
|
+
{ message: message, status: matching_alarm }
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
@@ -49,11 +49,11 @@ module RSMP
|
|
49
49
|
task.annotate "wait for command response"
|
50
50
|
want = options[:command_list].clone
|
51
51
|
result = {}
|
52
|
-
|
52
|
+
messages = []
|
53
|
+
collect(parent_task,options.merge({
|
53
54
|
type: ['CommandResponse','MessageNotAck'],
|
54
55
|
num: 1
|
55
|
-
})) do |
|
56
|
-
message = item[:message]
|
56
|
+
})) do |message|
|
57
57
|
if message.is_a?(MessageNotAck)
|
58
58
|
if message.attribute('oMId') == m_id
|
59
59
|
# set result to an exception, but don't raise it.
|
@@ -68,39 +68,38 @@ module RSMP
|
|
68
68
|
false
|
69
69
|
end
|
70
70
|
else
|
71
|
-
|
71
|
+
add = false
|
72
72
|
# look through querues
|
73
73
|
want.each_with_index do |query,i|
|
74
74
|
# look through items in message
|
75
|
-
|
76
|
-
|
77
|
-
if
|
75
|
+
message.attributes['rvs'].each do |input|
|
76
|
+
matching = command_match? query, input
|
77
|
+
if matching == true
|
78
78
|
result[query] = input
|
79
|
-
|
79
|
+
add = true
|
80
|
+
elsif matching == false
|
81
|
+
result.delete query
|
80
82
|
end
|
81
83
|
end
|
82
84
|
end
|
83
|
-
|
84
|
-
|
85
|
-
want.delete_at i
|
86
|
-
end
|
87
|
-
want.empty? # any queries left to match?
|
85
|
+
messages << message if add
|
86
|
+
result.size == want.size # any queries left to match?
|
88
87
|
end
|
89
88
|
end
|
90
|
-
result
|
89
|
+
return result, messages
|
91
90
|
rescue Async::TimeoutError
|
92
|
-
raise RSMP::TimeoutError.new "Did not receive command response to #{m_id} within #{options[:timeout]}s"
|
91
|
+
raise RSMP::TimeoutError.new "Did not receive correct command response to #{m_id} within #{options[:timeout]}s"
|
93
92
|
end
|
94
93
|
|
95
94
|
def collect_status_updates_or_responses task, type, options, m_id
|
96
|
-
want = options[:status_list]
|
95
|
+
want = options[:status_list].clone
|
97
96
|
result = {}
|
97
|
+
messages = []
|
98
98
|
# wait for a status update
|
99
|
-
|
99
|
+
collect(task,options.merge({
|
100
100
|
type: [type,'MessageNotAck'],
|
101
101
|
num: 1
|
102
|
-
})) do |
|
103
|
-
message = item[:message]
|
102
|
+
})) do |message|
|
104
103
|
if message.is_a?(MessageNotAck)
|
105
104
|
if message.attribute('oMId') == m_id
|
106
105
|
# set result to an exception, but don't raise it.
|
@@ -115,33 +114,33 @@ module RSMP
|
|
115
114
|
false
|
116
115
|
else
|
117
116
|
found = []
|
117
|
+
add = false
|
118
118
|
# look through querues
|
119
119
|
want.each_with_index do |query,i|
|
120
120
|
# look through status items in message
|
121
|
-
|
122
|
-
|
123
|
-
if
|
121
|
+
message.attributes['sS'].each do |input|
|
122
|
+
matching = status_match? query, input
|
123
|
+
if matching == true
|
124
124
|
result[query] = input
|
125
|
-
|
125
|
+
add = true
|
126
|
+
elsif matching == false
|
127
|
+
result.delete query
|
126
128
|
end
|
127
129
|
end
|
128
130
|
end
|
129
|
-
|
130
|
-
|
131
|
-
want.delete_at i
|
132
|
-
end
|
133
|
-
want.empty? # any queries left to match?
|
131
|
+
messages << message if add
|
132
|
+
result.size == want.size # any queries left to match?
|
134
133
|
end
|
135
134
|
end
|
136
|
-
result
|
135
|
+
return result, messages
|
137
136
|
rescue Async::TimeoutError
|
138
137
|
type_str = {'StatusUpdate'=>'update', 'StatusResponse'=>'response'}[type]
|
139
|
-
raise RSMP::TimeoutError.new "Did not received status #{type_str} in reply to #{m_id} within #{options[:timeout]}s"
|
138
|
+
raise RSMP::TimeoutError.new "Did not received correct status #{type_str} in reply to #{m_id} within #{options[:timeout]}s"
|
140
139
|
end
|
141
140
|
|
142
141
|
def status_match? query, item
|
143
|
-
return
|
144
|
-
return
|
142
|
+
return nil if query['sCI'] && query['sCI'] != item['sCI']
|
143
|
+
return nil if query['n'] && query['n'] != item['n']
|
145
144
|
return false if query['q'] && query['q'] != item['q']
|
146
145
|
if query['s'].is_a? Regexp
|
147
146
|
return false if query['s'] && item['s'] !~ query['s']
|
@@ -152,8 +151,8 @@ module RSMP
|
|
152
151
|
end
|
153
152
|
|
154
153
|
def command_match? query, item
|
155
|
-
return
|
156
|
-
return
|
154
|
+
return nil if query['cCI'] && query['cCI'] != item['cCI']
|
155
|
+
return nil if query['n'] && query['n'] != item['n']
|
157
156
|
if query['v'].is_a? Regexp
|
158
157
|
return false if query['v'] && item['v'] !~ query['v']
|
159
158
|
else
|
@@ -168,6 +167,8 @@ module RSMP
|
|
168
167
|
# wait for command responses in an async task
|
169
168
|
task = parent_task.async do |task|
|
170
169
|
collect_block.call task, m_id
|
170
|
+
rescue StandardError => e
|
171
|
+
notify_error e, level: :internal
|
171
172
|
end
|
172
173
|
|
173
174
|
# call block, it should send command request using the given m_id
|
@@ -177,5 +178,29 @@ module RSMP
|
|
177
178
|
task.wait
|
178
179
|
end
|
179
180
|
|
181
|
+
def wait_for_aggregated_status parent_task, options={}
|
182
|
+
collect(parent_task,options.merge({
|
183
|
+
type: ['AggregatedStatus','MessageNotAck'],
|
184
|
+
num: 1
|
185
|
+
})) do |message|
|
186
|
+
if message.is_a?(MessageNotAck)
|
187
|
+
if message.attribute('oMId') == m_id
|
188
|
+
# set result to an exception, but don't raise it.
|
189
|
+
# this will be returned by the task and stored as the task result
|
190
|
+
# when the parent task call wait() on the task, the exception
|
191
|
+
# will be raised in the parent task, and caught by rspec.
|
192
|
+
# rspec will then show the error and record the test as failed
|
193
|
+
m_id_short = RSMP::Message.shorten_m_id m_id, 8
|
194
|
+
result = RSMP::MessageRejected.new "Aggregated status request #{m_id_short} was rejected: #{message.attribute('rea')}"
|
195
|
+
next true # done, no more messages wanted
|
196
|
+
else
|
197
|
+
false
|
198
|
+
end
|
199
|
+
else
|
200
|
+
true
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
180
205
|
end
|
181
206
|
end
|