rsmp 0.1.40 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
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.