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
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
|