rsmp 0.1.40 → 0.2.3

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: d1feaa7fd1863a9783573d2f8c2c025f06ba53de97a441bd7f8b5da164c813cd
4
- data.tar.gz: e34aea14d3949b54d9ed9db3dcc8495cf3d5db8761f77e74b6c162bcf86468d6
3
+ metadata.gz: a57d963e9f3f6f4dccdfbfaf7bc2d4c09fcbae56d1ec886ed699faa373e054ed
4
+ data.tar.gz: 4035d49f738d335f94d4df8c9dd33a3744d258740e51df55be9da5998ce3e538
5
5
  SHA512:
6
- metadata.gz: 7da97ae66c060644d623f49dc7b8702110ce54a6fd4bfadac56cc74945430612a7a8c5269e98174a17aeedfd83a7551b3eecc9e151f5aea1cff53a88eb43c5c5
7
- data.tar.gz: 4d51c29847821378a1e34f2e34f6f5fe779053c18022927ac3041f51b235db55303f45658f7f10ea017f9021bbf1665ebe8383e491e0f9b98017f1c8da7a4dca
6
+ metadata.gz: 94e7df5ad072745c960726053e0630b8b9efefc87c746a0f96afb53c32c4ff7450a553d3576a9ad9cd430640355e8ff329862cb4fd24da8338780e500f3c0245
7
+ data.tar.gz: 70b0a93eb41dca5cfabe62cacfb08f675fe2f359886bc4038aa647a95d873553b04056277ee08bac16476c441c7b6f646300179567fe2b33f58aa83121456b37
data/Gemfile.lock CHANGED
@@ -1,9 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rsmp (0.1.40)
5
- async (~> 1.28.7)
6
- async-io (~> 1.30.2)
4
+ rsmp (0.2.3)
5
+ async (~> 1.29.1)
6
+ async-io (~> 1.32.1)
7
7
  colorize (~> 0.8.1)
8
8
  rsmp_schemer
9
9
  thor (~> 1.0.1)
@@ -11,91 +11,129 @@ PATH
11
11
  GEM
12
12
  remote: https://rubygems.org/
13
13
  specs:
14
- aruba (1.0.0)
15
- childprocess (~> 3.0)
16
- contracts (~> 0.16.0)
17
- cucumber (>= 2.4, < 4.0)
18
- ffi (~> 1.9)
14
+ activesupport (6.1.4)
15
+ concurrent-ruby (~> 1.0, >= 1.0.2)
16
+ i18n (>= 1.6, < 2)
17
+ minitest (>= 5.1)
18
+ tzinfo (~> 2.0)
19
+ zeitwerk (~> 2.3)
20
+ aruba (1.1.2)
21
+ bundler (>= 1.17, < 3.0)
22
+ childprocess (>= 2.0, < 5.0)
23
+ contracts (>= 0.16.0, < 0.18.0)
24
+ cucumber (>= 2.4, < 7.0)
19
25
  rspec-expectations (~> 3.4)
20
26
  thor (~> 1.0)
21
- async (1.28.9)
27
+ async (1.29.2)
22
28
  console (~> 1.10)
23
29
  nio4r (~> 2.3)
24
30
  timers (~> 4.1)
25
- async-io (1.30.2)
26
- async (~> 1.14)
27
- backports (3.17.0)
31
+ async-io (1.32.2)
32
+ async
28
33
  builder (3.2.4)
29
- childprocess (3.0.0)
34
+ childprocess (4.1.0)
30
35
  colorize (0.8.1)
36
+ concurrent-ruby (1.1.9)
31
37
  console (1.13.1)
32
38
  fiber-local
33
- contracts (0.16.0)
34
- cucumber (3.1.2)
35
- builder (>= 2.1.2)
36
- cucumber-core (~> 3.2.0)
37
- cucumber-expressions (~> 6.0.1)
38
- cucumber-wire (~> 0.0.1)
39
- diff-lcs (~> 1.3)
40
- gherkin (~> 5.1.0)
41
- multi_json (>= 1.7.5, < 2.0)
42
- multi_test (>= 0.1.2)
43
- cucumber-core (3.2.1)
44
- backports (>= 3.8.0)
45
- cucumber-tag_expressions (~> 1.1.0)
46
- gherkin (~> 5.0)
47
- cucumber-expressions (6.0.1)
48
- cucumber-tag_expressions (1.1.1)
49
- cucumber-wire (0.0.1)
50
- diff-lcs (1.3)
39
+ contracts (0.17)
40
+ cucumber (6.1.0)
41
+ builder (~> 3.2, >= 3.2.4)
42
+ cucumber-core (~> 9.0, >= 9.0.1)
43
+ cucumber-create-meta (~> 4.0, >= 4.0.0)
44
+ cucumber-cucumber-expressions (~> 12.1, >= 12.1.1)
45
+ cucumber-gherkin (~> 18.1, >= 18.1.0)
46
+ cucumber-html-formatter (~> 13.0, >= 13.0.0)
47
+ cucumber-messages (~> 15.0, >= 15.0.0)
48
+ cucumber-wire (~> 5.0, >= 5.0.1)
49
+ diff-lcs (~> 1.4, >= 1.4.4)
50
+ mime-types (~> 3.3, >= 3.3.1)
51
+ multi_test (~> 0.1, >= 0.1.2)
52
+ sys-uname (~> 1.2, >= 1.2.2)
53
+ cucumber-core (9.0.1)
54
+ cucumber-gherkin (~> 18.1, >= 18.1.0)
55
+ cucumber-messages (~> 15.0, >= 15.0.0)
56
+ cucumber-tag-expressions (~> 3.0, >= 3.0.1)
57
+ cucumber-create-meta (4.0.0)
58
+ cucumber-messages (~> 15.0, >= 15.0.0)
59
+ sys-uname (~> 1.2, >= 1.2.2)
60
+ cucumber-cucumber-expressions (12.1.1)
61
+ cucumber-gherkin (18.1.1)
62
+ cucumber-messages (~> 15.0, >= 15.0.0)
63
+ cucumber-html-formatter (13.0.0)
64
+ cucumber-messages (~> 15.0, >= 15.0.0)
65
+ cucumber-messages (15.0.0)
66
+ protobuf-cucumber (~> 3.10, >= 3.10.8)
67
+ cucumber-tag-expressions (3.0.1)
68
+ cucumber-wire (5.0.1)
69
+ cucumber-core (~> 9.0, >= 9.0.1)
70
+ cucumber-cucumber-expressions (~> 12.1, >= 12.1.1)
71
+ cucumber-messages (~> 15.0, >= 15.0.0)
72
+ diff-lcs (1.4.4)
51
73
  ecma-re-validator (0.3.0)
52
74
  regexp_parser (~> 2.0)
53
- ffi (1.12.2)
75
+ ffi (1.15.3)
54
76
  fiber-local (1.0.0)
55
- gherkin (5.1.0)
56
77
  hana (1.3.7)
78
+ i18n (1.8.10)
79
+ concurrent-ruby (~> 1.0)
57
80
  json_schemer (0.2.18)
58
81
  ecma-re-validator (~> 0.3)
59
82
  hana (~> 1.3)
60
83
  regexp_parser (~> 2.0)
61
84
  uri_template (~> 0.7)
62
- multi_json (1.14.1)
85
+ middleware (0.1.0)
86
+ mime-types (3.3.1)
87
+ mime-types-data (~> 3.2015)
88
+ mime-types-data (3.2021.0225)
89
+ minitest (5.14.4)
63
90
  multi_test (0.1.2)
64
- nio4r (2.5.7)
65
- rake (13.0.1)
91
+ nio4r (2.5.8)
92
+ protobuf-cucumber (3.10.8)
93
+ activesupport (>= 3.2)
94
+ middleware
95
+ thor
96
+ thread_safe
97
+ rake (13.0.3)
66
98
  regexp_parser (2.1.1)
67
99
  rsmp_schemer (0.3.1)
68
100
  json_schemer (~> 0.2.18)
69
- rspec (3.9.0)
70
- rspec-core (~> 3.9.0)
71
- rspec-expectations (~> 3.9.0)
72
- rspec-mocks (~> 3.9.0)
73
- rspec-core (3.9.1)
74
- rspec-support (~> 3.9.1)
75
- rspec-expectations (3.9.1)
101
+ rspec (3.10.0)
102
+ rspec-core (~> 3.10.0)
103
+ rspec-expectations (~> 3.10.0)
104
+ rspec-mocks (~> 3.10.0)
105
+ rspec-core (3.10.1)
106
+ rspec-support (~> 3.10.0)
107
+ rspec-expectations (3.10.1)
76
108
  diff-lcs (>= 1.2.0, < 2.0)
77
- rspec-support (~> 3.9.0)
78
- rspec-mocks (3.9.1)
109
+ rspec-support (~> 3.10.0)
110
+ rspec-mocks (3.10.2)
79
111
  diff-lcs (>= 1.2.0, < 2.0)
80
- rspec-support (~> 3.9.0)
81
- rspec-support (3.9.2)
112
+ rspec-support (~> 3.10.0)
113
+ rspec-support (3.10.2)
114
+ sys-uname (1.2.2)
115
+ ffi (~> 1.1)
82
116
  thor (1.0.1)
83
- timecop (0.9.1)
117
+ thread_safe (0.3.6)
118
+ timecop (0.9.4)
84
119
  timers (4.3.3)
120
+ tzinfo (2.0.4)
121
+ concurrent-ruby (~> 1.0)
85
122
  uri_template (0.7.0)
123
+ zeitwerk (2.4.2)
86
124
 
87
125
  PLATFORMS
88
- ruby
126
+ x86_64-darwin-20
89
127
 
90
128
  DEPENDENCIES
91
- aruba (~> 1.0.0)
92
- bundler (~> 2.2.3)
93
- cucumber (~> 3.1.2)
94
- rake (~> 13.0.1)
129
+ aruba (~> 1.1.2)
130
+ bundler (~> 2.2.21)
131
+ cucumber (~> 6.1.0)
132
+ rake (~> 13.0.3)
95
133
  rsmp!
96
- rspec (~> 3.9.0)
97
- rspec-expectations (~> 3.9.1)
98
- timecop (~> 0.9.1)
134
+ rspec (~> 3.10.0)
135
+ rspec-expectations (~> 3.10.1)
136
+ timecop (~> 0.9.4)
99
137
 
100
138
  BUNDLED WITH
101
- 2.2.3
139
+ 2.2.21
data/lib/rsmp/logger.rb CHANGED
@@ -96,7 +96,8 @@ module RSMP
96
96
  'statistics' => 'light_black',
97
97
  'not_acknowledged' => 'cyan',
98
98
  'warning' => 'light_yellow',
99
- 'error' => 'red'
99
+ 'error' => 'red',
100
+ 'debug' => 'light_black'
100
101
  }
101
102
  colors.merge! @settings["color"] if @settings["color"].is_a?(Hash)
102
103
  if colors[level.to_s]
data/lib/rsmp/node.rb CHANGED
@@ -6,21 +6,21 @@ module RSMP
6
6
  include Wait
7
7
  include Inspect
8
8
 
9
- attr_reader :archive, :logger, :task, :deferred, :error_condition, :clock
9
+ attr_reader :archive, :logger, :task, :deferred, :error_queue, :clock
10
10
 
11
11
  def initialize options
12
12
  initialize_logging options
13
13
  @task = options[:task]
14
14
  @deferred = []
15
15
  @clock = Clock.new
16
- @error_condition = Async::Notification.new
16
+ @error_queue = Async::Queue.new
17
17
  end
18
18
 
19
19
  def notify_error e, options={}
20
20
  if options[:level] == :internal
21
21
  log ["#{e.to_s} in task: #{Async::Task.current.to_s}",e.backtrace].flatten.join("\n"), level: :error
22
22
  end
23
- @error_condition.signal e
23
+ @error_queue.enqueue e
24
24
  end
25
25
 
26
26
  def defer item
data/lib/rsmp/proxy.rb CHANGED
@@ -11,22 +11,32 @@ module RSMP
11
11
  include Notifier
12
12
  include Inspect
13
13
 
14
- attr_reader :state, :archive, :connection_info, :sxl, :task, :collector
14
+ attr_reader :state, :archive, :connection_info, :sxl, :task, :collector, :ip, :port
15
15
 
16
16
  def initialize options
17
17
  initialize_logging options
18
+ setup options
19
+ initialize_distributor
20
+ prepare_collection @settings['collect']
21
+ clear
22
+ end
23
+
24
+ def revive options
25
+ setup options
26
+ end
27
+
28
+ def setup options
18
29
  @settings = options[:settings]
19
30
  @task = options[:task]
20
31
  @socket = options[:socket]
32
+ @stream = options[:stream]
33
+ @protocol = options[:protocol]
21
34
  @ip = options[:ip]
22
35
  @port = options[:port]
23
36
  @connection_info = options[:info]
24
37
  @sxl = nil
25
38
  @site_settings = nil # can't pick until we know the site id
26
- initialize_distributor
27
-
28
- prepare_collection @settings['collect']
29
- clear
39
+ @state = :stopped
30
40
  end
31
41
 
32
42
  def inspect
@@ -105,8 +115,8 @@ module RSMP
105
115
  def start_reader
106
116
  @reader = @task.async do |task|
107
117
  task.annotate "reader"
108
- @stream = Async::IO::Stream.new(@socket)
109
- @protocol = Async::IO::Protocol::Line.new(@stream,WRAPPING_DELIMITER) # rsmp messages are json terminated with a form-feed
118
+ @stream ||= Async::IO::Stream.new(@socket)
119
+ @protocol ||= Async::IO::Protocol::Line.new(@stream,WRAPPING_DELIMITER) # rsmp messages are json terminated with a form-feed
110
120
 
111
121
  while json = @protocol.read_line
112
122
  beginning = Time.now
@@ -15,6 +15,13 @@ module RSMP
15
15
  @site_id = nil
16
16
  end
17
17
 
18
+ def revive options
19
+ super options
20
+ @supervisor = options[:supervisor]
21
+ @settings = @supervisor.supervisor_settings.clone
22
+ end
23
+
24
+
18
25
  def inspect
19
26
  "#<#{self.class.name}:#{self.object_id}, #{inspector(
20
27
  :@acknowledgements,:@settings,:@site_settings,:@components
@@ -82,8 +89,12 @@ module RSMP
82
89
 
83
90
  end
84
91
 
92
+ def validate_ready action
93
+ raise NotReady.new("Can't #{action} because connection is not ready. (Currently #{@state})") unless ready?
94
+ end
95
+
85
96
  def request_aggregated_status component, options={}
86
- raise NotReady unless ready?
97
+ validate_ready 'request aggregated status'
87
98
  m_id = options[:m_id] || RSMP::Message.make_m_id
88
99
 
89
100
  message = RSMP::AggregatedStatusRequest.new({
@@ -163,7 +174,7 @@ module RSMP
163
174
  end
164
175
 
165
176
  def request_status component, status_list, options={}
166
- raise NotReady unless ready?
177
+ validate_ready 'request status'
167
178
  m_id = options[:m_id] || RSMP::Message.make_m_id
168
179
 
169
180
  # additional items can be used when verifying the response,
@@ -203,7 +214,7 @@ module RSMP
203
214
  end
204
215
 
205
216
  def subscribe_to_status component, status_list, options={}
206
- raise NotReady unless ready?
217
+ validate_ready 'subscribe to status'
207
218
  m_id = options[:m_id] || RSMP::Message.make_m_id
208
219
 
209
220
  # additional items can be used when verifying the response,
@@ -238,7 +249,7 @@ module RSMP
238
249
  end
239
250
 
240
251
  def unsubscribe_to_status component, status_list, options={}
241
- raise NotReady unless ready?
252
+ validate_ready 'unsubscribe to status'
242
253
  message = RSMP::StatusUnsubscribe.new({
243
254
  "ntsOId" => '',
244
255
  "xNId" => '',
@@ -269,7 +280,7 @@ module RSMP
269
280
  end
270
281
 
271
282
  def send_command component, command_list, options={}
272
- raise NotReady unless ready?
283
+ validate_ready 'send command'
273
284
  m_id = options[:m_id] || RSMP::Message.make_m_id
274
285
  message = RSMP::CommandRequest.new({
275
286
  "ntsOId" => '',
@@ -2,6 +2,113 @@
2
2
  module RSMP
3
3
  module SiteProxyWait
4
4
 
5
+ class Matcher
6
+ attr_reader :result, :messages
7
+
8
+ # Initialize with a list a wanted statuses
9
+ def initialize want, options={}
10
+ @want = want.clone
11
+ @result = {}
12
+ @messages = []
13
+ @m_id = options[:m_id]
14
+ end
15
+
16
+ # Check if a messages is wanted.
17
+ # Returns true when we found all that we want.
18
+ def process message
19
+ ack_status = check_not_ack message
20
+ return ack_status if ack_status != nil
21
+
22
+ add = false
23
+ @want.each_with_index do |query,i| # look through wanted
24
+ get_items(message).each do |input| # look through status items in message
25
+ matching = match? query, input
26
+ if matching == true
27
+ @result[query] = input
28
+ add = true
29
+ elsif matching == false
30
+ @result.delete query
31
+ end
32
+ end
33
+ end
34
+ @messages << message if add
35
+ @result.size == @want.size # queries left to match?
36
+ end
37
+
38
+ # Check for MessageNotAck
39
+ # If the original request identified by @m_id is rejected, we abort
40
+ def check_not_ack message
41
+ if message.is_a?(MessageNotAck)
42
+ if message.attribute('oMId') == @m_id
43
+ # Set result to an exception, but don't raise it.
44
+ # This will be returned by the async task and stored as the task result
45
+ # When the parent task call wait() on the task, the exception
46
+ # will be raised in the parent task, and caught by RSpec.
47
+ # RSpec will then show the error and record the test as failed
48
+ m_id_short = RSMP::Message.shorten_m_id @m_id, 8
49
+ @result = RSMP::MessageRejected.new("#{type_str} #{m_id_short} was rejected: #{message.attribute('rea')}")
50
+ @messages = [message]
51
+ return true
52
+ end
53
+ return false
54
+ end
55
+ end
56
+ end
57
+
58
+ class CommandResponseMatcher < RSMP::SiteProxyWait::Matcher
59
+ def initialize want, options={}
60
+ super
61
+ end
62
+
63
+ def type_str
64
+ "Command request"
65
+ end
66
+
67
+ def get_items message
68
+ message.attributes['rvs']
69
+ end
70
+
71
+ def match? query, item
72
+ return nil if query['cCI'] && query['cCI'] != item['cCI']
73
+ return nil if query['n'] && query['n'] != item['n']
74
+ if query['v'].is_a? Regexp
75
+ return false if query['v'] && item['v'] !~ query['v']
76
+ else
77
+ return false if query['v'] && item['v'] != query['v']
78
+ end
79
+ true
80
+ end
81
+ end
82
+
83
+ # Class for matching incoming messaging against a list of wanted statuses,
84
+ # and flagging when everything has been matched.
85
+ class StatusResponseMatcher < RSMP::SiteProxyWait::Matcher
86
+ def initialize want, options={}
87
+ super
88
+ end
89
+
90
+ def type_str
91
+ "Status request"
92
+ end
93
+
94
+ def get_items message
95
+ message.attributes['sS']
96
+ end
97
+
98
+ # Match an item against a query
99
+ def match? query, item
100
+ return nil if query['sCI'] && query['sCI'] != item['sCI']
101
+ return nil if query['n'] && query['n'] != item['n']
102
+ return false if query['q'] && query['q'] != item['q']
103
+ if query['s'].is_a? Regexp
104
+ return false if query['s'] && item['s'] !~ query['s']
105
+ else
106
+ return false if query['s'] && item['s'] != query['s']
107
+ end
108
+ true
109
+ end
110
+ end
111
+
5
112
  def wait_for_alarm parent_task, options={}
6
113
  matching_alarm = nil
7
114
  message = collect(parent_task,options.merge(type: "Alarm", with_message: true, num: 1)) do |message|
@@ -29,120 +136,26 @@ module RSMP
29
136
 
30
137
  def collect_command_responses parent_task, options, m_id
31
138
  task.annotate "wait for command response"
32
- want = options[:command_list].clone
33
- result = {}
34
- messages = []
35
- collect(parent_task,options.merge({
36
- type: ['CommandResponse','MessageNotAck'],
37
- num: 1
38
- })) do |message|
39
- if message.is_a?(MessageNotAck)
40
- if message.attribute('oMId') == m_id
41
- # set result to an exception, but don't raise it.
42
- # this will be returned by the task and stored as the task result
43
- # when the parent task call wait() on the task, the exception
44
- # will be raised in the parent task, and caught by rspec.
45
- # rspec will then show the error and record the test as failed
46
- m_id_short = RSMP::Message.shorten_m_id m_id, 8
47
- result = RSMP::MessageRejected.new "Command request #{m_id_short} was rejected: #{message.attribute('rea')}"
48
- next true # done, no more messages wanted
49
- else
50
- false
51
- end
52
- else
53
- add = false
54
- # look through querues
55
- want.each_with_index do |query,i|
56
- # look through items in message
57
- message.attributes['rvs'].each do |input|
58
- matching = command_match? query, input
59
- if matching == true
60
- result[query] = input
61
- add = true
62
- elsif matching == false
63
- result.delete query
64
- end
65
- end
66
- end
67
- messages << message if add
68
- result.size == want.size # any queries left to match?
69
- end
139
+ matcher = CommandResponseMatcher.new options[:command_list], m_id: m_id
140
+ collect(parent_task,options.merge(type: ['CommandResponse','MessageNotAck'], num: 1)) do |message|
141
+ matcher.process message # returns true when done (all queries matched)
70
142
  end
71
- return result, messages
143
+ return matcher.result, matcher.messages
72
144
  rescue Async::TimeoutError
73
145
  raise RSMP::TimeoutError.new "Did not receive correct command response to #{m_id} within #{options[:timeout]}s"
74
146
  end
75
147
 
76
148
  def collect_status_updates_or_responses task, type, options, m_id
77
- want = options[:status_list].clone
78
- result = {}
79
- messages = []
80
- # wait for a status update
81
- collect(task,options.merge({
82
- type: [type,'MessageNotAck'],
83
- num: 1
84
- })) do |message|
85
- if message.is_a?(MessageNotAck)
86
- if message.attribute('oMId') == m_id
87
- # set result to an exception, but don't raise it.
88
- # this will be returned by the task and stored as the task result
89
- # when the parent task call wait() on the task, the exception
90
- # will be raised in the parent task, and caught by rspec.
91
- # rspec will then show the error and record the test as failed
92
- m_id_short = RSMP::Message.shorten_m_id m_id, 8
93
- result = RSMP::MessageRejected.new "Status request #{m_id_short} was rejected: #{message.attribute('rea')}"
94
- next true # done, no more messages wanted
95
- end
96
- false
97
- else
98
- found = []
99
- add = false
100
- # look through querues
101
- want.each_with_index do |query,i|
102
- # look through status items in message
103
- message.attributes['sS'].each do |input|
104
- matching = status_match? query, input
105
- if matching == true
106
- result[query] = input
107
- add = true
108
- elsif matching == false
109
- result.delete query
110
- end
111
- end
112
- end
113
- messages << message if add
114
- result.size == want.size # any queries left to match?
115
- end
149
+ matcher = StatusResponseMatcher.new options[:status_list], m_id: m_id
150
+ collect(task,options.merge( type: [type,'MessageNotAck'], num: 1 )) do |message|
151
+ matcher.process message # returns true when done (all queries matched)
116
152
  end
117
- return result, messages
153
+ return matcher.result, matcher.messages
118
154
  rescue Async::TimeoutError
119
155
  type_str = {'StatusUpdate'=>'update', 'StatusResponse'=>'response'}[type]
120
156
  raise RSMP::TimeoutError.new "Did not received correct status #{type_str} in reply to #{m_id} within #{options[:timeout]}s"
121
157
  end
122
158
 
123
- def status_match? query, item
124
- return nil if query['sCI'] && query['sCI'] != item['sCI']
125
- return nil if query['n'] && query['n'] != item['n']
126
- return false if query['q'] && query['q'] != item['q']
127
- if query['s'].is_a? Regexp
128
- return false if query['s'] && item['s'] !~ query['s']
129
- else
130
- return false if query['s'] && item['s'] != query['s']
131
- end
132
- true
133
- end
134
-
135
- def command_match? query, item
136
- return nil if query['cCI'] && query['cCI'] != item['cCI']
137
- return nil if query['n'] && query['n'] != item['n']
138
- if query['v'].is_a? Regexp
139
- return false if query['v'] && item['v'] !~ query['v']
140
- else
141
- return false if query['v'] && item['v'] != query['v']
142
- end
143
- true
144
- end
145
-
146
159
  def wait_for_aggregated_status parent_task, options, m_id
147
160
  collect(parent_task,options.merge({
148
161
  type: ['AggregatedStatus','MessageNotAck'],
@@ -168,4 +181,4 @@ module RSMP
168
181
  end
169
182
 
170
183
  end
171
- end
184
+ end
@@ -136,6 +136,13 @@ module RSMP
136
136
  end
137
137
  end
138
138
 
139
+ def peek_version_message protocol
140
+ json = protocol.peek_line
141
+ attributes = Message.parse_attributes json
142
+ message = Message.build attributes, json
143
+ message.attribute('siteId').first['sId']
144
+ end
145
+
139
146
  def connect socket, info
140
147
  log "Site connected from #{format_ip_and_port(info)}",
141
148
  ip: info[:ip],
@@ -144,25 +151,36 @@ module RSMP
144
151
  timestamp: Clock.now
145
152
 
146
153
  authorize_ip info[:ip]
147
- check_max_sites
148
154
 
149
- proxy = build_proxy({
155
+ stream = Async::IO::Stream.new socket
156
+ protocol = Async::IO::Protocol::Line.new stream, Proxy::WRAPPING_DELIMITER
157
+
158
+ settings = {
150
159
  supervisor: self,
151
160
  ip: info[:ip],
152
161
  port: info[:port],
153
162
  task: @task,
154
163
  settings: {'collect'=>@supervisor_settings['collect']},
155
164
  socket: socket,
165
+ stream: stream,
166
+ protocol: protocol,
156
167
  info: info,
157
168
  logger: @logger,
158
169
  archive: @archive
159
- })
160
- @proxies.push proxy
170
+ }
171
+
172
+ id = peek_version_message protocol
173
+ proxy = find_site id
174
+ if proxy
175
+ proxy.revive settings
176
+ else
177
+ check_max_sites
178
+ proxy = build_proxy settings
179
+ @proxies.push proxy
180
+ end
161
181
  proxy.run # will run until the site disconnects
162
182
  ensure
163
- @proxies.delete proxy
164
183
  site_ids_changed
165
-
166
184
  stop if @supervisor_settings['one_shot']
167
185
  end
168
186
 
@@ -188,7 +206,14 @@ module RSMP
188
206
  return find_site(site_id) != nil
189
207
  end
190
208
 
191
- def find_site site_id
209
+ def find_site_from_ip_port ip, port
210
+ @proxies.each do |site|
211
+ return site if site.ip == ip && site.port == port
212
+ end
213
+ nil
214
+ end
215
+
216
+ def find_site site_id
192
217
  @proxies.each do |site|
193
218
  return site if site_id == :any || site.site_id == site_id
194
219
  end
@@ -210,12 +235,13 @@ module RSMP
210
235
  end
211
236
 
212
237
  def check_site_id site_id
213
- check_site_already_connected site_id
238
+ #check_site_already_connected site_id
214
239
  return site_id_to_site_setting site_id
215
240
  end
216
241
 
217
242
  def check_site_already_connected site_id
218
- raise FatalError.new "Site '#{site_id}' already connected" if find_site(site_id)
243
+ site = find_site(site_id)
244
+ raise FatalError.new "Site '#{site_id}' already connected" if site != nil && site != self
219
245
  end
220
246
 
221
247
  def site_id_to_site_setting site_id
@@ -132,7 +132,7 @@ module RSMP
132
132
  "fP" => 'NormalControl',
133
133
  "fS" => nil,
134
134
  "se" => component.aggregated_status_bools,
135
- "mId" => m_id
135
+ "mId" => m_id,
136
136
  })
137
137
 
138
138
  if options[:collect]
data/lib/rsmp/tlc.rb CHANGED
@@ -798,7 +798,7 @@ module RSMP
798
798
  super options
799
799
  @sxl = 'traffic_light_controller'
800
800
  @security_codes = options[:site_settings]['security_codes']
801
- @interval = options[:site_settings]['intervals']['timer'] || 1
801
+ @interval = options[:site_settings].dig('intervals','timer') || 1
802
802
  unless @main
803
803
  raise ConfigurationError.new "TLC must have a main component"
804
804
  end
data/lib/rsmp/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module RSMP
2
- VERSION = "0.1.40"
2
+ VERSION = "0.2.3"
3
3
  end
data/rsmp.gemspec CHANGED
@@ -30,17 +30,17 @@ Gem::Specification.new do |spec|
30
30
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
31
31
  spec.require_paths = ["lib"]
32
32
 
33
- spec.add_dependency "async", "~> 1.28.7"
34
- spec.add_dependency "async-io", "~> 1.30.2"
33
+ spec.add_dependency "async", "~> 1.29.1"
34
+ spec.add_dependency "async-io", "~> 1.32.1"
35
35
  spec.add_dependency "colorize", "~> 0.8.1"
36
36
  spec.add_dependency "thor", "~> 1.0.1"
37
37
  spec.add_dependency "rsmp_schemer"
38
38
 
39
- spec.add_development_dependency "bundler", "~> 2.2.3"
40
- spec.add_development_dependency "rake", "~> 13.0.1"
41
- spec.add_development_dependency "rspec", "~> 3.9.0"
42
- spec.add_development_dependency "rspec-expectations", "~> 3.9.1"
43
- spec.add_development_dependency "timecop", "~> 0.9.1"
44
- spec.add_development_dependency "cucumber", "~> 3.1.2"
45
- spec.add_development_dependency "aruba", "~> 1.0.0"
39
+ spec.add_development_dependency "bundler", "~> 2.2.21"
40
+ spec.add_development_dependency "rake", "~> 13.0.3"
41
+ spec.add_development_dependency "rspec", "~> 3.10.0"
42
+ spec.add_development_dependency "rspec-expectations", "~> 3.10.1"
43
+ spec.add_development_dependency "timecop", "~> 0.9.4"
44
+ spec.add_development_dependency "cucumber", "~> 6.1.0"
45
+ spec.add_development_dependency "aruba" , "~> 1.1.2"
46
46
  end
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.1.40
4
+ version: 0.2.3
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-06-30 00:00:00.000000000 Z
11
+ date: 2021-10-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 1.28.7
19
+ version: 1.29.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 1.28.7
26
+ version: 1.29.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: async-io
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 1.30.2
33
+ version: 1.32.1
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 1.30.2
40
+ version: 1.32.1
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: colorize
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -86,98 +86,98 @@ dependencies:
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: 2.2.3
89
+ version: 2.2.21
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: 2.2.3
96
+ version: 2.2.21
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rake
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: 13.0.1
103
+ version: 13.0.3
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: 13.0.1
110
+ version: 13.0.3
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: rspec
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: 3.9.0
117
+ version: 3.10.0
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: 3.9.0
124
+ version: 3.10.0
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: rspec-expectations
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: 3.9.1
131
+ version: 3.10.1
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: 3.9.1
138
+ version: 3.10.1
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: timecop
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
143
  - - "~>"
144
144
  - !ruby/object:Gem::Version
145
- version: 0.9.1
145
+ version: 0.9.4
146
146
  type: :development
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
- version: 0.9.1
152
+ version: 0.9.4
153
153
  - !ruby/object:Gem::Dependency
154
154
  name: cucumber
155
155
  requirement: !ruby/object:Gem::Requirement
156
156
  requirements:
157
157
  - - "~>"
158
158
  - !ruby/object:Gem::Version
159
- version: 3.1.2
159
+ version: 6.1.0
160
160
  type: :development
161
161
  prerelease: false
162
162
  version_requirements: !ruby/object:Gem::Requirement
163
163
  requirements:
164
164
  - - "~>"
165
165
  - !ruby/object:Gem::Version
166
- version: 3.1.2
166
+ version: 6.1.0
167
167
  - !ruby/object:Gem::Dependency
168
168
  name: aruba
169
169
  requirement: !ruby/object:Gem::Requirement
170
170
  requirements:
171
171
  - - "~>"
172
172
  - !ruby/object:Gem::Version
173
- version: 1.0.0
173
+ version: 1.1.2
174
174
  type: :development
175
175
  prerelease: false
176
176
  version_requirements: !ruby/object:Gem::Requirement
177
177
  requirements:
178
178
  - - "~>"
179
179
  - !ruby/object:Gem::Version
180
- version: 1.0.0
180
+ version: 1.1.2
181
181
  description: Easy RSMP site and supervisor communication.
182
182
  email:
183
183
  - zf0f@kk.dk
@@ -254,7 +254,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
254
254
  - !ruby/object:Gem::Version
255
255
  version: '0'
256
256
  requirements: []
257
- rubygems_version: 3.2.3
257
+ rubygems_version: 3.2.26
258
258
  signing_key:
259
259
  specification_version: 4
260
260
  summary: RoadSide Message Protocol (RSMP) library.