Class: RSMP::SiteProxy

Inherits:
Proxy
  • Object
show all
Includes:
Components, Modules::AggregatedStatus, Modules::Alarms, Modules::Commands, Modules::Status, SiteProxyConnection, SiteSxlSelection
Defined in:
lib/rsmp/proxy/site/site_proxy.rb,
lib/rsmp/proxy/site/modules/alarms.rb,
lib/rsmp/proxy/site/modules/status.rb,
lib/rsmp/proxy/site/modules/commands.rb,
lib/rsmp/proxy/site/modules/aggregated_status.rb

Overview

Handles a supervisor-side proxy for a connected site.

Defined Under Namespace

Modules: Modules

Constant Summary

Constants inherited from Proxy

Proxy::WRAPPING_DELIMITER

Instance Attribute Summary collapse

Attributes included from Components

#components, #main

Attributes inherited from Proxy

#accepted_sxls, #archive, #collector, #connection_info, #core_version, #core_version_string, #ip, #port, #rejected_sxls, #session_id, #site_settings, #state, #sxl_interfaces, #sxls

Attributes included from Task

#task

Attributes included from Distributor

#receivers

Attributes included from Logging

#archive, #logger

Instance Method Summary collapse

Methods included from SiteSxlSelection

#check_sxl_version, #rejected_sxl, #select_legacy_sxl, #select_sxl, #select_sxls

Methods included from SiteProxyConnection

#connect, #open_socket, #reconnect_delay?, #run, #run_accepted_connection, #run_outbound_connection

Methods included from Modules::Commands

#command_collector_list, #process_command_response, #send_command, #send_command!, #send_command_and_collect, #send_command_and_collect!

Methods included from Modules::Alarms

#process_alarm, #resume_alarm, #resume_alarm!, #send_alarm_acknowledgement, #send_alarm_acknowledgement!, #suspend_alarm, #suspend_alarm!

Methods included from Modules::AggregatedStatus

#aggregated_status_changed, #process_aggregated_status, #request_aggregated_status, #request_aggregated_status!, #request_aggregated_status_and_collect, #request_aggregated_status_and_collect!, #validate_aggregated_status

Methods included from Modules::Status

#ensure_subscription_path, #process_status_response, #process_status_update, #remove_subscription_item, #request_status, #request_status!, #request_status_and_collect, #request_status_and_collect!, #subscribe_to_status, #subscribe_to_status!, #subscribe_to_status_and_collect, #subscribe_to_status_and_collect!, #unsubscribe_from_all, #unsubscribe_to_status, #unsubscribe_to_status!, #update_subscription

Methods included from Components

#add_component, #aggregated_status_changed, #check_main_component, #clear_alarm_timestamps, #component_list, #find_component, #initialize_components, #natural_sort_key, #setup_components

Methods inherited from Proxy

#author, #build_sxl_interfaces, #clear, #clock, #command_codes, #command_items, #connected?, #disconnected?, #inspect, #log, #multiple_command_codes?, #now, #primary_sxl, #ready?, #receive_alarms?, #reject_multiple_command_codes, #schemas, #setup, #state_changed, #sxl, #sxl_interface, #sxl_interface_for, #sxl_version, #tlc, version_meets_requirement?

Methods included from Proxy::Modules::Lifecycle

#begin_session, #close, #close_from_result, #close_socket, #close_stream, #connect!, #connection_end_failure, #disconnect, #disconnect!, #distribute_event, #publish_connection_attempt_failure, #stop_reader, #stop_subtasks, #stop_task, #stop_timer, #wait_for_reader

Methods included from Proxy::Modules::Tasks

#connection_read_failure, #log_processing_statistics, #process_received_line, #processing_speed, #read_protocol_line, #run_reader, #run_timer, #session_active?, #session_tasks, #start_reader, #start_timer, #timer, #wait_for_session

Methods included from Proxy::Modules::Versions

#advertised_core_versions, #check_core_version, #component_list_acknowledged, #configured_sxls, #core_3_3?, #core_versions, #extraneous_version, #normalized_core_versions, #primary_configured_sxl, #send_legacy_version_response, #send_version, #send_version_message, #send_version_request, #send_version_response, #site_id_items, #sxl_request_items, #valid_sxl_response?, #validate_sxl_response!, #version_items, #version_meets_requirement?, version_meets_requirement?, #version_message_attributes, #version_request_attributes, #version_response_sxls, #wire_core_version_aliases

Methods included from Proxy::Modules::Receive

#expect_version_message, #peer_failure, #process_deferred, #process_incoming_message, #process_packet, #publish_peer_failure, #reject_fatal_message, #reject_invalid_message, #reject_invalid_packet, #reject_malformed_packet, #reject_packet, #reject_processed_message, #should_validate_ingoing_message?, #verify_sequence, #will_not_handle

Methods included from Proxy::Modules::Send

#apply_nts_message_attributes, #buffer_message, #buffer_or_fail, #disconnected_send_result, #invalid_outbound_result, #log_send, #prepare_message, #recover_write_failure, #send_generated_message, #send_message, #send_message!, #send_message_and_collect, #send_message_and_collect!, #write_message, #write_protocol

Methods included from Proxy::Modules::Acknowledgements

#acknowledge, #check_ack_timeout, #check_ingoing_acknowledged, #check_outgoing_acknowledged, #dont_acknowledge, #dont_expect_acknowledgement, #expect_acknowledgement, #find_original_for_message, #log_acknowledgement_for_original, #log_acknowledgement_for_unknown, #process_ack, #process_not_ack, #status_subscribe_acknowledged

Methods included from Proxy::Modules::Watchdogs

#check_watchdog_timeout, #process_watchdog, #send_watchdog, #start_watchdog, #stop_watchdog, #watchdog_send_timer, #with_watchdog_disabled

Methods included from Proxy::Modules::State

#wait_for_state, #wait_for_state!

Methods included from Task

#initialize_task, #restart, #run, #start, #stop, #stop_subtasks, #stop_task, #task_status, #wait, #wait_for_condition, #wait_for_condition!, #wait_for_termination

Methods included from Distributor

#add_receiver, #clear_deferred_distribution, #distribute, #distribute_event, #distribute_immediately, #distribute_queued, #initialize_distributor, #inspect, #remove_receiver, #with_deferred_distribution

Methods included from Logging

#author, #initialize_logging, #log

Constructor Details

#initialize(options) ⇒ SiteProxy

Returns a new instance of SiteProxy.



14
15
16
17
18
19
20
21
22
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 14

def initialize(options)
  super(options.merge(node: options[:supervisor]))
  initialize_components
  @supervisor = options[:supervisor]
  @settings = @supervisor.supervisor_settings.clone
  @site_id = options[:site_id]
  @configured_site_settings = options[:site_settings]
  @status_subscriptions = {}
end

Instance Attribute Details

#site_idObject (readonly)

Returns the value of attribute site_id.



12
13
14
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 12

def site_id
  @site_id
end

#supervisorObject (readonly)

Returns the value of attribute supervisor.



12
13
14
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 12

def supervisor
  @supervisor
end

Instance Method Details

#acknowledged_first_ingoing(message) ⇒ Object



94
95
96
97
98
99
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 94

def acknowledged_first_ingoing(message)
  case message.type
  when 'Watchdog'
    send_watchdog
  end
end

#acknowledged_first_outgoing(message) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 101

def acknowledged_first_outgoing(message)
  case message.type
  when 'Watchdog'
    if core_3_3?
      @outgoing_watchdog_acknowledged = true
      handshake_complete if @component_list_received
    else
      handshake_complete
    end
  end
end

#build_component(id:, type:, settings: {}) ⇒ Object



214
215
216
217
218
219
220
221
222
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 214

def build_component(id:, type:, settings: {})
  settings ||= {}
  if type == 'main'
    ComponentProxy.new id: id, node: self, type: type, name: settings['name'], grouped: true,
                       ntsoid: settings['ntsOId'], xnid: settings['xNId']
  else
    ComponentProxy.new id: id, node: self, type: type, name: settings['name'], grouped: false
  end
end

#check_site_ids(message) ⇒ Object



174
175
176
177
178
179
180
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 174

def check_site_ids(message)
  # RSMP support multiple site ids. we don't support this yet. instead we use the first id only
  site_id = message.attribute('siteId').map { |item| item['sId'] }.first
  @site_id ||= site_id
  @supervisor.check_site_id site_id
  site_ids_changed
end

#find_site_settings(_site_id) ⇒ Object



182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 182

def find_site_settings(_site_id)
  base = @settings['default'] || {}

  if @settings['sites']
    site_specific = @settings['sites'][@site_id] || @settings['sites']['default']
    if site_specific
      label = @settings['sites'][@site_id] ? "site id #{@site_id}" : 'default'
      log "Using #{label} site settings", level: :debug
      return base.deep_merge(site_specific)
    end
  end

  unless base.empty?
    log 'Using default site settings', level: :debug
    return base
  end

  nil
end

#handle_interface_message(message) ⇒ Object



65
66
67
68
69
70
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 65

def handle_interface_message(message)
  interface = sxl_interface_for message
  interface.validate_message! message
  record_interface_message message
  interface.process_message message
end

#handled_by_parent?(message) ⇒ Boolean

Returns:



61
62
63
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 61

def handled_by_parent?(message)
  message.is_a?(CommandRequest) || message.is_a?(StatusRequest) || message.is_a?(StatusSubscribe)
end

#handshake_completeObject



35
36
37
38
39
40
41
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 35

def handshake_complete
  super
  sxl_summary = accepted_sxls.map { |item| "#{item['name']} #{item['version']}" }.join(', ')
  log "Connection to site #{@site_id} established, using core #{@core_version}, SXLs [#{sxl_summary}]",
      level: :info
  start_watchdog
end

#infer_component_type(_component_id) ⇒ Object



224
225
226
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 224

def infer_component_type(_component_id)
  ComponentProxy
end

#nodeObject



31
32
33
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 31

def node
  supervisor
end

#process_component_list(message) ⇒ Object



130
131
132
133
134
135
136
137
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 130

def process_component_list(message)
  log "Received #{message.type}", message: message, level: :log
  rebuild_components_from_list message.attributes['components']
  build_sxl_interfaces
  acknowledge message
  @component_list_received = true
  handshake_complete if @outgoing_watchdog_acknowledged
end

#process_message(message) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 43

def process_message(message)
  return super if handled_by_parent?(message)

  case message
  when StatusUnsubscribe, AggregatedStatusRequest
    will_not_handle message
  when ComponentList
    process_component_list message
  when AggregatedStatus
    process_aggregated_status message
  when AlarmIssue, AlarmSuspended, AlarmResumed, AlarmAcknowledged,
       CommandResponse, StatusResponse, StatusUpdate
    handle_interface_message message
  else
    super
  end
end

#process_version(message) ⇒ Object



165
166
167
168
169
170
171
172
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 165

def process_version(message)
  return extraneous_version message if @version_determined

  check_site_ids message
  check_core_version message
  check_sxl_version message
  version_accepted message
end

#rebuild_components_from_list(items) ⇒ Object



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 139

def rebuild_components_from_list(items)
  main_id = @site_settings.dig('components', 'main')&.keys&.first
  @components = {}
  @main = nil
  items.each do |item|
    grouped = item['id'] == main_id
    component = ComponentProxy.new(
      id: item['id'],
      node: self,
      type: item['type'],
      name: item['name'],
      grouped: grouped
    )
    @components[component.c_id] = component
    @main = component if grouped
  end
end

#record_interface_message(message) ⇒ Object



72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 72

def record_interface_message(message)
  case message
  when AlarmIssue, AlarmSuspended, AlarmResumed, AlarmAcknowledged
    process_alarm message
  when CommandResponse
    process_command_response message
  when StatusResponse
    process_status_response message
  when StatusUpdate
    process_status_update message
  end
end

#revive(options) ⇒ Object



24
25
26
27
28
29
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 24

def revive(options)
  super
  @supervisor = options[:supervisor]
  @settings = @supervisor.supervisor_settings.clone
  @configured_site_settings = options[:site_settings]
end

#setup_site_settingsObject



202
203
204
205
206
207
208
209
210
211
212
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 202

def setup_site_settings
  @site_settings = @configured_site_settings || find_site_settings(@site_id)
  if @site_settings
    @sxls = configured_sxls
    @accepted_sxls = @sxls.dup
    build_sxl_interfaces
    setup_components @site_settings['components']
  else
    dont_acknowledge message, 'Rejected', "No config found for site #{@site_id}"
  end
end

#site_ids_changedObject



157
158
159
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 157

def site_ids_changed
  @supervisor.site_ids_changed
end

#validate_ready(action) ⇒ Object



113
114
115
116
117
118
119
120
121
122
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 113

def validate_ready(action)
  return Result.success(self) if ready?

  Result.failure(
    :not_ready,
    message: "Can't #{action} because connection is not ready. (Currently #{@state})",
    source: :connection,
    context: { action: action, state: @state, session_id: session_id }
  )
end

#validate_ready!(action) ⇒ Object



124
125
126
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 124

def validate_ready!(action)
  validate_ready(action).value!
end

#version_accepted(message) ⇒ Object



85
86
87
88
89
90
91
92
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 85

def version_accepted(message)
  log "Received Version message for site #{@site_id}", message: message, level: :log
  start_timer
  acknowledge message
  response_id = core_3_3? ? (@supervisor.site_id || @site_id) : @site_id
  send_version_response response_id, core_versions
  @version_determined = true
end

#version_acknowledgedObject



128
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 128

def version_acknowledged; end

#watchdog_interval=(interval) ⇒ Object



161
162
163
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 161

def watchdog_interval=(interval)
  @settings['intervals']['watchdog'] = interval
end