rsmp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
data/lib/rsmp/site.rb
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
# RSMP site
|
2
|
+
# The site initializes the connection to the supervisor.
|
3
|
+
# Connections to supervisors are handles via supervisor proxies.
|
4
|
+
|
5
|
+
module RSMP
|
6
|
+
class Site < Node
|
7
|
+
include SiteBase
|
8
|
+
|
9
|
+
attr_reader :rsmp_versions, :site_settings, :logger, :proxies
|
10
|
+
|
11
|
+
def initialize options={}
|
12
|
+
initialize_site
|
13
|
+
handle_site_settings options
|
14
|
+
super options.merge log_settings: @site_settings["log"]
|
15
|
+
@proxies = []
|
16
|
+
@sleep_condition = Async::Notification.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def site_id
|
20
|
+
@site_settings['site_id']
|
21
|
+
end
|
22
|
+
|
23
|
+
def handle_site_settings options
|
24
|
+
@site_settings = {
|
25
|
+
'site_id' => 'RN+SI0001',
|
26
|
+
'supervisors' => [
|
27
|
+
{ 'ip' => '127.0.0.1', 'port' => 12111 }
|
28
|
+
],
|
29
|
+
'rsmp_versions' => ['3.1.1','3.1.2','3.1.3','3.1.4'],
|
30
|
+
'timer_interval' => 0.1,
|
31
|
+
'watchdog_interval' => 1,
|
32
|
+
'watchdog_timeout' => 2,
|
33
|
+
'acknowledgement_timeout' => 2,
|
34
|
+
'command_response_timeout' => 1,
|
35
|
+
'status_response_timeout' => 1,
|
36
|
+
'status_update_timeout' => 1,
|
37
|
+
'site_connect_timeout' => 2,
|
38
|
+
'site_ready_timeout' => 1,
|
39
|
+
'reconnect_interval' => 0.1,
|
40
|
+
'send_after_connect' => true,
|
41
|
+
'components' => {
|
42
|
+
'C1' => {}
|
43
|
+
},
|
44
|
+
'log' => {
|
45
|
+
'active' => true,
|
46
|
+
'color' => true,
|
47
|
+
'ip' => false,
|
48
|
+
'timestamp' => true,
|
49
|
+
'site_id' => true,
|
50
|
+
'level' => false,
|
51
|
+
'acknowledgements' => false,
|
52
|
+
'watchdogs' => false,
|
53
|
+
'json' => false,
|
54
|
+
'statistics' => false
|
55
|
+
}
|
56
|
+
}
|
57
|
+
if options[:site_settings_path]
|
58
|
+
if File.exist? options[:site_settings_path]
|
59
|
+
@site_settings.merge! YAML.load_file(options[:site_settings_path])
|
60
|
+
else
|
61
|
+
puts "Error: Config #{options[:site_settings_path]} not found, pwd"
|
62
|
+
exit
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
if options[:site_settings]
|
67
|
+
converted = options[:site_settings].map { |k,v| [k.to_s,v] }.to_h #convert symbol keys to string keys
|
68
|
+
converted.compact!
|
69
|
+
@site_settings.merge! converted
|
70
|
+
end
|
71
|
+
|
72
|
+
required = [:supervisors,:rsmp_versions,:site_id,:watchdog_interval,:watchdog_timeout,
|
73
|
+
:acknowledgement_timeout,:command_response_timeout,:log]
|
74
|
+
check_required_settings @site_settings, required
|
75
|
+
|
76
|
+
setup_components @site_settings['components']
|
77
|
+
end
|
78
|
+
|
79
|
+
def reconnect
|
80
|
+
@sleep_condition.signal
|
81
|
+
end
|
82
|
+
|
83
|
+
def start_action
|
84
|
+
@site_settings["supervisors"].each do |supervisor_settings|
|
85
|
+
@task.async do |task|
|
86
|
+
task.annotate "site_proxy"
|
87
|
+
connect_to_supervisor task, supervisor_settings
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def build_connector settings
|
93
|
+
SupervisorProxy.new settings
|
94
|
+
end
|
95
|
+
|
96
|
+
def aggrated_status_changed component
|
97
|
+
@proxies.each do |proxy|
|
98
|
+
proxy.send_aggregated_status component
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def connect_to_supervisor task, supervisor_settings
|
103
|
+
proxy = build_connector({
|
104
|
+
site: self,
|
105
|
+
task: @task,
|
106
|
+
settings: @site_settings,
|
107
|
+
ip: supervisor_settings['ip'],
|
108
|
+
port: supervisor_settings['port'],
|
109
|
+
logger: @logger,
|
110
|
+
archive: @archive
|
111
|
+
})
|
112
|
+
@proxies << proxy
|
113
|
+
run_site_proxy task, proxy
|
114
|
+
ensure
|
115
|
+
@proxies.delete proxy
|
116
|
+
end
|
117
|
+
|
118
|
+
def run_site_proxy task, proxy
|
119
|
+
loop do
|
120
|
+
proxy.run # run until disconnected
|
121
|
+
rescue IOError => e
|
122
|
+
log "Stream error: #{e}", level: :warning
|
123
|
+
rescue SystemCallError => e # all ERRNO errors
|
124
|
+
log "Reader exception: #{e.to_s}", level: :error
|
125
|
+
rescue StandardError => e
|
126
|
+
log ["Reader exception: #{e}",e.backtrace].flatten.join("\n"), level: :error
|
127
|
+
ensure
|
128
|
+
begin
|
129
|
+
if @site_settings["reconnect_interval"] != :no
|
130
|
+
# sleep until waken by reconnect() or the reconnect interval passed
|
131
|
+
proxy.set_state :wait_for_reconnect
|
132
|
+
task.with_timeout(@site_settings["reconnect_interval"]) { @sleep_condition.wait }
|
133
|
+
else
|
134
|
+
proxy.set_state :cannot_connect
|
135
|
+
break
|
136
|
+
end
|
137
|
+
rescue Async::TimeoutError
|
138
|
+
# ignore
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def stop
|
144
|
+
log "Stopping site #{@site_settings["site_id"]}", level: :info
|
145
|
+
@proxies.each do |proxy|
|
146
|
+
proxy.stop
|
147
|
+
end
|
148
|
+
@proxies.clear
|
149
|
+
super
|
150
|
+
end
|
151
|
+
|
152
|
+
def starting
|
153
|
+
log "Starting site #{@site_settings["site_id"]}",
|
154
|
+
level: :info,
|
155
|
+
timestamp: RSMP.now_object
|
156
|
+
end
|
157
|
+
|
158
|
+
def alarm
|
159
|
+
@proxies.each do |proxy|
|
160
|
+
proxy.stop
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# Things shared between sites and site proxies
|
2
|
+
|
3
|
+
module RSMP
|
4
|
+
module SiteBase
|
5
|
+
attr_reader :components
|
6
|
+
|
7
|
+
def initialize_site
|
8
|
+
@components = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def aggrated_status_changed component
|
12
|
+
end
|
13
|
+
|
14
|
+
def setup_components settings
|
15
|
+
return unless settings
|
16
|
+
settings.each_pair do |id,settings|
|
17
|
+
@components[id] = build_component(id,settings)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def build_component id, settings={}
|
22
|
+
Component.new id: id, node: self, grouped: true
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,220 @@
|
|
1
|
+
# Handles a supervisor connection to a remote client
|
2
|
+
|
3
|
+
module RSMP
|
4
|
+
class SiteProxy < Proxy
|
5
|
+
include SiteBase
|
6
|
+
|
7
|
+
attr_reader :supervisor
|
8
|
+
|
9
|
+
def initialize options
|
10
|
+
super options
|
11
|
+
initialize_site
|
12
|
+
@supervisor = options[:supervisor]
|
13
|
+
@settings = @supervisor.supervisor_settings.clone
|
14
|
+
end
|
15
|
+
|
16
|
+
def node
|
17
|
+
supervisor
|
18
|
+
end
|
19
|
+
|
20
|
+
def start
|
21
|
+
super
|
22
|
+
start_reader
|
23
|
+
end
|
24
|
+
|
25
|
+
def connection_complete
|
26
|
+
super
|
27
|
+
log "Connection to site #{@site_ids.first} established", level: :info
|
28
|
+
end
|
29
|
+
|
30
|
+
def process_message message
|
31
|
+
case message
|
32
|
+
when CommandRequest
|
33
|
+
when StatusRequest
|
34
|
+
when StatusSubscribe
|
35
|
+
when StatusUnsubscribe
|
36
|
+
will_not_handle message
|
37
|
+
when AggregatedStatus
|
38
|
+
process_aggregated_status message
|
39
|
+
when Alarm
|
40
|
+
process_alarm message
|
41
|
+
when CommandResponse
|
42
|
+
process_command_response message
|
43
|
+
when StatusResponse
|
44
|
+
process_status_response message
|
45
|
+
when StatusUpdate
|
46
|
+
process_status_update message
|
47
|
+
else
|
48
|
+
super message
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def version_accepted message, rsmp_version
|
53
|
+
log "Received Version message for sites [#{@site_ids.join(',')}] using RSMP #{rsmp_version}", message: message, level: :log
|
54
|
+
start_timer
|
55
|
+
acknowledge message
|
56
|
+
send_version rsmp_version
|
57
|
+
@version_determined = true
|
58
|
+
|
59
|
+
site_id = @site_ids.first
|
60
|
+
if @settings['sites']
|
61
|
+
@site_settings = @settings['sites'][site_id]
|
62
|
+
if @site_settings
|
63
|
+
setup_components @site_settings['components']
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def validate_aggregated_status message, se
|
69
|
+
unless se && se.is_a?(Array) && se.size == 8
|
70
|
+
reason = "invalid AggregatedStatus, 'se' must be an Array of size 8"
|
71
|
+
dont_acknowledge message, "Received", reaons
|
72
|
+
raise InvalidMessage
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def process_aggregated_status message
|
77
|
+
se = message.attribute("se")
|
78
|
+
validate_aggregated_status(message,se) == false
|
79
|
+
c_id = message.attributes["cId"]
|
80
|
+
component = @components[c_id]
|
81
|
+
if component == nil
|
82
|
+
if @site_settings == nil || @site_settings['components'] == nil
|
83
|
+
component = build_component c_id
|
84
|
+
log "Adding component #{c_id} to site #{site_id}", level: :info
|
85
|
+
else
|
86
|
+
reason = "component #{c_id} not found"
|
87
|
+
dont_acknowledge message, "Ignoring #{message.type}:", reason
|
88
|
+
return
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
component.set_aggregated_status_bools se
|
93
|
+
log "Received #{message.type} status for component #{c_id} [#{component.aggregated_status.join(', ')}]", message: message
|
94
|
+
acknowledge message
|
95
|
+
end
|
96
|
+
|
97
|
+
def aggrated_status_changed component
|
98
|
+
@supervisor.aggregated_status_changed self, component
|
99
|
+
end
|
100
|
+
|
101
|
+
def process_alarm message
|
102
|
+
alarm_code = message.attribute("aCId")
|
103
|
+
asp = message.attribute("aSp")
|
104
|
+
status = ["ack","aS","sS"].map { |key| message.attribute(key) }.join(',')
|
105
|
+
log "Received #{message.type}, #{alarm_code} #{asp} [#{status}]", message: message, level: :log
|
106
|
+
acknowledge message
|
107
|
+
end
|
108
|
+
|
109
|
+
def version_acknowledged
|
110
|
+
connection_complete
|
111
|
+
end
|
112
|
+
|
113
|
+
def process_watchdog message
|
114
|
+
super
|
115
|
+
if @watchdog_started == false
|
116
|
+
start_watchdog
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def site_ids_changed
|
121
|
+
@supervisor.site_ids_changed
|
122
|
+
end
|
123
|
+
|
124
|
+
def check_site_id site_id
|
125
|
+
@site_settings = @supervisor.check_site_id site_id
|
126
|
+
end
|
127
|
+
|
128
|
+
def request_status component, status_list, timeout=nil
|
129
|
+
raise NotReady unless @state == :ready
|
130
|
+
message = RSMP::StatusRequest.new({
|
131
|
+
"ntsOId" => '',
|
132
|
+
"xNId" => '',
|
133
|
+
"cId" => component,
|
134
|
+
"sS" => status_list
|
135
|
+
})
|
136
|
+
send_message message
|
137
|
+
return message, wait_for_status_response(component: component, timeout: timeout)
|
138
|
+
end
|
139
|
+
|
140
|
+
def process_status_response message
|
141
|
+
log "Received #{message.type}", message: message, level: :log
|
142
|
+
acknowledge message
|
143
|
+
end
|
144
|
+
|
145
|
+
def wait_for_status_response options
|
146
|
+
raise ArgumentError unless options[:component]
|
147
|
+
item = @archive.capture(@task, options.merge(type: "StatusResponse", with_message: true, num: 1)) do |item|
|
148
|
+
# check component
|
149
|
+
end
|
150
|
+
item[:message] if item
|
151
|
+
end
|
152
|
+
|
153
|
+
def subscribe_to_status component, status_list
|
154
|
+
raise NotReady unless @state == :ready
|
155
|
+
message = RSMP::StatusSubscribe.new({
|
156
|
+
"ntsOId" => '',
|
157
|
+
"xNId" => '',
|
158
|
+
"cId" => component,
|
159
|
+
"sS" => status_list
|
160
|
+
})
|
161
|
+
send_message message
|
162
|
+
message
|
163
|
+
end
|
164
|
+
|
165
|
+
def unsubscribe_to_status component, status_list
|
166
|
+
raise NotReady unless @state == :ready
|
167
|
+
message = RSMP::StatusUnsubscribe.new({
|
168
|
+
"ntsOId" => '',
|
169
|
+
"xNId" => '',
|
170
|
+
"cId" => component,
|
171
|
+
"sS" => status_list
|
172
|
+
})
|
173
|
+
send_message message
|
174
|
+
message
|
175
|
+
end
|
176
|
+
|
177
|
+
def process_status_update message
|
178
|
+
log "Received #{message.type}", message: message, level: :log
|
179
|
+
acknowledge message
|
180
|
+
end
|
181
|
+
|
182
|
+
def wait_for_status_update options={}
|
183
|
+
raise ArgumentError unless options[:component]
|
184
|
+
item = @archive.capture(options.merge(type: "StatusUpdate", with_message: true, num: 1)) do |item|
|
185
|
+
# check component
|
186
|
+
end
|
187
|
+
item[:message] if item
|
188
|
+
end
|
189
|
+
|
190
|
+
def send_command component, args
|
191
|
+
raise NotReady unless @state == :ready
|
192
|
+
message = RSMP::CommandRequest.new({
|
193
|
+
"ntsOId" => '',
|
194
|
+
"xNId" => '',
|
195
|
+
"cId" => component,
|
196
|
+
"arg" => args
|
197
|
+
})
|
198
|
+
send_message message
|
199
|
+
message
|
200
|
+
end
|
201
|
+
|
202
|
+
def process_command_response message
|
203
|
+
log "Received #{message.type}", message: message, level: :log
|
204
|
+
acknowledge message
|
205
|
+
end
|
206
|
+
|
207
|
+
def wait_for_command_response options
|
208
|
+
raise ArgumentError unless options[:component]
|
209
|
+
item = @archive.capture(@task,options.merge(num: 1, type: "CommandResponse", with_message: true)) do |item|
|
210
|
+
# check component
|
211
|
+
end
|
212
|
+
item[:message] if item
|
213
|
+
end
|
214
|
+
|
215
|
+
def set_watchdog_interval interval
|
216
|
+
@settings["watchdog_interval"] = interval
|
217
|
+
end
|
218
|
+
|
219
|
+
end
|
220
|
+
end
|
@@ -0,0 +1,220 @@
|
|
1
|
+
# RSMP supervisor (server)
|
2
|
+
# The supervisor waits for sites to connect.
|
3
|
+
# Connections to sites are handles via site proxies.
|
4
|
+
|
5
|
+
module RSMP
|
6
|
+
class Supervisor < Node
|
7
|
+
attr_reader :rsmp_versions, :site_id, :supervisor_settings, :proxies, :logger
|
8
|
+
|
9
|
+
def initialize options={}
|
10
|
+
handle_supervisor_settings options
|
11
|
+
super options.merge log_settings: @supervisor_settings["log"]
|
12
|
+
@proxies = []
|
13
|
+
@site_id_condition = Async::Notification.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def site_id
|
17
|
+
@supervisor_settings['site_id']
|
18
|
+
end
|
19
|
+
|
20
|
+
def handle_supervisor_settings options
|
21
|
+
@supervisor_settings = {
|
22
|
+
'site_id' => 'RN+SU0001',
|
23
|
+
'port' => 12111,
|
24
|
+
'rsmp_versions' => ['3.1.1','3.1.2','3.1.3','3.1.4'],
|
25
|
+
'timer_interval' => 0.1,
|
26
|
+
'watchdog_interval' => 1,
|
27
|
+
'watchdog_timeout' => 2,
|
28
|
+
'acknowledgement_timeout' => 2,
|
29
|
+
'command_response_timeout' => 1,
|
30
|
+
'status_response_timeout' => 1,
|
31
|
+
'status_update_timeout' => 1,
|
32
|
+
'site_connect_timeout' => 2,
|
33
|
+
'site_ready_timeout' => 1,
|
34
|
+
'log' => {
|
35
|
+
'active' => true,
|
36
|
+
'color' => true,
|
37
|
+
'ip' => false,
|
38
|
+
'timestamp' => true,
|
39
|
+
'site_id' => true,
|
40
|
+
'level' => false,
|
41
|
+
'acknowledgements' => false,
|
42
|
+
'watchdogs' => false,
|
43
|
+
'json' => false
|
44
|
+
}
|
45
|
+
}
|
46
|
+
|
47
|
+
if options[:supervisor_settings_path]
|
48
|
+
if File.exist? options[:supervisor_settings_path]
|
49
|
+
@supervisor_settings.merge! YAML.load_file(options[:supervisor_settings_path])
|
50
|
+
else
|
51
|
+
puts "Error: Site settings #{options[:supervisor_settings_path]} not found"
|
52
|
+
exit
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
if options[:supervisor_settings]
|
58
|
+
converted = options[:supervisor_settings].map { |k,v| [k.to_s,v] }.to_h #convert symbol keys to string keys
|
59
|
+
@supervisor_settings.merge! converted
|
60
|
+
end
|
61
|
+
|
62
|
+
required = [:port, :rsmp_versions, :site_id, :watchdog_interval, :watchdog_timeout,
|
63
|
+
:acknowledgement_timeout, :command_response_timeout, :log]
|
64
|
+
check_required_settings @supervisor_settings, required
|
65
|
+
|
66
|
+
@rsmp_versions = @supervisor_settings["rsmp_versions"]
|
67
|
+
|
68
|
+
# randomize site id
|
69
|
+
#@supervisor_settings["site_id"] = "RN+SU#{rand(9999).to_i}"
|
70
|
+
|
71
|
+
# randomize port
|
72
|
+
#@supervisor_settings["port"] = @supervisor_settings["port"] + rand(10).to_i
|
73
|
+
end
|
74
|
+
|
75
|
+
def start_action
|
76
|
+
@endpoint = Async::IO::Endpoint.tcp('0.0.0.0', @supervisor_settings["port"])
|
77
|
+
@endpoint.accept do |socket|
|
78
|
+
handle_connection(socket)
|
79
|
+
end
|
80
|
+
rescue SystemCallError => e # all ERRNO errors
|
81
|
+
log "Exception: #{e.to_s}", level: :error
|
82
|
+
rescue StandardError => e
|
83
|
+
log ["Exception: #{e.inspect}",e.backtrace].flatten.join("\n"), level: :error
|
84
|
+
end
|
85
|
+
|
86
|
+
def stop
|
87
|
+
log "Stopping supervisor #{@supervisor_settings["site_id"]}", level: :info
|
88
|
+
@proxies.each { |proxy| proxy.stop }
|
89
|
+
@proxies.clear
|
90
|
+
super
|
91
|
+
@tcp_server.close if @tcp_server
|
92
|
+
@tcp_server = nil
|
93
|
+
end
|
94
|
+
|
95
|
+
def handle_connection socket
|
96
|
+
remote_port = socket.remote_address.ip_port
|
97
|
+
remote_hostname = socket.remote_address.ip_address
|
98
|
+
remote_ip = socket.remote_address.ip_address
|
99
|
+
|
100
|
+
info = {ip:remote_ip, port:remote_port, hostname:remote_hostname, now:RSMP.now_string()}
|
101
|
+
if accept? socket, info
|
102
|
+
connect socket, info
|
103
|
+
else
|
104
|
+
reject socket, info
|
105
|
+
end
|
106
|
+
rescue SystemCallError => e # all ERRNO errors
|
107
|
+
log "Exception: #{e.to_s}", level: :error
|
108
|
+
rescue StandardError => e
|
109
|
+
log "Exception: #{e}", exception: e, level: :error
|
110
|
+
ensure
|
111
|
+
close socket, info
|
112
|
+
end
|
113
|
+
|
114
|
+
def starting
|
115
|
+
log "Starting supervisor #{@supervisor_settings["site_id"]} on port #{@supervisor_settings["port"]}",
|
116
|
+
level: :info,
|
117
|
+
timestamp: RSMP.now_object
|
118
|
+
end
|
119
|
+
|
120
|
+
def accept? socket, info
|
121
|
+
true
|
122
|
+
end
|
123
|
+
|
124
|
+
def build_connector settings
|
125
|
+
SiteProxy.new settings
|
126
|
+
end
|
127
|
+
|
128
|
+
def connect socket, info
|
129
|
+
if @supervisor_settings['log']['hide_ip_and_port']
|
130
|
+
port_and_port = '********'
|
131
|
+
else
|
132
|
+
port_and_port = "#{info[:ip]}:#{info[:port]}"
|
133
|
+
end
|
134
|
+
|
135
|
+
log "Site connected from #{port_and_port}",
|
136
|
+
ip: port_and_port,
|
137
|
+
level: :info,
|
138
|
+
timestamp: RSMP.now_object
|
139
|
+
|
140
|
+
proxy = build_connector({
|
141
|
+
supervisor: self,
|
142
|
+
task: @task,
|
143
|
+
settings: @supervisor_settings[:sites],
|
144
|
+
socket: socket,
|
145
|
+
info: info,
|
146
|
+
logger: @logger,
|
147
|
+
archive: @archive
|
148
|
+
})
|
149
|
+
@proxies.push proxy
|
150
|
+
|
151
|
+
proxy.run # will run until the site disconnects
|
152
|
+
@proxies.delete proxy
|
153
|
+
site_ids_changed
|
154
|
+
end
|
155
|
+
|
156
|
+
def site_ids_changed
|
157
|
+
@site_id_condition.signal
|
158
|
+
end
|
159
|
+
|
160
|
+
def reject socket, info
|
161
|
+
log "Site rejected", ip: info[:ip], level: :info
|
162
|
+
end
|
163
|
+
|
164
|
+
def close socket, info
|
165
|
+
if info
|
166
|
+
log "Connection to #{info[:ip]}:#{info[:port]} closed", ip: info[:ip], level: :info, timestamp: RSMP.now_object
|
167
|
+
else
|
168
|
+
log "Connection closed", level: :info, timestamp: RSMP.now_object
|
169
|
+
end
|
170
|
+
|
171
|
+
socket.close
|
172
|
+
end
|
173
|
+
|
174
|
+
def site_connected? site_id
|
175
|
+
return find_site(site_id) != nil
|
176
|
+
end
|
177
|
+
|
178
|
+
def find_site site_id
|
179
|
+
@proxies.each do |site|
|
180
|
+
return site if site_id == :any || site.site_ids.include?(site_id)
|
181
|
+
end
|
182
|
+
nil
|
183
|
+
end
|
184
|
+
|
185
|
+
def wait_for_site site_id, timeout
|
186
|
+
RSMP::Wait.wait_for(@task,@site_id_condition,timeout) { find_site site_id }
|
187
|
+
rescue Async::TimeoutError
|
188
|
+
nil
|
189
|
+
end
|
190
|
+
|
191
|
+
def wait_for_site_disconnect site_id, timeout
|
192
|
+
RSMP::Wait.wait_for(@task,@site_id_condition,timeout) { true unless find_site site_id }
|
193
|
+
rescue Async::TimeoutError
|
194
|
+
false
|
195
|
+
end
|
196
|
+
|
197
|
+
def check_site_id site_id
|
198
|
+
check_site_already_connected site_id
|
199
|
+
return find_allowed_site_setting site_id
|
200
|
+
end
|
201
|
+
|
202
|
+
def check_site_already_connected site_id
|
203
|
+
raise FatalError.new "Site #{site_id} already connected" if find_site(site_id)
|
204
|
+
end
|
205
|
+
|
206
|
+
def find_allowed_site_setting site_id
|
207
|
+
return {} unless @supervisor_settings['sites']
|
208
|
+
@supervisor_settings['sites'].each_pair do |id,settings|
|
209
|
+
if id == site_id
|
210
|
+
return settings
|
211
|
+
end
|
212
|
+
end
|
213
|
+
raise FatalError.new "site id #{site_id} rejected"
|
214
|
+
end
|
215
|
+
|
216
|
+
def aggregated_status_changed site_proxy, component
|
217
|
+
end
|
218
|
+
|
219
|
+
end
|
220
|
+
end
|