rsmp 0.37.0 → 0.39.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.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/.devcontainer/devcontainer.json +22 -0
  3. data/.github/workflows/rubocop.yaml +17 -0
  4. data/.gitignore +5 -6
  5. data/.rubocop.yml +69 -0
  6. data/.tool-versions +1 -1
  7. data/Gemfile +14 -1
  8. data/Gemfile.lock +64 -29
  9. data/Rakefile +3 -3
  10. data/lib/rsmp/cli.rb +148 -124
  11. data/lib/rsmp/collect/ack_collector.rb +8 -7
  12. data/lib/rsmp/collect/aggregated_status_collector.rb +4 -4
  13. data/lib/rsmp/collect/alarm_collector.rb +31 -23
  14. data/lib/rsmp/collect/alarm_matcher.rb +6 -6
  15. data/lib/rsmp/collect/collector/logging.rb +18 -0
  16. data/lib/rsmp/collect/collector/reporting.rb +44 -0
  17. data/lib/rsmp/collect/collector/status.rb +34 -0
  18. data/lib/rsmp/collect/collector.rb +69 -150
  19. data/lib/rsmp/collect/command_matcher.rb +19 -6
  20. data/lib/rsmp/collect/command_response_collector.rb +7 -7
  21. data/lib/rsmp/collect/distributor.rb +14 -11
  22. data/lib/rsmp/collect/filter.rb +31 -15
  23. data/lib/rsmp/collect/matcher.rb +9 -13
  24. data/lib/rsmp/collect/queue.rb +7 -7
  25. data/lib/rsmp/collect/receiver.rb +11 -15
  26. data/lib/rsmp/collect/state_collector.rb +116 -77
  27. data/lib/rsmp/collect/status_collector.rb +6 -6
  28. data/lib/rsmp/collect/status_matcher.rb +15 -4
  29. data/lib/rsmp/{alarm_state.rb → component/alarm_state.rb} +76 -38
  30. data/lib/rsmp/{component.rb → component/component.rb} +15 -15
  31. data/lib/rsmp/component/component_base.rb +88 -0
  32. data/lib/rsmp/component/component_proxy.rb +75 -0
  33. data/lib/rsmp/component/components.rb +62 -0
  34. data/lib/rsmp/convert/export/json_schema.rb +118 -110
  35. data/lib/rsmp/convert/import/yaml.rb +22 -18
  36. data/lib/rsmp/{rsmp.rb → helpers/clock.rb} +8 -11
  37. data/lib/rsmp/{deep_merge.rb → helpers/deep_merge.rb} +3 -1
  38. data/lib/rsmp/helpers/error.rb +72 -0
  39. data/lib/rsmp/helpers/inspect.rb +41 -0
  40. data/lib/rsmp/log/archive.rb +97 -0
  41. data/lib/rsmp/log/colorization.rb +41 -0
  42. data/lib/rsmp/log/filtering.rb +54 -0
  43. data/lib/rsmp/log/logger.rb +207 -0
  44. data/lib/rsmp/{logging.rb → log/logging.rb} +6 -7
  45. data/lib/rsmp/message.rb +185 -148
  46. data/lib/rsmp/{node.rb → node/node.rb} +20 -19
  47. data/lib/rsmp/{protocol.rb → node/protocol.rb} +6 -3
  48. data/lib/rsmp/node/site/site.rb +192 -0
  49. data/lib/rsmp/node/supervisor/modules/configuration.rb +59 -0
  50. data/lib/rsmp/node/supervisor/modules/connection.rb +140 -0
  51. data/lib/rsmp/node/supervisor/modules/sites.rb +64 -0
  52. data/lib/rsmp/node/supervisor/supervisor.rb +69 -0
  53. data/lib/rsmp/{task.rb → node/task.rb} +13 -14
  54. data/lib/rsmp/proxy/modules/acknowledgements.rb +144 -0
  55. data/lib/rsmp/proxy/modules/receive.rb +119 -0
  56. data/lib/rsmp/proxy/modules/send.rb +76 -0
  57. data/lib/rsmp/proxy/modules/state.rb +25 -0
  58. data/lib/rsmp/proxy/modules/tasks.rb +105 -0
  59. data/lib/rsmp/proxy/modules/versions.rb +69 -0
  60. data/lib/rsmp/proxy/modules/watchdogs.rb +66 -0
  61. data/lib/rsmp/proxy/proxy.rb +197 -0
  62. data/lib/rsmp/proxy/site/modules/aggregated_status.rb +52 -0
  63. data/lib/rsmp/proxy/site/modules/alarms.rb +27 -0
  64. data/lib/rsmp/proxy/site/modules/commands.rb +31 -0
  65. data/lib/rsmp/proxy/site/modules/status.rb +110 -0
  66. data/lib/rsmp/proxy/site/site_proxy.rb +204 -0
  67. data/lib/rsmp/proxy/supervisor/modules/aggregated_status.rb +47 -0
  68. data/lib/rsmp/proxy/supervisor/modules/alarms.rb +73 -0
  69. data/lib/rsmp/proxy/supervisor/modules/commands.rb +53 -0
  70. data/lib/rsmp/proxy/supervisor/modules/status.rb +204 -0
  71. data/lib/rsmp/proxy/supervisor/supervisor_proxy.rb +177 -0
  72. data/lib/rsmp/tlc/detector_logic.rb +19 -34
  73. data/lib/rsmp/tlc/input_states.rb +126 -0
  74. data/lib/rsmp/tlc/modules/detector_logics.rb +50 -0
  75. data/lib/rsmp/tlc/modules/display.rb +78 -0
  76. data/lib/rsmp/tlc/modules/helpers.rb +41 -0
  77. data/lib/rsmp/tlc/modules/inputs.rb +173 -0
  78. data/lib/rsmp/tlc/modules/modes.rb +253 -0
  79. data/lib/rsmp/tlc/modules/outputs.rb +30 -0
  80. data/lib/rsmp/tlc/modules/plans.rb +218 -0
  81. data/lib/rsmp/tlc/modules/signal_groups.rb +109 -0
  82. data/lib/rsmp/tlc/modules/startup_sequence.rb +22 -0
  83. data/lib/rsmp/tlc/modules/system.rb +140 -0
  84. data/lib/rsmp/tlc/modules/traffic_data.rb +49 -0
  85. data/lib/rsmp/tlc/signal_group.rb +38 -41
  86. data/lib/rsmp/tlc/signal_plan.rb +14 -11
  87. data/lib/rsmp/tlc/signal_priority.rb +40 -35
  88. data/lib/rsmp/tlc/startup_sequence.rb +59 -0
  89. data/lib/rsmp/tlc/traffic_controller.rb +38 -1010
  90. data/lib/rsmp/tlc/traffic_controller_site.rb +58 -57
  91. data/lib/rsmp/version.rb +1 -1
  92. data/lib/rsmp.rb +82 -48
  93. data/rsmp.gemspec +24 -31
  94. metadata +79 -139
  95. data/lib/rsmp/archive.rb +0 -76
  96. data/lib/rsmp/collect/message_matchers.rb +0 -0
  97. data/lib/rsmp/component_base.rb +0 -87
  98. data/lib/rsmp/component_proxy.rb +0 -57
  99. data/lib/rsmp/components.rb +0 -65
  100. data/lib/rsmp/error.rb +0 -71
  101. data/lib/rsmp/inspect.rb +0 -46
  102. data/lib/rsmp/logger.rb +0 -216
  103. data/lib/rsmp/proxy.rb +0 -693
  104. data/lib/rsmp/site.rb +0 -188
  105. data/lib/rsmp/site_proxy.rb +0 -389
  106. data/lib/rsmp/supervisor.rb +0 -302
  107. data/lib/rsmp/supervisor_proxy.rb +0 -510
  108. data/lib/rsmp/tlc/inputs.rb +0 -134
data/lib/rsmp/cli.rb CHANGED
@@ -1,186 +1,209 @@
1
1
  require 'thor'
2
- require 'rsmp'
2
+ require_relative '../rsmp'
3
3
 
4
4
  module RSMP
5
+ # CLI commands for running RSMP site and supervisor.
5
6
  class CLI < Thor
6
- desc "version", "Show version"
7
+ desc 'version', 'Show version'
7
8
  def version
8
9
  puts RSMP::VERSION
9
10
  end
10
11
 
11
- desc "site", "Run RSMP site"
12
- method_option :config, :type => :string, :aliases => "-c", banner: 'Path to .yaml config file'
13
- method_option :id, :type => :string, :aliases => "-i", banner: 'RSMP site id'
14
- method_option :supervisors, :type => :string, :aliases => "-s", banner: 'ip:port,... list of supervisor to connect to'
15
- method_option :core, :string => :string, banner: "Core version: [#{RSMP::Schema.core_versions.join(' ')}]", enum: RSMP::Schema.core_versions
16
- method_option :type, :type => :string, :aliases => "-t", banner: 'Type of site: [tlc]', enum: ['tlc'], default: 'tlc'
17
- method_option :log, :type => :string, :aliases => "-l", banner: 'Path to log file'
18
- method_option :json, :type => :boolean, :aliases => "-j", banner: 'Show JSON messages in log'
12
+ desc 'site', 'Run RSMP site'
13
+ method_option :config, type: :string, aliases: '-c', banner: 'Path to .yaml config file'
14
+ method_option :id, type: :string, aliases: '-i', banner: 'RSMP site id'
15
+ method_option :supervisors, type: :string, aliases: '-s',
16
+ banner: 'ip:port,... list of supervisor to connect to'
17
+ method_option :core, type: :string, banner: "Core version: [#{RSMP::Schema.core_versions.join(' ')}]", enum: RSMP::Schema.core_versions
18
+ method_option :type, type: :string, aliases: '-t', banner: 'Type of site: [tlc]', enum: ['tlc'],
19
+ default: 'tlc'
20
+ method_option :log, type: :string, aliases: '-l', banner: 'Path to log file'
21
+ method_option :json, type: :boolean, aliases: '-j', banner: 'Show JSON messages in log'
19
22
  def site
20
- settings = {}
21
- log_settings = { 'active' => true }
23
+ settings, log_settings = load_site_configuration
24
+ apply_site_options(settings, log_settings)
25
+ site_class = determine_site_class(settings)
26
+ run_site(site_class, settings, log_settings)
27
+ rescue Interrupt
28
+ # ctrl-c
29
+ rescue StandardError => e
30
+ puts "Uncaught error: #{e}"
31
+ puts caller.join("\n")
32
+ end
33
+
34
+ desc 'supervisor', 'Run RSMP supervisor'
35
+ method_option :config, type: :string, aliases: '-c', banner: 'Path to .yaml config file'
36
+ method_option :id, type: :string, aliases: '-i', banner: 'RSMP site id'
37
+ method_option :ip, type: :string, banner: 'IP address to listen on'
38
+ method_option :port, type: :string, aliases: '-p', banner: 'Port to listen on'
39
+ method_option :core, type: :string, banner: "Core version: [#{RSMP::Schema.core_versions.join(' ')}]", enum: RSMP::Schema.core_versions
40
+ method_option :log, type: :string, aliases: '-l', banner: 'Path to log file'
41
+ method_option :json, type: :boolean, aliases: '-j', banner: 'Show JSON messages in log'
42
+ def supervisor
43
+ settings, log_settings = load_supervisor_configuration
44
+ apply_supervisor_options(settings, log_settings)
45
+ run_supervisor(settings, log_settings)
46
+ rescue Interrupt
47
+ # ctrl-c
48
+ end
49
+
50
+ desc 'convert', 'Convert SXL from YAML to JSON Schema'
51
+ method_option :in, type: :string, aliases: '-i', banner: 'Path to YAML input file'
52
+ method_option :out, type: :string, aliases: '-o', banner: 'Path to JSON Schema output file'
53
+ def convert
54
+ validate_convert_options
55
+ validate_input_file_exists
56
+ perform_conversion
57
+ end
58
+
59
+ no_commands do
60
+ def load_site_configuration
61
+ settings = {}
62
+ log_settings = { 'active' => true }
63
+
64
+ return [settings, log_settings] unless options[:config]
22
65
 
23
- if options[:config]
24
66
  if File.exist? options[:config]
25
67
  settings = YAML.load_file options[:config]
26
- log_settings = settings.delete('log') || {}
68
+ log_settings = settings.delete('log') || log_settings
27
69
  else
28
70
  puts "Error: Config #{options[:config]} not found"
29
71
  exit
30
72
  end
31
- end
32
73
 
33
- if options[:id]
34
- settings['site_id'] = options[:id]
74
+ [settings, log_settings]
35
75
  end
76
+ end
36
77
 
37
- if options[:supervisors]
38
- settings['supervisors'] = []
39
- options[:supervisors].split(',').each do |supervisor|
40
- ip, port = supervisor.split ':'
41
- ip = '127.0.0.1' if ip.empty?
42
- port = '12111' if port.empty?
43
- settings['supervisors'] << {"ip"=>ip, "port"=>port}
44
- end
45
- end
78
+ private
46
79
 
47
- if options[:core]
48
- settings['core_version'] = options[:core]
49
- end
80
+ def apply_site_options(settings, log_settings)
81
+ apply_basic_site_options(settings)
82
+ parse_supervisors(settings) if options[:supervisors]
83
+ apply_log_options(log_settings)
84
+ end
50
85
 
51
- site_class = RSMP::Site
52
- site_type = options[:type] || settings['type']
53
- case site_type
54
- when 'tlc'
55
- site_class = RSMP::TLC::TrafficControllerSite
56
- else
57
- puts "Error: Unknown site type #{site_type}"
58
- exit
59
- end
86
+ def apply_basic_site_options(settings)
87
+ settings['site_id'] = options[:id] if options[:id]
88
+ settings['core_version'] = options[:core] if options[:core]
89
+ end
60
90
 
61
- if options[:log]
62
- log_settings['path'] = options[:log]
91
+ def parse_supervisors(settings)
92
+ settings['supervisors'] = []
93
+ options[:supervisors].split(',').each do |supervisor|
94
+ ip, port = supervisor.split ':'
95
+ ip = '127.0.0.1' if ip.empty?
96
+ port = '12111' if port.empty?
97
+ settings['supervisors'] << { 'ip' => ip, 'port' => port }
63
98
  end
99
+ end
64
100
 
65
- if options[:json]
66
- log_settings['json'] = options[:json]
101
+ def determine_site_class(settings)
102
+ site_type = options[:type] || settings['type']
103
+ case site_type
104
+ when 'tlc'
105
+ RSMP::TLC::TrafficControllerSite
106
+ else
107
+ puts "Error: Unknown site type #{site_type}"
108
+ exit
67
109
  end
110
+ end
68
111
 
112
+ def run_site(site_class, settings, log_settings)
69
113
  Async do |task|
70
114
  task.annotate 'cli'
71
115
  loop do
72
- begin
73
- site = site_class.new(site_settings: settings, log_settings: log_settings)
74
- site.start
75
- site.wait
76
- rescue Psych::SyntaxError => e
77
- puts "Cannot read config file #{e}"
78
- break
79
- rescue RSMP::Schema::UnknownSchemaTypeError => e
80
- puts "Cannot start site: #{e}"
81
- break
82
- rescue RSMP::Schema::UnknownSchemaVersionError => e
83
- puts "Cannot start site: #{e}"
84
- break
85
- rescue RSMP::ConfigurationError => e
86
- puts "Cannot start site: #{e}"
87
- break
88
- rescue RSMP::Restart
89
- site.stop
90
- end
116
+ site = site_class.new(site_settings: settings, log_settings: log_settings)
117
+ site.start
118
+ site.wait
119
+ rescue Psych::SyntaxError => e
120
+ puts "Cannot read config file #{e}"
121
+ break
122
+ rescue RSMP::Schema::UnknownSchemaTypeError, RSMP::Schema::UnknownSchemaVersionError,
123
+ RSMP::ConfigurationError => e
124
+ puts "Cannot start site: #{e}"
125
+ break
126
+ rescue RSMP::Restart
127
+ site.stop
91
128
  end
92
129
  end
93
- rescue Interrupt
94
- # cntr-c
95
- rescue Exception => e
96
- puts "Uncaught error: #{e}"
97
- puts caller.join("\n")
98
130
  end
99
131
 
100
- desc "supervisor", "Run RSMP supervisor"
101
- method_option :config, :type => :string, :aliases => "-c", banner: 'Path to .yaml config file'
102
- method_option :id, :type => :string, :aliases => "-i", banner: 'RSMP site id'
103
- method_option :ip, :type => :numeric, banner: 'IP address to listen on'
104
- method_option :port, :type => :string, :aliases => "-p", banner: 'Port to listen on'
105
- method_option :core, :string => :string, banner: "Core version: [#{RSMP::Schema.core_versions.join(' ')}]", enum: RSMP::Schema.core_versions
106
- method_option :log, :type => :string, :aliases => "-l", banner: 'Path to log file'
107
- method_option :json, :type => :boolean, :aliases => "-j", banner: 'Show JSON messages in log'
108
- def supervisor
132
+ def load_supervisor_configuration
109
133
  settings = {}
110
134
  log_settings = { 'active' => true }
111
135
 
112
- if options[:config]
113
- if File.exist? options[:config]
114
- settings = YAML.load_file options[:config]
115
- log_settings = settings.delete 'log'
116
- else
117
- puts "Error: Config #{options[:config]} not found"
118
- exit
119
- end
120
- end
136
+ return [settings, log_settings] unless options[:config]
121
137
 
122
- if options[:id]
123
- settings['site_id'] = options[:id]
138
+ if File.exist? options[:config]
139
+ settings = YAML.load_file options[:config]
140
+ log_settings = settings.delete('log') || log_settings
141
+ else
142
+ puts "Error: Config #{options[:config]} not found"
143
+ exit
124
144
  end
125
145
 
126
- if options[:ip]
127
- settings['ip'] = options[:ip]
128
- end
146
+ [settings, log_settings]
147
+ end
129
148
 
130
- if options[:port]
131
- settings['port'] = options[:port]
132
- end
149
+ def apply_supervisor_options(settings, log_settings)
150
+ apply_basic_supervisor_options(settings)
151
+ apply_core_version_option(settings)
152
+ apply_log_options(log_settings)
153
+ end
133
154
 
134
- if options[:core]
135
- settings['guest'] = {}
136
- settings['guest']['core_version'] = options[:core]
137
- end
155
+ def apply_basic_supervisor_options(settings)
156
+ settings['site_id'] = options[:id] if options[:id]
157
+ settings['ip'] = options[:ip] if options[:ip]
158
+ settings['port'] = options[:port] if options[:port]
159
+ end
138
160
 
139
- if options[:log]
140
- log_settings['path'] = options[:log]
141
- end
161
+ def apply_core_version_option(settings)
162
+ return unless options[:core]
142
163
 
143
- if options[:json]
144
- log_settings['json'] = options[:json]
145
- end
164
+ settings['guest'] ||= {}
165
+ settings['guest']['core_version'] = options[:core]
166
+ end
146
167
 
168
+ def apply_log_options(log_settings)
169
+ log_settings['path'] = options[:log] if options[:log]
170
+ log_settings['json'] = options[:json] if options[:json]
171
+ end
172
+
173
+ def run_supervisor(settings, log_settings)
147
174
  Async do |task|
148
175
  task.annotate 'cli'
149
- supervisor = RSMP::Supervisor.new(supervisor_settings:settings,log_settings:log_settings)
176
+ supervisor = RSMP::Supervisor.new(supervisor_settings: settings, log_settings: log_settings)
150
177
  supervisor.start
151
178
  supervisor.wait
152
179
  rescue Psych::SyntaxError => e
153
180
  puts "Cannot read config file #{e}"
154
- rescue RSMP::Schema::UnknownSchemaTypeError => e
155
- puts "Cannot start supervisor: #{e}"
156
- rescue RSMP::Schema::UnknownSchemaVersionError => e
157
- puts "Cannot start supervisor: #{e}"
158
- rescue RSMP::ConfigurationError => e
181
+ rescue RSMP::Schema::UnknownSchemaTypeError, RSMP::Schema::UnknownSchemaVersionError,
182
+ RSMP::ConfigurationError => e
159
183
  puts "Cannot start supervisor: #{e}"
160
184
  end
161
- rescue Interrupt
162
- # ctrl-c
163
185
  end
164
186
 
165
- desc "convert", "Convert SXL from YAML to JSON Schema"
166
- method_option :in, :type => :string, :aliases => "-i", banner: 'Path to YAML input file'
167
- method_option :out, :type => :string, :aliases => "-o", banner: 'Path to JSON Schema output file'
168
- def convert
187
+ def validate_convert_options
169
188
  unless options[:in]
170
- puts "Error: Input option missing"
189
+ puts 'Error: Input option missing'
171
190
  exit
172
191
  end
173
192
 
174
- unless options[:out]
175
- puts "Error: Output option missing"
176
- exit
177
- end
193
+ return if options[:out]
178
194
 
179
- unless File.exist? options[:in]
180
- puts "Error: Input path file #{options[:in]} not found"
181
- exit
182
- end
195
+ puts 'Error: Output option missing'
196
+ exit
197
+ end
198
+
199
+ def validate_input_file_exists
200
+ return if File.exist? options[:in]
201
+
202
+ puts "Error: Input path file #{options[:in]} not found"
203
+ exit
204
+ end
183
205
 
206
+ def perform_conversion
184
207
  sxl = RSMP::Convert::Import::YAML.read options[:in]
185
208
  RSMP::Convert::Export::JSONSchema.write sxl, options[:out]
186
209
  end
@@ -190,5 +213,6 @@ module RSMP
190
213
  def self.exit_on_failure?
191
214
  true
192
215
  end
216
+ private_class_method :exit_on_failure?
193
217
  end
194
- end
218
+ end
@@ -1,18 +1,19 @@
1
1
  module RSMP
2
2
  # Class for waiting for a message acknowledgement
3
3
  class AckCollector < Collector
4
- def initialize proxy, options={}
5
- raise ArgumentError.new("m_id must be provided") unless options[:m_id]
6
- super proxy, options.merge(
4
+ def initialize(proxy, options = {})
5
+ raise ArgumentError, 'm_id must be provided' unless options[:m_id]
6
+
7
+ super(proxy, options.merge(
7
8
  filter: RSMP::Filter.new(ingoing: true, outgoing: false, type: 'MessageAck'),
8
9
  num: 1,
9
10
  title: 'message acknowledgement'
10
- )
11
+ ))
11
12
  end
12
13
 
13
14
  # Check if we the MessageAck related to initiating request, identified by @m_id.
14
- def acceptable? message
15
- super(message) && message.attribute('oMId') == @m_id
15
+ def acceptable?(message)
16
+ super && message.attribute('oMId') == @m_id
16
17
  end
17
18
  end
18
- end
19
+ end
@@ -1,11 +1,11 @@
1
1
  module RSMP
2
2
  # Class for waiting for an aggregated status response
3
3
  class AggregatedStatusCollector < Collector
4
- def initialize proxy, options={}
5
- super proxy, options.merge(
4
+ def initialize(proxy, options = {})
5
+ super(proxy, options.merge(
6
6
  filter: RSMP::Filter.new(ingoing: true, outgoing: false, type: 'AggregatedStatus'),
7
7
  title: 'aggregated status'
8
- )
8
+ ))
9
9
  end
10
10
  end
11
- end
11
+ end
@@ -1,20 +1,26 @@
1
1
  module RSMP
2
2
  # Class for waiting for specific command responses
3
3
  class AlarmCollector < Collector
4
- def initialize proxy,options={}
4
+ def initialize(proxy, options = {})
5
5
  @matcher = options[:matcher] || {}
6
- super proxy, options.merge(
6
+ super(proxy, options.merge(
7
7
  filter: RSMP::Filter.new(ingoing: true, outgoing: false, type: 'Alarm'),
8
- title:'alarm'
9
- )
8
+ title: 'alarm'
9
+ ))
10
10
  end
11
11
 
12
- # match alarm attributes
13
- def acceptable? message
14
- return false if super(message) == false
12
+ def acceptable?(message)
13
+ return false if super == false
14
+ return false unless fixed_attributes_match?(message)
15
+ return false unless rvs_attributes_match?(message)
15
16
 
16
- # match fixed attributes
17
- %w{cId aCId aSp ack aS sS cat pri}.each do |key|
17
+ true
18
+ end
19
+
20
+ private
21
+
22
+ def fixed_attributes_match?(message)
23
+ %w[cId aCId aSp ack aS sS cat pri].each do |key|
18
24
  want = @matcher[key]
19
25
  got = message.attribute(key)
20
26
  case want
@@ -24,26 +30,28 @@ module RSMP
24
30
  return false if got != want
25
31
  end
26
32
  end
33
+ true
34
+ end
27
35
 
28
- # match rvs items
29
- if @matcher['rvs']
30
- matcher_rvs = @matcher['rvs']
31
- message_rvs = message.attributes['rvs']
32
- return false unless message_rvs
33
- return false unless matcher_rvs.all? do |matcher_item|
34
- return false unless message_rvs.any? do |message_item|
35
- next message_item['n'] == matcher_item['n'] && message_item['v'] == matcher_item['v']
36
- end
37
- next true
36
+ def rvs_attributes_match?(message)
37
+ return true unless @matcher['rvs']
38
+
39
+ matcher_rvs = @matcher['rvs']
40
+ message_rvs = message.attributes['rvs']
41
+ return false unless message_rvs
42
+
43
+ matcher_rvs.all? do |matcher_item|
44
+ message_rvs.any? do |message_item|
45
+ message_item['n'] == matcher_item['n'] && message_item['v'] == matcher_item['v']
38
46
  end
39
47
  end
40
- true
41
48
  end
42
49
 
50
+ public
51
+
43
52
  # return a string that describes what we're collecting
44
53
  def describe_matcher
45
- "#{describe_num_and_type} #{ {component: @options[:component]}.merge(@matcher).compact }"
54
+ "#{describe_num_and_type} #{{ component: @options[:component] }.merge(@matcher).compact}"
46
55
  end
47
-
48
56
  end
49
- end
57
+ end
@@ -1,15 +1,15 @@
1
1
  module RSMP
2
2
  # Match a specific alarm
3
3
  class AlarmMatcher < Matcher
4
- # Match an alarm value against a matcher
5
- def match? item
6
- return false if @want['n'] && @want['n'] != item['n']
4
+ def match(item)
5
+ return nil if @want['n'] && @want['n'] != item['n']
6
+
7
7
  if @want['v'].is_a? Regexp
8
- return false if item['v'] !~ @want['v']
8
+ return nil if item['v'] !~ @want['v']
9
9
  elsif @want['v']
10
- return false if item['v'] != @want['v']
10
+ return nil if item['v'] != @want['v']
11
11
  end
12
12
  true
13
13
  end
14
14
  end
15
- end
15
+ end
@@ -0,0 +1,18 @@
1
+ module RSMP
2
+ class Collector
3
+ # Logging helpers for Collector instances.
4
+ module Logging
5
+ def log_start
6
+ @distributor.log "#{identifier}: Waiting for #{describe_matcher}".strip, level: :collect
7
+ end
8
+
9
+ def log_incomplete
10
+ @distributor.log "#{identifier}: #{describe_progress}", level: :collect
11
+ end
12
+
13
+ def log_complete
14
+ @distributor.log "#{identifier}: Done", level: :collect
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,44 @@
1
+ module RSMP
2
+ class Collector
3
+ # Progress reporting and description methods for collectors
4
+ module Reporting
5
+ # return a string describing the types of messages we're collecting
6
+ def describe_types
7
+ [@filter&.type].flatten.join('/')
8
+ end
9
+
10
+ # return a string that describes whe number of messages, and type of message we're collecting
11
+ def describe_num_and_type
12
+ if @num && @num > 1
13
+ "#{@num} #{describe_types}s"
14
+ else
15
+ describe_types
16
+ end
17
+ end
18
+
19
+ # return a string that describes the attributes that we're looking for
20
+ def describe_matcher
21
+ h = { component: @filter&.component }.compact
22
+ if h.empty?
23
+ describe_num_and_type
24
+ else
25
+ "#{describe_num_and_type} #{h}"
26
+ end
27
+ end
28
+
29
+ # Build a string describing how far progress reached before timeout
30
+ def describe_progress
31
+ str = "#{@title.capitalize} #{identifier} "
32
+ str << "in response to #{@m_id} " if @m_id
33
+ str << "timed out after #{@timeout}s, "
34
+ str << "reaching #{@messages.size}/#{@num}"
35
+ str
36
+ end
37
+
38
+ # get a short id in hex format, identifying ourself
39
+ def identifier
40
+ "Collect #{object_id.to_s(16)}"
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,34 @@
1
+ module RSMP
2
+ class Collector
3
+ # Status predicate methods for collectors
4
+ module Status
5
+ def collecting?
6
+ @status == :collecting
7
+ end
8
+
9
+ def ok?
10
+ @status == :ok
11
+ end
12
+
13
+ def timeout?
14
+ @status == :timeout
15
+ end
16
+
17
+ def ready?
18
+ @status == :ready
19
+ end
20
+
21
+ def cancelled?
22
+ @status == :cancelled
23
+ end
24
+
25
+ def ingoing?
26
+ @ingoing == true
27
+ end
28
+
29
+ def outgoing?
30
+ @outgoing == true
31
+ end
32
+ end
33
+ end
34
+ end