Class: RSMP::SiteProxy

Inherits:
Proxy
  • Object
show all
Includes:
Components, Modules::AggregatedStatus, Modules::Alarms, Modules::Commands, Modules::Status
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

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

#archive, #collector, #connection_info, #core_version, #ip, #port, #state, #sxl

Attributes included from Task

#task

Attributes included from Distributor

#receivers

Attributes included from Logging

#archive, #logger

Instance Method Summary collapse

Methods included from Modules::Commands

#process_command_response, #send_command

Methods included from Modules::Alarms

#process_alarm, #send_alarm_acknowledgement

Methods included from Modules::AggregatedStatus

#aggregated_status_changed, #process_aggregated_status, #request_aggregated_status, #validate_aggregated_status

Methods included from Modules::Status

#ensure_subscription_path, #process_status_response, #process_status_update, #remove_subscription_item, #request_status, #subscribe_to_status, #unsubscribe_to_status, #update_subscription

Methods included from Components

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

Methods inherited from Proxy

#author, #clear, #clock, #close, #close_socket, #close_stream, #connected?, #disconnect, #disconnected?, #log, #now, #ready?, #schemas, #setup, #state_changed, #stop_reader, #stop_subtasks, #stop_task, #stop_timer, version_meets_requirement?, #wait_for_reader

Methods included from Proxy::Modules::Tasks

#read_line, #run_reader, #run_timer, #start_reader, #start_timer, #timer

Methods included from Proxy::Modules::Versions

#check_core_version, #core_versions, #extraneous_version, #send_version, version_meets_requirement?

Methods included from Proxy::Modules::Receive

#expect_version_message, #handle_fatal_error, #handle_invalid_message, #handle_invalid_packet, #handle_malformed_message, #handle_schema_error, #process_deferred, #process_packet, #should_validate_ingoing_message?, #verify_sequence, #will_not_handle

Methods included from Proxy::Modules::Send

#apply_nts_message_attributes, #buffer_message, #handle_send_schema_error, #log_send, #send_and_optionally_collect, #send_message

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

Methods included from Task

#initialize_task, #restart, #start, #stop, #stop_subtasks, #stop_task, #task_status, #wait, #wait_for_condition

Methods included from Inspect

#inspector

Methods included from Distributor

#add_receiver, #clear_deferred_distribution, #distribute, #distribute_error, #distribute_immediately, #distribute_queued, #initialize_distributor, #remove_receiver, #with_deferred_distribution

Methods included from Logging

#author, #initialize_logging, #log

Constructor Details

#initialize(options) ⇒ SiteProxy

Returns a new instance of SiteProxy.



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

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

Instance Attribute Details

#site_idObject (readonly)

Returns the value of attribute site_id.



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

def site_id
  @site_id
end

#supervisorObject (readonly)

Returns the value of attribute supervisor.



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

def supervisor
  @supervisor
end

Instance Method Details

#acknowledged_first_ingoing(message) ⇒ Object



97
98
99
100
101
102
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 97

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

#acknowledged_first_outgoing(message) ⇒ Object



104
105
106
107
108
109
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 104

def acknowledged_first_outgoing(message)
  case message.type
  when 'Watchdog'
    handshake_complete
  end
end

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



191
192
193
194
195
196
197
198
199
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 191

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

#check_site_ids(message) ⇒ Object



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

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
  @supervisor.check_site_id site_id
  site_ids_changed
end

#check_sxl_version(message) ⇒ Object



125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 125

def check_sxl_version(message)
  # check that we have a schema for specified sxl type and version
  # note that the type comes from the site config, while the version
  # comes from the Version message send by the site
  type = @site_settings['sxl']
  version = message.attribute 'SXL'
  RSMP::Schema.find_schema! type, version, lenient: true

  # store sxl version requested by site
  # TODO should check agaist site settings
  @site_sxl_version = message.attribute 'SXL'
rescue RSMP::Schema::UnknownSchemaError => e
  dont_acknowledge message, "Rejected #{message.type} message,", e.to_s
end

#find_site_settings(_site_id) ⇒ Object



161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 161

def find_site_settings(_site_id)
  if @settings['sites'] && @settings['sites'][@site_id]
    log "Using site settings for site id #{@site_id}", level: :debug
    return @settings['sites'][@site_id]
  end

  @settings['guest']
  if @settings['guest']
    log 'Using site settings for guest', level: :debug
    return @settings['guest']
  end

  nil
end

#handled_by_parent?(message) ⇒ Boolean

Returns:

  • (Boolean)


85
86
87
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 85

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

#handshake_completeObject



52
53
54
55
56
57
58
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 52

def handshake_complete
  super
  sanitized_sxl_version = RSMP::Schema.sanitize_version(@site_sxl_version)
  log "Connection to site #{@site_id} established, using core #{@core_version}, #{@sxl} #{sanitized_sxl_version}",
      level: :info
  start_watchdog
end

#infer_component_type(_component_id) ⇒ Object



201
202
203
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 201

def infer_component_type(_component_id)
  ComponentProxy
end

#inspectObject



42
43
44
45
46
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 42

def inspect
  "#<#{self.class.name}:#{object_id}, #{inspector(
    :@acknowledgements, :@settings, :@site_settings, :@components
  )}>"
end

#nodeObject



48
49
50
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 48

def node
  supervisor
end

#process_message(message) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 60

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

  case message
  when StatusUnsubscribe, AggregatedStatusRequest
    will_not_handle message
  when AggregatedStatus
    process_aggregated_status 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
  else
    super
  end
rescue RSMP::RepeatedAlarmError, RSMP::RepeatedStatusError, RSMP::TimestampError => e
  str = "Rejected #{message.type} message,"
  dont_acknowledge message, str, e.to_s
  distribute_error e.exception("#{str}#{e.message} #{message.json}")
end

#process_version(message) ⇒ Object



146
147
148
149
150
151
152
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 146

def process_version(message)
  return extraneous_version message if @version_determined

  check_site_ids message
  check_sxl_version message
  version_accepted message
end

#receive_error(error, options = {}) ⇒ Object



186
187
188
189
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 186

def receive_error(error, options = {})
  @supervisor&.receive_error error, options
  distribute_error error, options
end

#revive(options) ⇒ Object



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

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

#runObject

handle communication when we’re created, the socket is already open



24
25
26
27
28
29
30
31
32
33
34
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 24

def run
  self.state = :connected
  start_reader
  wait_for_reader # run until disconnected
rescue RSMP::ConnectionError => e
  log e, level: :error
rescue StandardError => e
  distribute_error e, level: :internal
ensure
  close
end

#setup_site_settingsObject



176
177
178
179
180
181
182
183
184
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 176

def setup_site_settings
  @site_settings = find_site_settings @site_id
  if @site_settings
    @sxl = @site_settings['sxl']
    setup_components @site_settings['components']
  else
    dont_acknowledge message, 'Rejected', "No config found for site #{@site_id}"
  end
end

#site_ids_changedObject



117
118
119
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 117

def site_ids_changed
  @supervisor.site_ids_changed
end

#sxl_versionObject



140
141
142
143
144
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 140

def sxl_version
  # a supervisor does not maintain it's own sxl version
  # instead we use what the site requests
  @site_sxl_version
end

#validate_ready(action) ⇒ Object

Raises:



111
112
113
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 111

def validate_ready(action)
  raise NotReady, "Can't #{action} because connection is not ready. (Currently #{@state})" unless ready?
end

#version_accepted(message) ⇒ Object



89
90
91
92
93
94
95
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 89

def version_accepted(message)
  log "Received Version message for site #{@site_id}", message: message, level: :log
  start_timer
  acknowledge message
  send_version @site_id, core_versions
  @version_determined = true
end

#version_acknowledgedObject



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

def version_acknowledged; end

#watchdog_interval=(interval) ⇒ Object



121
122
123
# File 'lib/rsmp/proxy/site/site_proxy.rb', line 121

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