rsmp 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.gitmodules +3 -0
- data/.rspec +1 -0
- data/CHANGELOG.md +4 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +101 -0
- data/LICENSE +7 -0
- data/README.md +204 -0
- data/Rakefile +6 -0
- data/bin/console +51 -0
- data/bin/setup +8 -0
- data/config/site.yaml +41 -0
- data/config/supervisor.yaml +33 -0
- data/exe/rsmp +4 -0
- data/lib/rsmp/alarm.rb +15 -0
- data/lib/rsmp/archive.rb +75 -0
- data/lib/rsmp/base.rb +26 -0
- data/lib/rsmp/cli.rb +52 -0
- data/lib/rsmp/component.rb +65 -0
- data/lib/rsmp/error.rb +44 -0
- data/lib/rsmp/logger.rb +153 -0
- data/lib/rsmp/message.rb +313 -0
- data/lib/rsmp/node.rb +53 -0
- data/lib/rsmp/probe.rb +104 -0
- data/lib/rsmp/probe_collection.rb +28 -0
- data/lib/rsmp/proxy.rb +508 -0
- data/lib/rsmp/rsmp.rb +31 -0
- data/lib/rsmp/site.rb +165 -0
- data/lib/rsmp/site_base.rb +26 -0
- data/lib/rsmp/site_proxy.rb +220 -0
- data/lib/rsmp/supervisor.rb +220 -0
- data/lib/rsmp/supervisor_base.rb +10 -0
- data/lib/rsmp/supervisor_proxy.rb +292 -0
- data/lib/rsmp/version.rb +3 -0
- data/lib/rsmp/wait.rb +17 -0
- data/lib/rsmp.rb +29 -0
- data/rsmp.gemspec +43 -0
- metadata +266 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 250eabe3e6427dd2032d46756055c93175383c5a32c5ca13d56a9b237bd9d033
|
4
|
+
data.tar.gz: 34d1ce845bbb2029b1bb00165d66c4e1181c8479ab99953b4d1687d51180d50c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a12e73c1c5a98c557cb733ce2ed1251ece7ade05763fb3f657846d12120413b020aa3a716b48d3c76aa4a913898732b0f87add636a790052390777d54308ed14
|
7
|
+
data.tar.gz: 449d24617bc74cafab1f314fba2297fcb17fcfba74743c69a2720ba9ca9297e3d61798be49d4303c0294b5215262382b8eb570d91f04e1318e570094739b7455
|
data/.gitignore
ADDED
data/.gitmodules
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require spec_helper
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
rsmp (0.1.0)
|
5
|
+
async (~> 1.23.0)
|
6
|
+
async-io (~> 1.27.0)
|
7
|
+
colorize (~> 0.8.1)
|
8
|
+
json_schemer (~> 0.2.8)
|
9
|
+
thor (~> 0.20.3)
|
10
|
+
|
11
|
+
GEM
|
12
|
+
remote: https://rubygems.org/
|
13
|
+
specs:
|
14
|
+
aruba (0.14.11)
|
15
|
+
childprocess (>= 0.6.3, < 3.0.0)
|
16
|
+
contracts (~> 0.9)
|
17
|
+
cucumber (>= 1.3.19)
|
18
|
+
ffi (~> 1.9)
|
19
|
+
rspec-expectations (>= 2.99)
|
20
|
+
thor (~> 0.19)
|
21
|
+
async (1.23.0)
|
22
|
+
console (~> 1.0)
|
23
|
+
nio4r (~> 2.3)
|
24
|
+
timers (~> 4.1)
|
25
|
+
async-io (1.27.0)
|
26
|
+
async (~> 1.14)
|
27
|
+
backports (3.15.0)
|
28
|
+
builder (3.2.3)
|
29
|
+
childprocess (2.0.0)
|
30
|
+
rake (< 13.0)
|
31
|
+
colorize (0.8.1)
|
32
|
+
console (1.5.0)
|
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)
|
51
|
+
ecma-re-validator (0.2.0)
|
52
|
+
regexp_parser (~> 1.2)
|
53
|
+
ffi (1.11.1)
|
54
|
+
gherkin (5.1.0)
|
55
|
+
hana (1.3.5)
|
56
|
+
json_schemer (0.2.8)
|
57
|
+
ecma-re-validator (~> 0.2)
|
58
|
+
hana (~> 1.3)
|
59
|
+
regexp_parser (~> 1.5)
|
60
|
+
uri_template (~> 0.7)
|
61
|
+
multi_json (1.13.1)
|
62
|
+
multi_test (0.1.2)
|
63
|
+
nio4r (2.5.2)
|
64
|
+
rake (10.5.0)
|
65
|
+
regexp_parser (1.6.0)
|
66
|
+
rspec (3.8.0)
|
67
|
+
rspec-core (~> 3.8.0)
|
68
|
+
rspec-expectations (~> 3.8.0)
|
69
|
+
rspec-mocks (~> 3.8.0)
|
70
|
+
rspec-core (3.8.2)
|
71
|
+
rspec-support (~> 3.8.0)
|
72
|
+
rspec-expectations (3.8.4)
|
73
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
74
|
+
rspec-support (~> 3.8.0)
|
75
|
+
rspec-mocks (3.8.1)
|
76
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
77
|
+
rspec-support (~> 3.8.0)
|
78
|
+
rspec-support (3.8.2)
|
79
|
+
rspec-with_params (0.2.0)
|
80
|
+
rspec (~> 3.0)
|
81
|
+
thor (0.20.3)
|
82
|
+
timecop (0.9.1)
|
83
|
+
timers (4.3.0)
|
84
|
+
uri_template (0.7.0)
|
85
|
+
|
86
|
+
PLATFORMS
|
87
|
+
ruby
|
88
|
+
|
89
|
+
DEPENDENCIES
|
90
|
+
aruba (~> 0.14.11)
|
91
|
+
bundler (~> 2.0)
|
92
|
+
cucumber (~> 3.1.2)
|
93
|
+
rake (~> 10.0)
|
94
|
+
rsmp!
|
95
|
+
rspec (~> 3.0)
|
96
|
+
rspec-expectations (~> 3.8.3)
|
97
|
+
rspec-with_params (~> 0.2.0)
|
98
|
+
timecop (~> 0.9.1)
|
99
|
+
|
100
|
+
BUNDLED WITH
|
101
|
+
2.1.0.pre.2
|
data/LICENSE
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
Copyright 2019 The City Copenhagen
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
4
|
+
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,204 @@
|
|
1
|
+
# rsmp
|
2
|
+
This is a Ruby implementation of the RSMP protocol, including:
|
3
|
+
- RSMP classes that can be used to build tests or other RSMP tools
|
4
|
+
- Command-line tools for quickly running RSMP supervisors or sites and view messages exchanged
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
You need a recent version of Ruby intalled. 2.6.3 or later is recommended.
|
8
|
+
|
9
|
+
Install required gems:
|
10
|
+
|
11
|
+
```console
|
12
|
+
$ gem install bundler
|
13
|
+
$ bundle
|
14
|
+
```
|
15
|
+
|
16
|
+
Install git submodules:
|
17
|
+
The JSON Schema is is included as a git submodule. To install it:
|
18
|
+
|
19
|
+
```console
|
20
|
+
$ git submodule init # initialize local submodule config
|
21
|
+
$ git submodule update # fetch submodules
|
22
|
+
```
|
23
|
+
|
24
|
+
Alternatively, you can pass --recurse-submodules to the git clone command, and it will automatically initialize and update each submodule in the repository.
|
25
|
+
|
26
|
+
## Usage
|
27
|
+
### Site and Supervisor
|
28
|
+
The RSMP::Site and RSMP::Supervisor classes can be used to run a RSMP site.
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
require 'rsmp'
|
32
|
+
RSMP::Site.new.start # run site until Ctlr-C is pressed
|
33
|
+
```
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
require 'rsmp'
|
37
|
+
RSMP::Supervisor.new.start # run supervisor until Ctlr-C is pressed
|
38
|
+
```
|
39
|
+
|
40
|
+
Be default, a site will try to connect to a single supervisor on localhost 127.0.0.1, port 12111. By default, a supervisor will listen for sites on port 12111 and accept any site.
|
41
|
+
|
42
|
+
You can pass options to control ip adresseses, ports, logging and other behaviour:
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
require 'rsmp'
|
46
|
+
settings = {
|
47
|
+
'site_id' => 'RN+SI0001', # site id
|
48
|
+
'supervisors' => [ # list of supervisor to connect to
|
49
|
+
{ 'ip' => '127.0.0.1', 'port' => 12111 } # ip and port
|
50
|
+
],
|
51
|
+
'log' => {
|
52
|
+
'json' => true, # show raw json messages in log
|
53
|
+
}
|
54
|
+
}
|
55
|
+
RSMP::Site.new(site_settings:settings)
|
56
|
+
```
|
57
|
+
|
58
|
+
See lib/rsmp/site.rb and lib/rsmp/supervisor.rb for a list of settings and their default values.
|
59
|
+
|
60
|
+
### Concurrency
|
61
|
+
The [async](https://github.com/socketry/async) and [async-io](https://github.com/socketry/async-io) gems are used to handle concurrency. Everything happens in a single thread, but fibers are used to switch between tasks whenever an IO operation blocks.
|
62
|
+
|
63
|
+
If you start a site or a supervisor inside an Async block, it will run concurrently:
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
require 'rsmp'
|
67
|
+
settings = {
|
68
|
+
'log' => { 'active' => false } # disable log output
|
69
|
+
}
|
70
|
+
Async do |task|
|
71
|
+
site = RSMP::Site.new(site_settings:settings)
|
72
|
+
site.start # run concurrently since we're inside an Async block
|
73
|
+
loop do
|
74
|
+
task.sleep 1 # use task.sleep() instead of sleep() to avoid blocking
|
75
|
+
puts "Latest archive item: #{site.archive.items.last}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
```
|
79
|
+
|
80
|
+
Use task.show_hierarchy to see what task are created, task.stop() to stop all sites and supervisors running inside it:
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
require 'rsmp'
|
84
|
+
Async do |task|
|
85
|
+
RSMP::Site.new.start
|
86
|
+
task.sleep 1
|
87
|
+
task.print_hierarchy
|
88
|
+
task.stop # stop everything inside this Async block
|
89
|
+
end
|
90
|
+
puts "Bye!"
|
91
|
+
```
|
92
|
+
|
93
|
+
RSMP::Site and RSMP::Supervisor is not Async task themselves, but each contain a ```task``` attribute containing an async task used to run network and timers. A supervisor contains a single task listening for connections from sites. A site contain a task for each supervisor that it connects to.
|
94
|
+
|
95
|
+
See the async documentation for more information about working with task and concurrency.
|
96
|
+
|
97
|
+
### Archive and Logging
|
98
|
+
Sites and supervisor can log message and events, and will store them in an archive.
|
99
|
+
|
100
|
+
RSMP::Archive stores messages. RSMP::Logger filters and formats messages according to log settings.
|
101
|
+
|
102
|
+
By default, sites and supervisor will create a new archive when initialized, but you can pass in an exsiting archive, which is useful in case you want several sites/supervisors to use the same archive:
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
require 'rsmp'
|
106
|
+
|
107
|
+
# create common archive and logger
|
108
|
+
logger = RSMP::Logger.new('timestamp'=>false,'author'=>true)
|
109
|
+
archive = RSMP::Archive.new
|
110
|
+
|
111
|
+
# run supervisor and site for 0.1 second, then stop them
|
112
|
+
Async do |task|
|
113
|
+
RSMP::Supervisor.new(archive:archive,logger:logger).start
|
114
|
+
RSMP::Site.new(archive:archive,logger:logger).start
|
115
|
+
task.sleep 0.1
|
116
|
+
task.stop
|
117
|
+
end
|
118
|
+
|
119
|
+
# show archiuve content
|
120
|
+
logger.dump archive, force:true
|
121
|
+
```
|
122
|
+
|
123
|
+
This will output messages form both the site and the supervisor, ordered chronologically:
|
124
|
+
|
125
|
+
```console
|
126
|
+
RN+SU0001 Starting supervisor RN+SU0001 on port 12111
|
127
|
+
RN+SI0001 Starting site RN+SI0001
|
128
|
+
RN+SI0001 Connecting to superviser at 127.0.0.1:12111
|
129
|
+
RN+SI0001 <-- f8c7 Sent Version
|
130
|
+
RN+SU0001 Site connected from 127.0.0.1:53500
|
131
|
+
RN+SU0001 RN+SI0001 --> f8c7 Received Version message for sites [RN+SI0001] using RSMP 3.1.4
|
132
|
+
...
|
133
|
+
```
|
134
|
+
|
135
|
+
### JSON Schema validation
|
136
|
+
All messages sent and received will be validated against the core [RSMP JSON Schema](https://github.com/rsmp-nordic/rsmp_schema).
|
137
|
+
|
138
|
+
## Command-line tool
|
139
|
+
Tools for easily running RSMP supervisors and sites. The binary is called ```rsmp```.
|
140
|
+
|
141
|
+
The ```supervisor``` command will start an RSMP supervisor, which sites can connect to:
|
142
|
+
|
143
|
+
```console
|
144
|
+
% rsmp supervisor
|
145
|
+
2019-11-11 12:21:55 UTC Starting supervisor RN+SU0001 on port 12111
|
146
|
+
2019-11-11 12:22:00 UTC Site connected from 127.0.0.1:50098
|
147
|
+
2019-11-11 12:22:00 UTC RN+SI0001 --> 792f Received Version message for sites [RN+SI0001] using RSMP 3.1.4
|
148
|
+
2019-11-11 12:22:00 UTC RN+SI0001 <-- e70e Sent Version
|
149
|
+
2019-11-11 12:22:00 UTC RN+SI0001 Connection to site RN+SI0001 established
|
150
|
+
2019-11-11 12:22:00 UTC RN+SI0001 Adding component C1 to site RN+SI0001
|
151
|
+
2019-11-11 12:22:00 UTC RN+SI0001 C1 --> 8280 Received AggregatedStatus status for component C1 []
|
152
|
+
```
|
153
|
+
|
154
|
+
The ```site``` command will start an RSMP site, which will try to connect to one or more supervisor. Here's an example of the site connecting to a Ruby supervisor:
|
155
|
+
|
156
|
+
```console
|
157
|
+
% rsmp site
|
158
|
+
2019-11-11 12:22:00 UTC Starting site RN+SI0001
|
159
|
+
2019-11-11 12:22:00 UTC Connecting to superviser at 127.0.0.1:12111
|
160
|
+
2019-11-11 12:22:00 UTC <-- 792f Sent Version
|
161
|
+
2019-11-11 12:22:00 UTC RN+SU0001 --> e70e Received Version message, using RSMP 3.1.4
|
162
|
+
2019-11-11 12:22:00 UTC RN+SU0001 Connection to supervisor established
|
163
|
+
2019-11-11 12:22:00 UTC RN+SU0001 C1 <-- 8280 Sent AggregatedStatus
|
164
|
+
```
|
165
|
+
|
166
|
+
### CLI help and options.
|
167
|
+
Use ```--help <command>``` to get a list of available options.
|
168
|
+
|
169
|
+
Use ```--config <path>``` to point to a .yaml config file, controlling things like IP adresses, ports, and log output. Examples of config files can be found the folder ```config/```.
|
170
|
+
|
171
|
+
## Tests
|
172
|
+
### RSpec
|
173
|
+
RSpec tests are located in spec/. The tests will start supervisor and sites to test communication, but will do so on port 13111, rather than the usual port 12111, to avoid inferference with other RMSP processes running locally.
|
174
|
+
|
175
|
+
Note that these tests are NOT intented for testing external equipment or systems. The tests are for validating the code in this repository. To test external equipment or systems.
|
176
|
+
|
177
|
+
```console
|
178
|
+
$ rspec
|
179
|
+
.........................
|
180
|
+
|
181
|
+
Finished in 0.12746 seconds (files took 0.6571 seconds to load)
|
182
|
+
25 examples, 0 failures
|
183
|
+
|
184
|
+
```
|
185
|
+
|
186
|
+
# Cucumber
|
187
|
+
Cucumber is used to test the CLI binaries.
|
188
|
+
|
189
|
+
```console
|
190
|
+
$ cucumber
|
191
|
+
Feature: Help
|
192
|
+
|
193
|
+
Scenario: Displaying help # features/help.feature:3
|
194
|
+
When I run `rsmp help` # aruba-0.14.11/lib/aruba/cucumber/command.rb:6
|
195
|
+
Then it should pass with "Commands:" # aruba-0.14.11/lib/aruba/cucumber/command.rb:271
|
196
|
+
|
197
|
+
Feature: Run site
|
198
|
+
...
|
199
|
+
|
200
|
+
7 scenarios (7 passed)
|
201
|
+
28 steps (28 passed)
|
202
|
+
0m7.036s
|
203
|
+
```
|
204
|
+
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Make IRB run inside Async, so async task
|
4
|
+
# will run the the background.
|
5
|
+
|
6
|
+
require 'bundler/setup'
|
7
|
+
require 'irb'
|
8
|
+
require 'rsmp'
|
9
|
+
#require 'async/io/protocol/line'
|
10
|
+
|
11
|
+
module IRB
|
12
|
+
|
13
|
+
# custom input class which reads from an async stream
|
14
|
+
class MyInputMethod < StdioInputMethod
|
15
|
+
def initialize
|
16
|
+
super
|
17
|
+
@input = Async::IO::Protocol::Line.new(
|
18
|
+
Async::IO::Stream.new(
|
19
|
+
Async::IO::Generic.new($stdin)
|
20
|
+
)
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
def gets
|
25
|
+
# since this is an async stream, the call to read_line()
|
26
|
+
# will give the Async reactor a chance to schedule other task
|
27
|
+
print @prompt
|
28
|
+
line = @input.read_line
|
29
|
+
@line[@line_no += 1] = "#{line}\n"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.start(ap_path = nil)
|
34
|
+
STDOUT.sync = true
|
35
|
+
$0 = File::basename(ap_path, ".rb") if ap_path
|
36
|
+
|
37
|
+
IRB.setup(ap_path)
|
38
|
+
|
39
|
+
if @CONF[:SCRIPT]
|
40
|
+
irb = Irb.new(nil, @CONF[:SCRIPT])
|
41
|
+
else
|
42
|
+
irb = Irb.new(nil,MyInputMethod.new)
|
43
|
+
end
|
44
|
+
|
45
|
+
irb.run(@CONF)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
Async do
|
50
|
+
IRB.start(__FILE__)
|
51
|
+
end
|
data/bin/setup
ADDED
data/config/site.yaml
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
site_id: RN+SI0001
|
2
|
+
supervisors:
|
3
|
+
- ip: 127.0.0.1
|
4
|
+
port: 12111
|
5
|
+
|
6
|
+
sxl: traffic_light_controller
|
7
|
+
|
8
|
+
rsmp_versions:
|
9
|
+
- 3.1.1
|
10
|
+
- 3.1.2
|
11
|
+
- 3.1.3
|
12
|
+
- 3.1.4
|
13
|
+
|
14
|
+
components:
|
15
|
+
A1:
|
16
|
+
type: main
|
17
|
+
|
18
|
+
watchdog_interval: 1
|
19
|
+
watchdog_timeout: 2
|
20
|
+
acknowledgement_timeout: 2
|
21
|
+
store_messages: false
|
22
|
+
command_response_timeout: 1
|
23
|
+
status_response_timeout: 1
|
24
|
+
status_update_timeout: 1
|
25
|
+
reconnect_interval: 0.1
|
26
|
+
|
27
|
+
log:
|
28
|
+
active: true
|
29
|
+
color: true
|
30
|
+
timestamp: true
|
31
|
+
id: true
|
32
|
+
component: true
|
33
|
+
ip: false
|
34
|
+
site_id: true
|
35
|
+
level: false
|
36
|
+
text: true
|
37
|
+
direction: true
|
38
|
+
json: true
|
39
|
+
acknowledgements: false
|
40
|
+
watchdogs: false
|
41
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
site_id: RN+SU0001
|
2
|
+
port: 12111
|
3
|
+
rsmp_versions:
|
4
|
+
- 3.1.4
|
5
|
+
|
6
|
+
watchdog_interval: 1
|
7
|
+
watchdog_timeout: 2
|
8
|
+
acknowledgement_timeout: 2
|
9
|
+
store_messages: false
|
10
|
+
command_response_timeout: 1
|
11
|
+
status_response_timeout: 1
|
12
|
+
status_update_timeout: 1
|
13
|
+
|
14
|
+
sites:
|
15
|
+
AA+BBCCC=DDD: # rsmp simulator
|
16
|
+
sxl: core
|
17
|
+
RN+SI0001: # ruby rsmp site
|
18
|
+
|
19
|
+
log:
|
20
|
+
active: true
|
21
|
+
color: true
|
22
|
+
timestamp: true
|
23
|
+
id: true
|
24
|
+
component: true
|
25
|
+
ip: false
|
26
|
+
site_id: true
|
27
|
+
text: true
|
28
|
+
direction: true
|
29
|
+
level: false
|
30
|
+
json: true
|
31
|
+
acknowledgements: true
|
32
|
+
watchdogs: true
|
33
|
+
|
data/exe/rsmp
ADDED
data/lib/rsmp/alarm.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# RSMP Alarm. Manages the various states an alarm can be in.
|
2
|
+
|
3
|
+
module RSMP
|
4
|
+
class Alarm
|
5
|
+
|
6
|
+
def initialize code: code, blocked: blocked=false, suspended: suspended=false, acknowledged: acknowledged=false
|
7
|
+
@code = code
|
8
|
+
@code = code
|
9
|
+
@blocked = blocked
|
10
|
+
@suspended = suspended
|
11
|
+
@acknowledged = acknowledged
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
data/lib/rsmp/archive.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
# Archive of log items, which can be messages or info items.
|
2
|
+
# All items are timestamped, and stored chronologically.
|
3
|
+
|
4
|
+
module RSMP
|
5
|
+
class Archive
|
6
|
+
attr_reader :items
|
7
|
+
attr_accessor :probes
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@items = []
|
11
|
+
@probes = ProbeCollection.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.prepare_item item
|
15
|
+
raise ArgumentError unless item.is_a? Hash
|
16
|
+
|
17
|
+
now_obj = RSMP.now_object
|
18
|
+
now_str = RSMP.now_string(now_obj)
|
19
|
+
|
20
|
+
cleaned = item.select { |k,v| [:author,:level,:ip,:port,:site_id,:component_id,:str,:message,:exception].include? k }
|
21
|
+
cleaned[:timestamp] = now_obj
|
22
|
+
if item[:message]
|
23
|
+
cleaned[:direction] = item[:message].direction
|
24
|
+
cleaned[:component_id] = item[:message].attributes['cId']
|
25
|
+
end
|
26
|
+
|
27
|
+
cleaned
|
28
|
+
end
|
29
|
+
|
30
|
+
def by_level levels
|
31
|
+
items.select { |item| levels.include? item[:level] }
|
32
|
+
end
|
33
|
+
|
34
|
+
def strings
|
35
|
+
items.map { |item| item[:str] }
|
36
|
+
end
|
37
|
+
|
38
|
+
def current_index
|
39
|
+
@items.size
|
40
|
+
end
|
41
|
+
|
42
|
+
def add item
|
43
|
+
item[:index] = @items.size
|
44
|
+
@items << item
|
45
|
+
probe item
|
46
|
+
end
|
47
|
+
|
48
|
+
def capture task, options, &block
|
49
|
+
probe = RSMP::Probe.new self
|
50
|
+
probe.capture task, options, &block
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def probe item
|
56
|
+
@probes.process item
|
57
|
+
end
|
58
|
+
|
59
|
+
def find options, &block
|
60
|
+
# search backwards from newest to older, stopping once messages
|
61
|
+
# are older that options[:earliest]
|
62
|
+
out = []
|
63
|
+
@items.reverse_each do |item|
|
64
|
+
break if options[:earliest] && item[:timestamp] < options[:earliest]
|
65
|
+
next if options[:level] && item[:level] != options[:level]
|
66
|
+
next if options[:type] && (item[:message] == nil || (item[:message].type != options[:type]))
|
67
|
+
next if options[:with_message] && !(item[:direction] && item[:message])
|
68
|
+
next if block_given? && block.call != true
|
69
|
+
out.unshift item
|
70
|
+
end
|
71
|
+
out
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
data/lib/rsmp/base.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
#
|
2
|
+
# RSMP base class
|
3
|
+
#
|
4
|
+
|
5
|
+
module RSMP
|
6
|
+
class Base
|
7
|
+
attr_reader :archive, :logger
|
8
|
+
|
9
|
+
def initialize options
|
10
|
+
@archive = options[:archive] || RSMP::Archive.new
|
11
|
+
@logger = options[:logger] || RSMP::Logger.new(options[:log_settings])
|
12
|
+
end
|
13
|
+
|
14
|
+
def author
|
15
|
+
end
|
16
|
+
|
17
|
+
def log str, options={}
|
18
|
+
default = { level: :log, author: author }
|
19
|
+
prepared = RSMP::Archive.prepare_item default.merge(options.merge str: str)
|
20
|
+
@archive.add prepared
|
21
|
+
@logger.log prepared
|
22
|
+
prepared
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
data/lib/rsmp/cli.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'rsmp'
|
3
|
+
|
4
|
+
module RSMP
|
5
|
+
class CLI < Thor
|
6
|
+
|
7
|
+
desc "site", "Run RSMP site"
|
8
|
+
method_option :config, :type => :string, :aliases => "-c", banner: 'Path to .yaml config file'
|
9
|
+
method_option :id, :type => :string, :aliases => "-i", banner: 'RSMP site id'
|
10
|
+
method_option :supervisors, :type => :string, :aliases => "-s", banner: 'ip:port,... list of supervisor to connect to'
|
11
|
+
def site
|
12
|
+
converted = {
|
13
|
+
site_settings_path: options[:config],
|
14
|
+
site_settings: {
|
15
|
+
site_id: options[:id],
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
19
|
+
if options[:supervisors]
|
20
|
+
options[:supervisors].split(',').each do |supervisor|
|
21
|
+
converted[:site_settings][:supervisors] ||= []
|
22
|
+
ip, port = supervisor.split ':'
|
23
|
+
ip = '127.0.0.1' if ip.empty?
|
24
|
+
port = '12111' if port.empty?
|
25
|
+
converted[:site_settings][:supervisors] << {"ip"=>ip, "port"=>port}
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
converted[:site_settings].compact!
|
30
|
+
RSMP::Site.new(converted).start
|
31
|
+
end
|
32
|
+
|
33
|
+
desc "supervisor", "Run RSMP supervisor"
|
34
|
+
method_option :config, :type => :string, :aliases => "-c", banner: 'Path to .yaml config file'
|
35
|
+
method_option :id, :type => :string, :aliases => "-i", banner: 'RSMP site id'
|
36
|
+
method_option :ip, :type => :numeric, banner: 'IP address to listen on'
|
37
|
+
method_option :port, :type => :string, :aliases => "-p", banner: 'Port to listen on'
|
38
|
+
def supervisor
|
39
|
+
converted = {
|
40
|
+
supervisor_settings_path: options[:config],
|
41
|
+
supervisor_settings: {
|
42
|
+
site_id: options[:id],
|
43
|
+
ip: options[:ip],
|
44
|
+
port: options[:port]
|
45
|
+
}
|
46
|
+
}
|
47
|
+
converted[:supervisor_settings].compact!
|
48
|
+
RSMP::Supervisor.new(converted).start
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|