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/message.rb CHANGED
@@ -2,72 +2,68 @@ require 'rsmp_schema'
2
2
 
3
3
  # rsmp messages
4
4
  module RSMP
5
+ # Base RSMP message class used to represent parsed and built messages.
5
6
  class Message
6
7
  include Inspect
7
8
 
8
- attr_reader :now, :attributes, :out
9
- attr_reader :timestamp # this is an internal timestamp recording when we receive/send
9
+ attr_reader :now, :attributes, :out, :timestamp # this is an internal timestamp recording when we receive/send
10
10
  attr_accessor :json, :direction
11
11
 
12
12
  def self.make_m_id
13
- SecureRandom.uuid()
13
+ SecureRandom.uuid
14
14
  end
15
15
 
16
- def self.parse_attributes json
16
+ def self.parse_attributes(json)
17
17
  raise ArgumentError unless json
18
+
18
19
  JSON.parse json
19
20
  rescue JSON::ParserError
20
21
  raise InvalidPacket, bin_to_chars(json)
21
22
  end
22
23
 
23
- def self.build attributes, json
24
+ def self.build(attributes, json)
24
25
  validate_message_type attributes
25
- case attributes["type"]
26
- when "MessageAck"
27
- message = MessageAck.new attributes
28
- when "MessageNotAck"
29
- message = MessageNotAck.new attributes
30
- when "Version"
31
- message = Version.new attributes
32
- when "AggregatedStatus"
33
- message = AggregatedStatus.new attributes
34
- when "AggregatedStatusRequest"
35
- message = AggregatedStatusRequest.new attributes
36
- when "Watchdog"
37
- message = Watchdog.new attributes
38
- when "Alarm"
39
- message = self.build_alarm attributes
40
- when "CommandRequest"
41
- message = CommandRequest.new attributes
42
- when "CommandResponse"
43
- message = CommandResponse.new attributes
44
- when "StatusRequest"
45
- message = StatusRequest.new attributes
46
- when "StatusResponse"
47
- message = StatusResponse.new attributes
48
- when "StatusSubscribe"
49
- message = StatusSubscribe.new attributes
50
- when "StatusUnsubscribe"
51
- message = StatusUnsubscribe.new attributes
52
- when "StatusUpdate"
53
- message = StatusUpdate.new attributes
54
- else
55
- message = Unknown.new attributes
56
- end
26
+ message = create_message_instance(attributes)
57
27
  message.json = json
58
28
  message.direction = :in
59
29
  message
60
30
  end
61
31
 
62
- def self.build_alarm attributes
63
- case attributes["aSp"]
32
+ def self.message_types
33
+ {
34
+ 'MessageAck' => MessageAck,
35
+ 'MessageNotAck' => MessageNotAck,
36
+ 'Version' => Version,
37
+ 'AggregatedStatus' => AggregatedStatus,
38
+ 'AggregatedStatusRequest' => AggregatedStatusRequest,
39
+ 'Watchdog' => Watchdog,
40
+ 'CommandRequest' => CommandRequest,
41
+ 'CommandResponse' => CommandResponse,
42
+ 'StatusRequest' => StatusRequest,
43
+ 'StatusResponse' => StatusResponse,
44
+ 'StatusSubscribe' => StatusSubscribe,
45
+ 'StatusUnsubscribe' => StatusUnsubscribe,
46
+ 'StatusUpdate' => StatusUpdate
47
+ }
48
+ end
49
+
50
+ def self.create_message_instance(attributes)
51
+ type = attributes['type']
52
+ return build_alarm(attributes) if type == 'Alarm'
53
+
54
+ klass = message_types[type] || Unknown
55
+ klass.new(attributes)
56
+ end
57
+
58
+ def self.build_alarm(attributes)
59
+ case attributes['aSp']
64
60
  when /^Issue$/i
65
61
  AlarmIssue.new attributes
66
62
  when /^Request$/i
67
63
  AlarmRequest.new attributes
68
64
  when /^Acknowledge$/i
69
65
  if attributes['ack'] =~ /^acknowledged$/i
70
- AlarmAcknowledged.new attributes
66
+ AlarmAcknowledged.new attributes
71
67
  else
72
68
  AlarmAcknowledge.new attributes
73
69
  end
@@ -87,84 +83,97 @@ module RSMP
87
83
  end
88
84
 
89
85
  def type
90
- @attributes["type"]
86
+ @attributes['type']
91
87
  end
92
88
 
93
89
  def m_id
94
- @attributes["mId"]
90
+ @attributes['mId']
95
91
  end
96
92
 
97
- def self.shorten_m_id m_id, length=4
98
- m_id[0..length-1]
93
+ def self.shorten_m_id(m_id, length = 4)
94
+ m_id[0..(length - 1)]
99
95
  end
100
96
 
101
97
  def m_id_short
102
- Message.shorten_m_id @attributes["mId"]
98
+ Message.shorten_m_id @attributes['mId']
103
99
  end
104
100
 
105
- def attribute key
106
- unless @attributes.key? key # note that this is not the same as @attributes[key] when
107
- maybe = @attributes.find { |k,v| k.downcase == key.downcase }
108
- if maybe
109
- raise MissingAttribute.new "attribute '#{maybe.first}' should be named '#{key}'"
110
- else
111
- raise MissingAttribute.new "missing attribute '#{key}'"
112
- end
101
+ def attribute(key)
102
+ unless @attributes.key? key # NOTE: that this is not the same as @attributes[key] when
103
+ maybe = @attributes.find { |k, _v| k.downcase == key.downcase }
104
+ raise MissingAttribute, "attribute '#{maybe.first}' should be named '#{key}'" if maybe
105
+
106
+ raise MissingAttribute, "missing attribute '#{key}'"
107
+
113
108
  end
114
109
  @attributes[key]
115
110
  end
116
111
 
117
- def self.bin_to_chars(s)
118
- out = s.gsub(/[^[:print:]]/i, '.')
112
+ def self.bin_to_chars(str)
113
+ out = str.gsub(/[^[:print:]]/i, '.')
119
114
  max = 120
120
115
  if out.size <= max
121
116
  out
122
117
  else
123
- mid = " ... "
124
- length = (max-mid.size)/2 - 1
125
- "#{out[0..length]} ... #{out[-length-1..-1]}"
118
+ mid = ' ... '
119
+ length = ((max - mid.size) / 2) - 1
120
+ "#{out[0..length]} ... #{out[(-length - 1)..]}"
126
121
  end
127
122
  end
128
123
 
129
- def self.validate_message_type attributes
130
- raise MalformedMessage.new("JSON must be a Hash, got #{attributes.class} ") unless attributes.is_a?(Hash)
131
- raise MalformedMessage.new("'mType' is missing") unless attributes["mType"]
132
- raise MalformedMessage.new("'mType' must be a String, got #{attributes["mType"].class}") unless attributes["mType"].is_a? String
133
- raise MalformedMessage.new("'mType' must be 'rSMsg', got '#{attributes["mType"]}'") unless attributes["mType"] == "rSMsg"
134
- raise MalformedMessage.new("'type' is missing") unless attributes["type"]
135
- raise MalformedMessage.new("'type' must be a String, got #{attributes["type"].class}") unless attributes["type"].is_a? String
124
+ def self.validate_message_type(attributes)
125
+ validate_attributes_structure(attributes)
126
+ validate_mtype_field(attributes)
127
+ validate_type_field(attributes)
136
128
  end
137
129
 
138
- def initialize attributes = {}
139
- @timestamp = Time.now # this timestamp is for internal use, and does not use the clock
140
- # in the node, which can be set by an rsmp supervisor
130
+ def self.validate_attributes_structure(attributes)
131
+ raise MalformedMessage, "JSON must be a Hash, got #{attributes.class} " unless attributes.is_a?(Hash)
132
+ end
141
133
 
142
- @attributes = { "mType"=> "rSMsg" }.merge attributes
134
+ def self.validate_mtype_field(attributes)
135
+ mtype = attributes['mType']
136
+ raise MalformedMessage, "'mType' is missing" unless mtype
137
+ raise MalformedMessage, "'mType' must be a String, got #{mtype.class}" unless mtype.is_a?(String)
138
+ raise MalformedMessage, "'mType' must be 'rSMsg', got '#{mtype}'" unless mtype == 'rSMsg'
139
+ end
140
+
141
+ def self.validate_type_field(attributes)
142
+ type = attributes['type']
143
+ raise MalformedMessage, "'type' is missing" unless type
144
+ raise MalformedMessage, "'type' must be a String, got #{type.class}" unless type.is_a?(String)
145
+ end
146
+
147
+ def initialize(attributes = {})
148
+ @timestamp = Time.now # this timestamp is for internal use, and does not use the clock
149
+ # in the node, which can be set by an rsmp supervisor
150
+
151
+ @attributes = { 'mType' => 'rSMsg' }.merge attributes
143
152
 
144
153
  ensure_message_id
145
154
  end
146
155
 
147
156
  def ensure_message_id
148
157
  # if message id is empty, generate a new one
149
- @attributes["mId"] ||= Message.make_m_id
158
+ @attributes['mId'] ||= Message.make_m_id
150
159
  end
151
160
 
152
- def validate schemas
161
+ def validate(schemas)
153
162
  errors = RSMP::Schema.validate attributes, schemas
154
- if errors
155
- error_string = errors.map {|item| item.reject {|e| e=='' } }.compact.join(', ').strip
156
- err = SchemaError.new "#{error_string}"
157
- err.schemas = schemas
158
- raise err
159
- end
163
+ return unless errors
164
+
165
+ error_string = errors.map { |item| item.reject { |e| e == '' } }.compact.join(', ').strip
166
+ err = SchemaError.new error_string.to_s
167
+ err.schemas = schemas
168
+ raise err
160
169
  end
161
170
 
162
- def validate_type
163
- @attributes["mType"] == "rSMsg"
171
+ def validate_type?
172
+ @attributes['mType'] == 'rSMsg'
164
173
  end
165
174
 
166
- def validate_id
167
- (@attributes["mId"] =~ /[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}/i) != nil
175
+ def validate_id?
176
+ !(@attributes['mId'] =~ /[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}/i).nil?
168
177
  end
169
178
 
170
179
  def valid?
@@ -181,165 +190,186 @@ module RSMP
181
190
  }
182
191
  @json = JSON.generate @attributes, options
183
192
  end
184
-
185
193
  end
186
194
 
195
+ # Represents a malformed message with invalid attributes.
187
196
  class Malformed < Message
188
- def initialize attributes = {}
197
+ # rubocop:disable Lint/MissingSuper
198
+ def initialize(attributes = {})
189
199
  # don't call super, just copy (potentially invalid) attributes
190
200
  @attributes = {}
191
201
  @invalid_attributes = attributes
192
202
  end
203
+ # rubocop:enable Lint/MissingSuper
193
204
  end
194
205
 
206
+ # Version message, lists supported versions and SXL information.
195
207
  class Version < Message
196
- def initialize attributes = {}
208
+ def initialize(attributes = {})
197
209
  super({
198
- "type" => "Version",
210
+ 'type' => 'Version'
199
211
  }.merge attributes)
200
212
  end
201
213
 
202
214
  def versions
203
- attribute("RSMP").map{ |item| item["vers"] }
215
+ attribute('RSMP').map { |item| item['vers'] }
204
216
  end
205
217
  end
206
218
 
219
+ # Unknown message type wrapper.
207
220
  class Unknown < Message
208
221
  end
209
222
 
223
+ # AggregatedStatus message type.
210
224
  class AggregatedStatus < Message
211
- def initialize attributes = {}
225
+ def initialize(attributes = {})
212
226
  super({
213
- "type" => "AggregatedStatus",
227
+ 'type' => 'AggregatedStatus'
214
228
  }.merge attributes)
215
229
  end
216
230
  end
217
231
 
232
+ # AggregatedStatusRequest message type.
218
233
  class AggregatedStatusRequest < Message
219
- def initialize attributes = {}
234
+ def initialize(attributes = {})
220
235
  super({
221
- "type" => "AggregatedStatusRequest",
236
+ 'type' => 'AggregatedStatusRequest'
222
237
  }.merge attributes)
223
238
  end
224
239
  end
225
240
 
241
+ # Alarm base message type.
226
242
  class Alarm < Message
227
- def initialize attributes = {}
243
+ def initialize(attributes = {})
228
244
  super({
229
- "type" => "Alarm",
230
- "ntsOId" => '',
231
- "xNId" => '',
232
- "xACId" => '',
233
- "xNACId" => ''
245
+ 'type' => 'Alarm',
246
+ 'ntsOId' => '',
247
+ 'xNId' => '',
248
+ 'xACId' => '',
249
+ 'xNACId' => ''
234
250
  }.merge attributes)
235
251
  end
236
252
 
237
- def differ? from
238
- %w{aSp aCId ack aS sS aTs cat pri}.each do |key|
253
+ def differ?(from)
254
+ %w[aSp aCId ack aS sS aTs cat pri].each do |key|
239
255
  return true if attribute(key).downcase != from.attribute(key).downcase
240
256
  end
241
257
  return true if attribute('rvs') != from.attribute('rvs')
258
+
242
259
  false
243
260
  end
244
261
  end
245
262
 
263
+ # Alarm issue specialization.
246
264
  class AlarmIssue < Alarm
247
- def initialize attributes = {}
265
+ def initialize(attributes = {})
248
266
  super({
249
- "aSp" => "Issue"
267
+ 'aSp' => 'Issue'
250
268
  }.merge attributes)
251
269
  end
252
270
  end
253
271
 
272
+ # Alarm request specialization.
254
273
  class AlarmRequest < Alarm
255
- def initialize attributes = {}
274
+ def initialize(attributes = {})
256
275
  super({
257
- "aSp" => "Request",
276
+ 'aSp' => 'Request'
258
277
  }.merge attributes)
259
278
  end
260
279
  end
261
280
 
281
+ # Alarm acknowledge message.
262
282
  class AlarmAcknowledge < Alarm
263
- def initialize attributes = {}
283
+ def initialize(attributes = {})
264
284
  super({
265
- "aSp" => "Acknowledge",
285
+ 'aSp' => 'Acknowledge'
266
286
  }.merge attributes)
267
287
  end
268
288
  end
269
289
 
290
+ # Alarm acknowledged (acknowledged state) message.
270
291
  class AlarmAcknowledged < Alarm
271
- def initialize attributes = {}
292
+ def initialize(attributes = {})
272
293
  super({
273
- "aSp" => "Acknowledge",
274
- "ack" => "acknowledged"
294
+ 'aSp' => 'Acknowledge',
295
+ 'ack' => 'acknowledged'
275
296
  }.merge attributes)
276
297
  end
277
298
  end
299
+
300
+ # Alarm suspend message.
278
301
  class AlarmSuspend < Alarm
279
- def initialize attributes = {}
302
+ def initialize(attributes = {})
280
303
  super({
281
- "aSp" => "Suspend",
304
+ 'aSp' => 'Suspend'
282
305
  }.merge attributes)
283
306
  end
284
307
  end
285
308
 
309
+ # Alarm suspended (suspended state) message.
286
310
  class AlarmSuspended < Alarm
287
- def initialize attributes = {}
311
+ def initialize(attributes = {})
288
312
  super({
289
- "aSp" => "Suspend",
290
- "sS" => "Suspended"
313
+ 'aSp' => 'Suspend',
314
+ 'sS' => 'Suspended'
291
315
  }.merge attributes)
292
316
  end
293
317
  end
294
318
 
319
+ # Alarm resume message.
295
320
  class AlarmResume < Alarm
296
- def initialize attributes = {}
321
+ def initialize(attributes = {})
297
322
  super({
298
- "aSp" => "Resume",
323
+ 'aSp' => 'Resume'
299
324
  }.merge attributes)
300
325
  end
301
326
  end
302
327
 
328
+ # Alarm resumed (not suspended) message.
303
329
  class AlarmResumed < Alarm
304
- def initialize attributes = {}
330
+ def initialize(attributes = {})
305
331
  super({
306
- "aSp" => "Suspend",
307
- "sS" => "notSuspended"
332
+ 'aSp' => 'Suspend',
333
+ 'sS' => 'notSuspended'
308
334
  }.merge attributes)
309
335
  end
310
336
  end
311
337
 
338
+ # Watchdog message type.
312
339
  class Watchdog < Message
313
- def initialize attributes = {}
340
+ def initialize(attributes = {})
314
341
  super({
315
- "type" => "Watchdog",
342
+ 'type' => 'Watchdog'
316
343
  }.merge attributes)
317
344
  end
318
345
  end
319
346
 
347
+ # Base class for acking messages (MessageAck / MessageNotAck).
320
348
  class MessageAcking < Message
321
349
  attr_reader :original
322
350
 
323
- def self.build_from message
324
- return new({
325
- "oMId" => message.attributes["mId"]
326
- })
351
+ def self.build_from(message)
352
+ new({
353
+ 'oMId' => message.attributes['mId']
354
+ })
327
355
  end
328
356
 
329
- def original= message
357
+ def original=(message)
330
358
  raise InvalidArgument unless message
359
+
331
360
  @original = message
332
361
  end
333
362
 
334
- def validate_id
363
+ def validate_id?
335
364
  true
336
365
  end
337
366
  end
338
367
 
368
+ # Acknowledgement for a received message.
339
369
  class MessageAck < MessageAcking
340
- def initialize attributes = {}
370
+ def initialize(attributes = {})
341
371
  super({
342
- "type" => "MessageAck",
372
+ 'type' => 'MessageAck'
343
373
  }.merge attributes)
344
374
  end
345
375
 
@@ -348,70 +378,77 @@ module RSMP
348
378
  end
349
379
  end
350
380
 
381
+ # Negative acknowledgement for a received message.
351
382
  class MessageNotAck < MessageAcking
352
- def initialize attributes = {}
383
+ def initialize(attributes = {})
353
384
  super({
354
- "type" => "MessageNotAck",
355
- "rea" => "Unknown reason"
385
+ 'type' => 'MessageNotAck',
386
+ 'rea' => 'Unknown reason'
356
387
  }.merge attributes)
357
- @attributes.delete "mId"
358
- end
388
+ @attributes.delete 'mId'
389
+ end
359
390
  end
360
391
 
392
+ # Command request message type.
361
393
  class CommandRequest < Message
362
- def initialize attributes = {}
394
+ def initialize(attributes = {})
363
395
  super({
364
- "type" => "CommandRequest",
396
+ 'type' => 'CommandRequest'
365
397
  }.merge attributes)
366
398
  end
367
399
  end
368
400
 
401
+ # Command response message type.
369
402
  class CommandResponse < Message
370
- def initialize attributes = {}
403
+ def initialize(attributes = {})
371
404
  super({
372
- "type" => "CommandResponse",
405
+ 'type' => 'CommandResponse'
373
406
  }.merge attributes)
374
407
  end
375
408
  end
376
409
 
410
+ # Status request message type.
377
411
  class StatusRequest < Message
378
- def initialize attributes = {}
412
+ def initialize(attributes = {})
379
413
  super({
380
- "type" => "StatusRequest",
414
+ 'type' => 'StatusRequest'
381
415
  }.merge attributes)
382
416
  end
383
417
  end
384
418
 
419
+ # Status response message type.
385
420
  class StatusResponse < Message
386
- def initialize attributes = {}
421
+ def initialize(attributes = {})
387
422
  super({
388
- "type" => "StatusResponse",
423
+ 'type' => 'StatusResponse'
389
424
  }.merge attributes)
390
425
  end
391
426
  end
392
427
 
428
+ # Status subscribe message type.
393
429
  class StatusSubscribe < Message
394
- def initialize attributes = {}
430
+ def initialize(attributes = {})
395
431
  super({
396
- "type" => "StatusSubscribe",
432
+ 'type' => 'StatusSubscribe'
397
433
  }.merge attributes)
398
434
  end
399
435
  end
400
436
 
437
+ # Status unsubscribe message type.
401
438
  class StatusUnsubscribe < Message
402
- def initialize attributes = {}
439
+ def initialize(attributes = {})
403
440
  super({
404
- "type" => "StatusUnsubscribe",
441
+ 'type' => 'StatusUnsubscribe'
405
442
  }.merge attributes)
406
443
  end
407
444
  end
408
445
 
446
+ # Status update message type.
409
447
  class StatusUpdate < Message
410
- def initialize attributes = {}
448
+ def initialize(attributes = {})
411
449
  super({
412
- "type" => "StatusUpdate",
450
+ 'type' => 'StatusUpdate'
413
451
  }.merge attributes)
414
452
  end
415
453
  end
416
-
417
- end
454
+ end
@@ -1,6 +1,5 @@
1
- # Base class for sites and supervisors
2
-
3
1
  module RSMP
2
+ # Base class for sites and supervisors.
4
3
  class Node
5
4
  include Logging
6
5
  include Inspect
@@ -8,7 +7,7 @@ module RSMP
8
7
 
9
8
  attr_reader :archive, :logger, :task, :deferred, :error_queue, :clock, :collector
10
9
 
11
- def initialize options={}
10
+ def initialize(options = {})
12
11
  initialize_logging options
13
12
  initialize_task
14
13
  @deferred = []
@@ -24,55 +23,57 @@ module RSMP
24
23
 
25
24
  # stop proxies, then call super
26
25
  def stop_subtasks
27
- @proxies.each { |proxy| proxy.stop }
26
+ @proxies.each(&:stop)
28
27
  @proxies.clear
29
28
  super
30
29
  end
31
30
 
32
- def ignore_errors classes, &block
33
- was, @ignore_errors = @ignore_errors, [classes].flatten
31
+ def ignore_errors(classes)
32
+ was = @ignore_errors
33
+ @ignore_errors = [classes].flatten
34
34
  yield
35
35
  ensure
36
36
  @ignore_errors = was
37
37
  end
38
38
 
39
- def distribute_error e, options={}
40
- return if @ignore_errors.find { |klass| e.is_a? klass }
39
+ def distribute_error(error, options = {})
40
+ return if @ignore_errors.find { |klass| error.is_a? klass }
41
+
41
42
  if options[:level] == :internal
42
- log ["#{e.to_s} in task: #{Async::Task.current.to_s}",e.backtrace].flatten.join("\n"), level: :error
43
+ log ["#{error} in task: #{Async::Task.current}", error.backtrace].flatten.join("\n"),
44
+ level: :error
43
45
  end
44
- @error_queue.enqueue e
46
+ @error_queue.enqueue error
45
47
  end
46
48
 
47
- def defer key, item=nil
49
+ def defer(key, item = nil)
48
50
  @deferred << [key, item]
49
51
  end
50
52
 
51
53
  def process_deferred
52
- cloned = @deferred.clone # clone in case do_deferred restarts the current task
54
+ cloned = @deferred.clone # clone in case do_deferred restarts the current task
53
55
  @deferred.clear
54
56
  cloned.each do |pair|
55
57
  do_deferred pair.first, pair.last
56
58
  end
57
59
  end
58
60
 
59
- def do_deferred key,item=nil
60
- end
61
+ def do_deferred(key, item = nil); end
61
62
 
62
63
  def clear_deferred
63
64
  @deferred.clear
64
65
  end
65
66
 
66
- def check_required_settings settings, required
67
- raise ArgumentError.new "Settings is empty" unless settings
67
+ def check_required_settings(settings, required)
68
+ raise ArgumentError, 'Settings is empty' unless settings
69
+
68
70
  required.each do |setting|
69
- raise ArgumentError.new "Missing setting: #{setting}" unless settings.include? setting.to_s
71
+ raise ArgumentError, "Missing setting: #{setting}" unless settings.include? setting.to_s
70
72
  end
71
73
  end
72
74
 
73
75
  def author
74
76
  site_id
75
77
  end
76
-
77
78
  end
78
- end
79
+ end