rsmp 0.3.6 → 0.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '06464038166b8a2a0dbd21e7e53d28472117acfb704312755023792d2650943b'
4
- data.tar.gz: 149b50fb2e39d2287fd3fbd7fbc6f5520a9922d778315272250a361a6cf4d4be
3
+ metadata.gz: 05d67026eef7404afe7979c198bcfe97bd63e231400e174988ab14454f23ea09
4
+ data.tar.gz: e82717dc287f0eb2e91577cf5e02d752cdf1d1fef6bdac6f4cf3569494d8da3e
5
5
  SHA512:
6
- metadata.gz: 115228cc10a63d009bffd2a7f3f0408ad47e2dafd14883f8a25b38870ef99fe73292ddc61ac9e38a1d895d70f53c5a08928492c940d01641d87b19e466764dba
7
- data.tar.gz: 6df15fe4e9c6044cb5fab93da68202d4e0bdb32e109bc538fc4d55c232669cbbf745e7aeacee87fa75567658687683d84ee5255d98b9841f05090a918d6b6c49
6
+ metadata.gz: 0d971e86ebd1ef25ff52cc4babd23567b2b5e870cc70f7edfc18ce7925a850fd94dfa851e70c16a43d4df1ef174045999ad41c0fd5ad2ed7c074ae022282e441
7
+ data.tar.gz: 5f991d2aee4af7ac5a30b133ecfa8e1505b005fbc8e7092551f0d28bd4d26cee36fb645aa188e8a9664c0a7d5c991c78a2059445c82e1ec697ff14a8df3d2cdf
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rsmp (0.3.6)
4
+ rsmp (0.4.0)
5
5
  async (~> 1.29.1)
6
6
  async-io (~> 1.32.1)
7
7
  colorize (~> 0.8.1)
@@ -52,11 +52,14 @@ module RSMP
52
52
  raise RSMP::TimeoutError.new str
53
53
  end
54
54
 
55
+ # Get the collected message.
56
+ def message
57
+ @messages.first
58
+ end
59
+
55
60
  # Get the collected messages.
56
- # If one message was requested, return it as a plain object instead of array
57
- def result
58
- return @messages.first if @options[:num] == 1
59
- @messages.first @options[:num]
61
+ def messages
62
+ @messages
60
63
  end
61
64
 
62
65
  # Clear all query results
File without changes
@@ -0,0 +1,100 @@
1
+ module RSMP
2
+ # Base class for waiting for specific status or command responses, specified by
3
+ # a list of queries. Queries are defined as an array of hashes, e.g
4
+ # [
5
+ # {"cCI"=>"M0104", "cO"=>"setDate", "n"=>"securityCode", "v"=>"1111"},
6
+ # {"cCI"=>"M0104", "cO"=>"setDate", "n"=>"year", "v"=>"2020"},
7
+ # {"cCI"=>"M0104", "cO"=>"setDate", "n"=>"month", "v"=>/\d+/}
8
+ # ]
9
+ #
10
+ # Note that queries can contain regex patterns for values, like /\d+/ in the example above.
11
+ #
12
+ # When an input messages is received it typically contains several items, eg:
13
+ # [
14
+ # {"cCI"=>"M0104", "n"=>"month", "v"=>"9", "age"=>"recent"},
15
+ # {"cCI"=>"M0104", "n"=>"day", "v"=>"29", "age"=>"recent"},
16
+ # {"cCI"=>"M0104", "n"=>"hour", "v"=>"17", "age"=>"recent"}
17
+ # ]
18
+ #
19
+ # Each input item is matched against each of the queries.
20
+ # If a match is found, it's stored in the @results hash, with the query as the key,
21
+ # and a mesage and status as the key. In the example above, this query:
22
+ #
23
+ # {"cCI"=>"M0104", "cO"=>"setDate", "n"=>"month", "v"=>/\d+/}
24
+ #
25
+ # matches this input:
26
+ #
27
+ # {"cCI"=>"M0104", "n"=>"month", "v"=>"9", "age"=>"recent"}
28
+ #
29
+ # And the result is stored as:
30
+ # {
31
+ # {"cCI"=>"M0104", "cO"=>"setDate", "n"=>"month", "v"=>/\d+/} =>
32
+ # { <StatusResponse message>, {"cCI"=>"M0104", "cO"=>"setDate", "n"=>"month", "v"=>"9"} }
33
+ # }
34
+
35
+ class Matcher < Collector
36
+ attr_reader :queries
37
+
38
+ # Initialize with a list a wanted statuses
39
+ def initialize proxy, want, options={}
40
+ super proxy, options.merge( ingoing: true, outgoing: false)
41
+ @queries = want.map { |wanted_item| build_query wanted_item }
42
+ end
43
+
44
+ # Build a query object.
45
+ # Sub-classes should override to use their own query classes.
46
+ def build_query want
47
+ Query.new want
48
+ end
49
+
50
+ # Get a results
51
+ def query_result want
52
+ query = @queries.find { |q| q.want == want}
53
+ raise unless query
54
+ query.item
55
+ end
56
+
57
+ # get the first message. Useful when you only collected one mesage
58
+ def message
59
+ @queries.first.message
60
+ end
61
+
62
+ # Get messages from results
63
+ def messages
64
+ @queries.map { |query| query.message }.uniq
65
+ end
66
+
67
+ # Get items from results
68
+ def items
69
+ @queries.map { |query| query.item }.uniq
70
+ end
71
+
72
+ # Are there queries left to match?
73
+ def done?
74
+ @queries.all? { |query| query.done? }
75
+ end
76
+
77
+ # Get a simplified hash of queries, with values set to either true or false,
78
+ # indicating which queries have been matched.
79
+ def status
80
+ @queries.map { |query| [query.query,query.done?] }.to_h
81
+ end
82
+
83
+ # Get a simply array of bools, showing which queries ahve been matched.
84
+ def summary
85
+ @queries.map { |query| query.done? }
86
+ end
87
+
88
+ # Check if a messages matches our criteria.
89
+ # We iterate through each of the status items or return values in the message
90
+ # Breaks as soon as where done matching all queries
91
+ def check_match message
92
+ return unless match?(message)
93
+ @queries.each do |query| # look through queries
94
+ get_items(message).each do |item| # look through status items in message
95
+ break if query.check_match(item,message) != nil #check_item_match message, query, item
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,64 @@
1
+ module RSMP
2
+ # Class for waiting for specific command responses
3
+ class CommandResponseMatcher < Matcher
4
+ def initialize proxy, want, options={}
5
+ super proxy, want, options.merge(
6
+ type: ['CommandResponse','MessageNotAck'],
7
+ title:'command response'
8
+ )
9
+ end
10
+
11
+ def build_query want
12
+ CommandQuery.new want
13
+ end
14
+
15
+ # Get items, in our case the return values
16
+ def get_items message
17
+ message.attributes['rvs']
18
+ end
19
+ end
20
+
21
+ # Base class for waiting for status updates or responses
22
+ class StatusUpdateOrResponseMatcher < Matcher
23
+ def initialize proxy, want, options={}
24
+ super proxy, want, options.merge
25
+ end
26
+
27
+ def build_query want
28
+ StatusQuery.new want
29
+ end
30
+
31
+ # Get items, in our case status values
32
+ def get_items message
33
+ message.attributes['sS']
34
+ end
35
+ end
36
+
37
+ # Class for waiting for specific status responses
38
+ class StatusResponseMatcher < StatusUpdateOrResponseMatcher
39
+ def initialize proxy, want, options={}
40
+ super proxy, want, options.merge(
41
+ type: ['StatusResponse','MessageNotAck'],
42
+ title: 'status response'
43
+ )
44
+ end
45
+ end
46
+
47
+ # Class for waiting for specific status responses
48
+ class StatusUpdateMatcher < StatusUpdateOrResponseMatcher
49
+ def initialize proxy, want, options={}
50
+ super proxy, want, options.merge(
51
+ type: ['StatusUpdate','MessageNotAck'],
52
+ title:'status update'
53
+ )
54
+ end
55
+ end
56
+
57
+ # Class for waiting for an aggregated status response
58
+ class AggregatedStatusMatcher < Collector
59
+ def initialize proxy, options={}
60
+ required = { type: ['AggregatedStatus','MessageNotAck'], title: 'aggregated status' }
61
+ super proxy, options.merge(required)
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,33 @@
1
+ module RSMP
2
+ # Match a specific command responses
3
+ class CommandQuery < Query
4
+ # Match a return value item against a query
5
+ def match? item
6
+ return nil if @want['cCI'] && @want['cCI'] != item['cCI']
7
+ return nil if @want['n'] && @want['n'] != item['n']
8
+ if @want['v'].is_a? Regexp
9
+ return false if @want['v'] && item['v'] !~ @want['v']
10
+ else
11
+ return false if @want['v'] && item['v'] != @want['v']
12
+ end
13
+ true
14
+ end
15
+ end
16
+
17
+ # Match a specific status response or update
18
+ class StatusQuery < Query
19
+ # Match a status value against a query
20
+ def match? item
21
+ return nil if @want['sCI'] && @want['sCI'] != item['sCI']
22
+ return nil if @want['cO'] && @want['cO'] != item['cO']
23
+ return nil if @want['n'] && @want['n'] != item['n']
24
+ return false if @want['q'] && @want['q'] != item['q']
25
+ if @want['s'].is_a? Regexp
26
+ return false if @want['s'] && item['s'] !~ @want['s']
27
+ else
28
+ return false if @want['s'] && item['s'] != @want['s']
29
+ end
30
+ true
31
+ end
32
+ end
33
+ end
File without changes
@@ -0,0 +1,44 @@
1
+ module RSMP
2
+
3
+ # Class that matches a single status or command item
4
+ class Query
5
+ attr_reader :want, :item, :message
6
+
7
+ def initialize want
8
+ @want = want
9
+ @item = nil
10
+ @message = nil
11
+ @done = false
12
+ end
13
+
14
+ def done?
15
+ @done
16
+ end
17
+
18
+ def check_match item, message
19
+ matched = match? item
20
+ if matched == true
21
+ keep message, item
22
+ true
23
+ elsif matched == false
24
+ forget
25
+ true
26
+ end
27
+ end
28
+
29
+ def match? item
30
+ end
31
+
32
+ # Mark a query as matched and store item and message
33
+ def keep message, item
34
+ @message = message
35
+ @item = item
36
+ @done = true
37
+ end
38
+
39
+ # Mark a query as not matched
40
+ def forget
41
+ @done = false
42
+ end
43
+ end
44
+ end
@@ -13,7 +13,7 @@ module RSMP
13
13
  :rest,
14
14
  :not_connected ]
15
15
 
16
- def initialize node:, id:, grouped:
16
+ def initialize node:, id:, grouped: false
17
17
  @c_id = id
18
18
  @node = node
19
19
  @grouped = grouped
@@ -39,7 +39,7 @@ module RSMP
39
39
  end
40
40
 
41
41
  def infer_component_type component_id
42
- { klass: Component, grouped: false }
42
+ Component
43
43
  end
44
44
 
45
45
  def find_component component_id, build: true
@@ -47,10 +47,10 @@ module RSMP
47
47
  return component if component
48
48
  if build
49
49
  inferred = infer_component_type component_id
50
- component = inferred[:klass].new node: self, id: component_id
50
+ component = inferred.new node: self, id: component_id
51
51
  @components[ component_id] = component
52
52
  class_name = component.class.name.split('::').last
53
- log "Inferred component #{component_id} of type #{class_name} for site #{@site_id}", level: :info
53
+ log "Inferred #{class_name} component #{component_id}", level: :info
54
54
  component
55
55
  else
56
56
  raise UnknownComponent.new("Component #{component_id} not found") unless component
@@ -121,18 +121,6 @@ module RSMP
121
121
  end
122
122
  end
123
123
 
124
- def infer_component_type component_id
125
- if component_id =~ /TC/
126
- { klass: TrafficController, grouped: true }
127
- elsif component_id =~ /DL/
128
- { klass: DetectorLogic, goruped: false }
129
- elsif component_id =~ /SG/
130
- { klass: SignalGroup, grouped: false }
131
- else
132
- super
133
- end
134
- end
135
-
136
124
  def process_aggregated_status message
137
125
  se = message.attribute("se")
138
126
  validate_aggregated_status(message,se) == false
@@ -347,20 +335,12 @@ module RSMP
347
335
  @supervisor.notify_error e, options if @supervisor
348
336
  end
349
337
 
350
- def wait_for_alarm parent_task, options={}
351
- matching_alarm = nil
352
- message = collect(parent_task,options.merge(type: "Alarm", with_message: true, num: 1)) do |message|
353
- # TODO check components
354
- matching_alarm = nil
355
- alarm = message
338
+ def collect_alarms parent_task, options={}
339
+ collect(parent_task,options.merge(type: "Alarm")) do |alarm|
356
340
  next if options[:aCId] && options[:aCId] != alarm.attribute("aCId")
357
341
  next if options[:aSp] && options[:aSp] != alarm.attribute("aSp")
358
342
  next if options[:aS] && options[:aS] != alarm.attribute("aS")
359
- matching_alarm = alarm
360
- break
361
- end
362
- if item
363
- { message: message, status: matching_alarm }
343
+ true
364
344
  end
365
345
  end
366
346
 
data/lib/rsmp/tlc.rb CHANGED
@@ -293,7 +293,8 @@ module RSMP
293
293
  def handle_s0002 status_code, status_name=nil
294
294
  case status_name
295
295
  when 'detectorlogicstatus'
296
- RSMP::Tlc.make_status @detector_logics.map { |dl| dl.forced ? '1' : '0' }.join
296
+ RSMP::Tlc.make_status @detector_logics.each { |dl| p dl.value }
297
+ RSMP::Tlc.make_status @detector_logics.map { |dl| dl.value ? '1' : '0' }.join
297
298
  end
298
299
  end
299
300
 
@@ -625,13 +626,15 @@ module RSMP
625
626
  class SignalGroup < Component
626
627
  attr_reader :plan, :state
627
628
 
628
- def initialize node:, id:, plan:
629
+ # plan is a string, with each character representing a signal phase at a particular second in the cycle
630
+ def initialize node:, id:, plan: nil
629
631
  super node: node, id: id, grouped: false
630
632
  @plan = plan
631
633
  move 0
632
634
  end
633
635
 
634
636
  def get_state pos
637
+ return 'a' unless @plan # if no plan, use phase a, which means disabled/dark
635
638
  if pos > @plan.length
636
639
  '.'
637
640
  else
@@ -701,7 +704,7 @@ module RSMP
701
704
  end
702
705
 
703
706
  class DetectorLogic < Component
704
- attr_reader :status, :forced, :value
707
+ attr_reader :forced, :value
705
708
 
706
709
  def initialize node:, id:
707
710
  super node: node, id: id, grouped: false
@@ -781,13 +784,20 @@ module RSMP
781
784
 
782
785
  def handle_m0008 arg
783
786
  @node.verify_security_code 2, arg['securityCode']
784
- force_detector_logic arg['status']=='True', arg['value']='True'
787
+ status = arg['status']=='True'
788
+ mode = arg['mode']=='True'
789
+ force_detector_logic status, mode
785
790
  arg
786
791
  end
787
792
 
788
- def force_detector_logic status, value
789
- @forced = status
793
+ def force_detector_logic forced, value
794
+ @forced = forced
790
795
  @value = value
796
+ if @forced
797
+ log "Forcing to #{value}", level: :info
798
+ else
799
+ log "Releasing", level: :info
800
+ end
791
801
  end
792
802
 
793
803
  end
data/lib/rsmp/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module RSMP
2
- VERSION = "0.3.6"
2
+ VERSION = "0.4.0"
3
3
  end
data/lib/rsmp.rb CHANGED
@@ -17,10 +17,13 @@ require 'rsmp/wait'
17
17
  require 'rsmp/node'
18
18
  require 'rsmp/supervisor'
19
19
  require 'rsmp/components'
20
- require 'rsmp/notifier'
21
- require 'rsmp/listener'
22
- require 'rsmp/collector'
23
- require 'rsmp/matcher'
20
+ require 'rsmp/collect/notifier'
21
+ require 'rsmp/collect/listener'
22
+ require 'rsmp/collect/collector'
23
+ require 'rsmp/collect/query'
24
+ require 'rsmp/collect/matcher'
25
+ require 'rsmp/collect/message_queries'
26
+ require 'rsmp/collect/message_matchers'
24
27
  require 'rsmp/component'
25
28
  require 'rsmp/site'
26
29
  require 'rsmp/proxy'
data/test.rb ADDED
@@ -0,0 +1,27 @@
1
+ class A
2
+ def go &block
3
+ @block = block # block will be converted automatically to a Proc
4
+ indirect
5
+ end
6
+
7
+ def call
8
+ @block.call
9
+ end
10
+
11
+ def indirect
12
+ call
13
+ end
14
+
15
+ end
16
+
17
+ a = A.new
18
+
19
+ a.go do
20
+ break # this is ok. break causes the block to exit, and the encasing method to return - go() will exit
21
+ end
22
+
23
+ # this raises an error. the block we passed to go() will be called again, and it tries to break
24
+ # but we're not inside a method we can exit from
25
+
26
+
27
+ a.indirect
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rsmp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.6
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Emil Tin
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-10-22 00:00:00.000000000 Z
11
+ date: 2021-10-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async
@@ -205,7 +205,13 @@ files:
205
205
  - lib/rsmp.rb
206
206
  - lib/rsmp/archive.rb
207
207
  - lib/rsmp/cli.rb
208
- - lib/rsmp/collector.rb
208
+ - lib/rsmp/collect/collector.rb
209
+ - lib/rsmp/collect/listener.rb
210
+ - lib/rsmp/collect/matcher.rb
211
+ - lib/rsmp/collect/message_matchers.rb
212
+ - lib/rsmp/collect/message_queries.rb
213
+ - lib/rsmp/collect/notifier.rb
214
+ - lib/rsmp/collect/query.rb
209
215
  - lib/rsmp/component.rb
210
216
  - lib/rsmp/components.rb
211
217
  - lib/rsmp/convert/export/json_schema.rb
@@ -213,13 +219,10 @@ files:
213
219
  - lib/rsmp/deep_merge.rb
214
220
  - lib/rsmp/error.rb
215
221
  - lib/rsmp/inspect.rb
216
- - lib/rsmp/listener.rb
217
222
  - lib/rsmp/logger.rb
218
223
  - lib/rsmp/logging.rb
219
- - lib/rsmp/matcher.rb
220
224
  - lib/rsmp/message.rb
221
225
  - lib/rsmp/node.rb
222
- - lib/rsmp/notifier.rb
223
226
  - lib/rsmp/proxy.rb
224
227
  - lib/rsmp/rsmp.rb
225
228
  - lib/rsmp/site.rb
@@ -231,6 +234,7 @@ files:
231
234
  - lib/rsmp/version.rb
232
235
  - lib/rsmp/wait.rb
233
236
  - rsmp.gemspec
237
+ - test.rb
234
238
  homepage: https://github.com/rsmp-nordic/rsmp
235
239
  licenses:
236
240
  - MIT
data/lib/rsmp/matcher.rb DELETED
@@ -1,195 +0,0 @@
1
- module RSMP
2
-
3
- # Base class for waiting for specific status or command responses, specified by
4
- # a list of queries. Queries are defined as an array of hashes, e.g
5
- # [
6
- # {"cCI"=>"M0104", "cO"=>"setDate", "n"=>"securityCode", "v"=>"1111"},
7
- # {"cCI"=>"M0104", "cO"=>"setDate", "n"=>"year", "v"=>"2020"},
8
- # {"cCI"=>"M0104", "cO"=>"setDate", "n"=>"month", "v"=>/\d+/}
9
- # ]
10
- #
11
- # Note that queries can contain regex patterns for values, like /\d+/ in the example above.
12
- #
13
- # When an input messages is received it typically contains several items, eg:
14
- # [
15
- # {"cCI"=>"M0104", "n"=>"month", "v"=>"9", "age"=>"recent"},
16
- # {"cCI"=>"M0104", "n"=>"day", "v"=>"29", "age"=>"recent"},
17
- # {"cCI"=>"M0104", "n"=>"hour", "v"=>"17", "age"=>"recent"}
18
- # ]
19
- #
20
- # Each input item is matched against each of the queries.
21
- # If a match is found, it's stored in the @results hash, with the query as the key,
22
- # and a mesage and status as the key. In the example above, this query:
23
- #
24
- # {"cCI"=>"M0104", "cO"=>"setDate", "n"=>"month", "v"=>/\d+/}
25
- #
26
- # matches this input:
27
- #
28
- # {"cCI"=>"M0104", "n"=>"month", "v"=>"9", "age"=>"recent"}
29
- #
30
- # And the result is stored as:
31
- # {
32
- # {"cCI"=>"M0104", "cO"=>"setDate", "n"=>"month", "v"=>/\d+/} =>
33
- # { <StatusResponse message>, {"cCI"=>"M0104", "cO"=>"setDate", "n"=>"month", "v"=>"9"} }
34
- # }
35
- #
36
- #
37
- class Matcher < Collector
38
- attr_reader :queries
39
-
40
- # Initialize with a list a wanted statuses
41
- def initialize proxy, want, options={}
42
- super proxy, options.merge( ingoing: true, outgoing: false)
43
- @queries = {}
44
- want.each do |query|
45
- @queries[query] = nil
46
- end
47
- end
48
-
49
- # Get the results, as a hash of queries => results
50
- def result
51
- @queries
52
- end
53
-
54
- # Get messages from results
55
- def messages
56
- @queries.map { |query,result| result[:message] }.uniq
57
- end
58
-
59
- # Get items from results
60
- def items
61
- @queries.map { |query,result| result[:item] }.uniq
62
- end
63
-
64
- # Are there queries left to match?
65
- def done?
66
- @queries.values.all? { |result| result != nil }
67
- end
68
-
69
- # Get a simplified hash of queries, with values set to either true or false,
70
- # indicating which queries have been matched.
71
- def status
72
- @queries.transform_values{ |v| v != nil }
73
- end
74
-
75
- # Get a simply array of bools, showing which queries ahve been matched.
76
- def summary
77
- @queries.values.map { |v| v != nil }
78
- end
79
-
80
- # Mark a query as matched, by linking it to the matched item and message
81
- def keep query, message, item
82
- @queries[query] = { message:message, item:item }
83
- end
84
-
85
- # Mark a query as not matched
86
- def forget query
87
- @queries[query] = nil
88
- end
89
-
90
- # Check if a messages matches our criteria.
91
- # We iterate through each of the status items or return values in the message
92
- # Breaks as soon as where done matching all queries
93
- def check_match message
94
- return unless match?(message)
95
- @queries.keys.each do |query| # look through queries
96
- get_items(message).each do |item| # look through status items in message
97
- break if check_item_match message, query, item
98
- end
99
- end
100
- end
101
-
102
- # Check if an item matches, and mark query as matched/unmatched accordingly.
103
- def check_item_match message, query, item
104
- matched = match_item? query, item
105
- if matched == true
106
- keep query, message, item
107
- true
108
- elsif matched == false
109
- forget query
110
- true
111
- end
112
- end
113
- end
114
-
115
- # Class for waiting for specific command responses
116
- class CommandResponseMatcher < Matcher
117
- def initialize proxy, want, options={}
118
- super proxy, want, options.merge(
119
- type: ['CommandResponse','MessageNotAck'],
120
- title:'command response'
121
- )
122
- end
123
-
124
- # Get items, in our case the return values
125
- def get_items message
126
- message.attributes['rvs']
127
- end
128
-
129
- # Match a return value item against a query
130
- def match_item? query, item
131
- return nil if query['cCI'] && query['cCI'] != item['cCI']
132
- return nil if query['n'] && query['n'] != item['n']
133
- if query['v'].is_a? Regexp
134
- return false if query['v'] && item['v'] !~ query['v']
135
- else
136
- return false if query['v'] && item['v'] != query['v']
137
- end
138
- true
139
- end
140
- end
141
-
142
- # Base class for waiting for status updates or responses
143
- class StatusUpdateOrResponseMatcher < Matcher
144
- def initialize proxy, want, options={}
145
- super proxy, want, options.merge
146
- end
147
-
148
- # Get items, in our case status values
149
- def get_items message
150
- message.attributes['sS']
151
- end
152
-
153
- # Match a status value against a query
154
- def match_item? query, item
155
- return nil if query['sCI'] && query['sCI'] != item['sCI']
156
- return nil if query['cO'] && query['cO'] != item['cO']
157
- return nil if query['n'] && query['n'] != item['n']
158
- return false if query['q'] && query['q'] != item['q']
159
- if query['s'].is_a? Regexp
160
- return false if query['s'] && item['s'] !~ query['s']
161
- else
162
- return false if query['s'] && item['s'] != query['s']
163
- end
164
- true
165
- end
166
- end
167
-
168
- # Class for waiting for specific status responses
169
- class StatusResponseMatcher < StatusUpdateOrResponseMatcher
170
- def initialize proxy, want, options={}
171
- super proxy, want, options.merge(
172
- type: ['StatusResponse','MessageNotAck'],
173
- title: 'status response'
174
- )
175
- end
176
- end
177
-
178
- # Class for waiting for specific status responses
179
- class StatusUpdateMatcher < StatusUpdateOrResponseMatcher
180
- def initialize proxy, want, options={}
181
- super proxy, want, options.merge(
182
- type: ['StatusUpdate','MessageNotAck'],
183
- title:'status update'
184
- )
185
- end
186
- end
187
-
188
- # Class for waiting for an aggregated status response
189
- class AggregatedStatusMatcher < Collector
190
- def initialize proxy, options={}
191
- required = { type: ['AggregatedStatus','MessageNotAck'], title: 'aggregated status' }
192
- super proxy, options.merge(required)
193
- end
194
- end
195
- end