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 +4 -4
- data/Gemfile.lock +95 -57
- data/lib/rsmp/logger.rb +2 -1
- data/lib/rsmp/node.rb +3 -3
- data/lib/rsmp/proxy.rb +17 -7
- data/lib/rsmp/site_proxy.rb +16 -5
- data/lib/rsmp/site_proxy_wait.rb +116 -103
- data/lib/rsmp/supervisor.rb +35 -9
- data/lib/rsmp/supervisor_proxy.rb +1 -1
- data/lib/rsmp/tlc.rb +1 -1
- data/lib/rsmp/version.rb +1 -1
- data/rsmp.gemspec +9 -9
- metadata +21 -21
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a57d963e9f3f6f4dccdfbfaf7bc2d4c09fcbae56d1ec886ed699faa373e054ed
|
|
4
|
+
data.tar.gz: 4035d49f738d335f94d4df8c9dd33a3744d258740e51df55be9da5998ce3e538
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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.
|
|
5
|
-
async (~> 1.
|
|
6
|
-
async-io (~> 1.
|
|
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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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.
|
|
27
|
+
async (1.29.2)
|
|
22
28
|
console (~> 1.10)
|
|
23
29
|
nio4r (~> 2.3)
|
|
24
30
|
timers (~> 4.1)
|
|
25
|
-
async-io (1.
|
|
26
|
-
async
|
|
27
|
-
backports (3.17.0)
|
|
31
|
+
async-io (1.32.2)
|
|
32
|
+
async
|
|
28
33
|
builder (3.2.4)
|
|
29
|
-
childprocess (
|
|
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.
|
|
34
|
-
cucumber (
|
|
35
|
-
builder (>= 2.
|
|
36
|
-
cucumber-core (~>
|
|
37
|
-
cucumber-
|
|
38
|
-
cucumber-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
cucumber-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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.
|
|
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
|
-
|
|
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.
|
|
65
|
-
|
|
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.
|
|
70
|
-
rspec-core (~> 3.
|
|
71
|
-
rspec-expectations (~> 3.
|
|
72
|
-
rspec-mocks (~> 3.
|
|
73
|
-
rspec-core (3.
|
|
74
|
-
rspec-support (~> 3.
|
|
75
|
-
rspec-expectations (3.
|
|
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.
|
|
78
|
-
rspec-mocks (3.
|
|
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.
|
|
81
|
-
rspec-support (3.
|
|
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
|
-
|
|
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
|
-
|
|
126
|
+
x86_64-darwin-20
|
|
89
127
|
|
|
90
128
|
DEPENDENCIES
|
|
91
|
-
aruba (~> 1.
|
|
92
|
-
bundler (~> 2.2.
|
|
93
|
-
cucumber (~>
|
|
94
|
-
rake (~> 13.0.
|
|
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.
|
|
97
|
-
rspec-expectations (~> 3.
|
|
98
|
-
timecop (~> 0.9.
|
|
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.
|
|
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, :
|
|
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
|
-
@
|
|
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
|
-
@
|
|
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
|
-
|
|
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
|
|
109
|
-
@protocol
|
|
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
|
data/lib/rsmp/site_proxy.rb
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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" => '',
|
data/lib/rsmp/site_proxy_wait.rb
CHANGED
|
@@ -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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
data/lib/rsmp/supervisor.rb
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
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]
|
|
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
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.
|
|
34
|
-
spec.add_dependency "async-io", "~> 1.
|
|
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.
|
|
40
|
-
spec.add_development_dependency "rake", "~> 13.0.
|
|
41
|
-
spec.add_development_dependency "rspec", "~> 3.
|
|
42
|
-
spec.add_development_dependency "rspec-expectations", "~> 3.
|
|
43
|
-
spec.add_development_dependency "timecop", "~> 0.9.
|
|
44
|
-
spec.add_development_dependency "cucumber", "~>
|
|
45
|
-
spec.add_development_dependency "aruba", "~> 1.
|
|
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.
|
|
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-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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:
|
|
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:
|
|
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.
|
|
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.
|
|
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.
|
|
257
|
+
rubygems_version: 3.2.26
|
|
258
258
|
signing_key:
|
|
259
259
|
specification_version: 4
|
|
260
260
|
summary: RoadSide Message Protocol (RSMP) library.
|