def do_state_connected(self, event): self.log.debug("do_state_connected") device = self.adapter_agent.get_device(self.device_id) self.stub = openolt_pb2_grpc.OpenoltStub(self.channel) device_info = self.stub.GetDeviceInfo(openolt_pb2.Empty()) self.log.info('Device connected', device_info=device_info) device.vendor = device_info.vendor device.model = device_info.model device.hardware_version = device_info.hardware_version device.firmware_version = device_info.firmware_version self.resource_manager = OpenOltResourceMgr(self.device_id, self.host_and_port, self.extra_args, device_info) self.flow_mgr = OpenOltFlowMgr(self.log, self.stub, self.device_id, self.logical_device_id, self.resource_manager) yield self._initialize_resource_manager_resource_pools() # TODO: check for uptime and reboot if too long (VOL-1192) device.connect_status = ConnectStatus.REACHABLE self.adapter_agent.update_device(device)
def reboot(self): self.log.debug('rebooting openolt device', device_id=self.device_id) try: self.stub.Reboot(openolt_pb2.Empty()) except Exception as e: self.log.error('something went wrong with the reboot', error=e) else: self.log.info('device rebooted')
def trigger_statistics_collection(self): try: self.stub.CollectStatistics(openolt_pb2.Empty()) except Exception as e: self.log.error('Error while triggering statistics collection', error=e) else: self.log.info('statistics requested')
def do_state_connected(self, event): self.log.debug("do_state_connected") device = self.adapter_agent.get_device(self.device_id) self.stub = openolt_pb2_grpc.OpenoltStub(self.channel) delay = 1 while True: try: device_info = self.stub.GetDeviceInfo(openolt_pb2.Empty()) break except Exception as e: reraise = True if delay > 120: self.log.error("gRPC failure too many times") else: self.log.warn("gRPC failure, retry in %ds: %s" % (delay, repr(e))) time.sleep(delay) delay += delay reraise = False if reraise: raise self.log.info('Device connected', device_info=device_info) self.create_logical_device(device_info) device.serial_number = self.serial_number self.resource_mgr = self.resource_mgr_class(self.device_id, self.host_and_port, self.extra_args, device_info) self.platform = self.platform_class(self.log, self.resource_mgr) self.flow_mgr = self.flow_mgr_class(self.adapter_agent, self.log, self.stub, self.device_id, self.logical_device_id, self.platform, self.resource_mgr) self.alarm_mgr = self.alarm_mgr_class(self.log, self.adapter_agent, self.device_id, self.logical_device_id, self.platform) self.stats_mgr = self.stats_mgr_class(self, self.log, self.platform) self.bw_mgr = self.bw_mgr_class(self.log, self.proxy) device.vendor = device_info.vendor device.model = device_info.model device.hardware_version = device_info.hardware_version device.firmware_version = device_info.firmware_version # TODO: check for uptime and reboot if too long (VOL-1192) device.connect_status = ConnectStatus.REACHABLE self.adapter_agent.update_device(device)
def reenable(self): self.log.debug('reenabling-olt') try: self.stub.ReenableOlt(openolt_pb2.Empty()) except Exception as e: self.log.error('Failure to reenable openolt device', error=e) else: self.log.info('openolt device reenabled') self.admin_state = "up"
def disable(self): self.log.debug('sending-deactivate-olt-message') try: # Send grpc call self.stub.DisableOlt(openolt_pb2.Empty()) self.admin_state = "down" self.log.info('openolt device disabled') except Exception as e: self.log.error('Failure to disable openolt device', error=e)
def reenable(self): self.log.debug('reenabling-olt', device_id=self.device_id) try: self.stub.ReenableOlt(openolt_pb2.Empty()) self.log.info('enabling-all-ports', device_id=self.device_id) self.adapter_agent.enable_all_ports(self.device_id) except Exception as e: self.log.error('Failure to reenable openolt device', error=e) else: self.log.info('openolt device reenabled')
def disable(self): self.log.debug('sending-deactivate-olt-message', device_id=self.device_id) try: # Send grpc call self.stub.DisableOlt(openolt_pb2.Empty()) # The resulting indication will bring the OLT down # self.go_state_down() self.log.info('openolt device disabled') except Exception as e: self.log.error('Failure to disable openolt device', error=e)
def indications_thread(self): self.log.debug('starting-indications-thread') self.log.debug('connecting to olt', device_id=self.device_id) self.channel_ready_future.result() # blocking call self.log.info('connected to olt', device_id=self.device_id) self.go_state_connected() self.indications = self.stub.EnableIndication(openolt_pb2.Empty()) while True: try: # get the next indication from olt ind = next(self.indications) except Exception as e: self.log.warn('gRPC connection lost', error=e) reactor.callFromThread(self.go_state_down) reactor.callFromThread(self.go_state_init) break else: self.log.debug("rx indication", indication=ind) # indication handlers run in the main event loop if ind.HasField('olt_ind'): reactor.callFromThread(self.olt_indication, ind.olt_ind) elif ind.HasField('intf_ind'): reactor.callFromThread(self.intf_indication, ind.intf_ind) elif ind.HasField('intf_oper_ind'): reactor.callFromThread(self.intf_oper_indication, ind.intf_oper_ind) elif ind.HasField('onu_disc_ind'): reactor.callFromThread(self.onu_discovery_indication, ind.onu_disc_ind) elif ind.HasField('onu_ind'): reactor.callFromThread(self.onu_indication, ind.onu_ind) elif ind.HasField('omci_ind'): reactor.callFromThread(self.omci_indication, ind.omci_ind) elif ind.HasField('pkt_ind'): reactor.callFromThread(self.packet_indication, ind.pkt_ind) elif ind.HasField('port_stats'): reactor.callFromThread( self.stats_mgr.port_statistics_indication, ind.port_stats) elif ind.HasField('flow_stats'): reactor.callFromThread( self.stats_mgr.flow_statistics_indication, ind.flow_stats) elif ind.HasField('alarm_ind'): reactor.callFromThread(self.alarm_mgr.process_alarms, ind.alarm_ind) else: self.log.warn('unknown indication type')
def process_indications(self): self.log.debug('starting-indications-thread') self.indications = self.stub.EnableIndication(openolt_pb2.Empty()) while self.indications_thread_active: try: # get the next indication from olt ind = next(self.indications) except Exception as e: self.log.warn('GRPC-connection-lost-stoping-indication-thread', error=e) self.indications_thread_active = False else: self.log.debug("rx indication", indication=ind) # indication handlers run in the main event loop if ind.HasField('olt_ind'): reactor.callFromThread(self.olt_indication, ind.olt_ind) elif ind.HasField('intf_ind'): reactor.callFromThread(self.intf_indication, ind.intf_ind) elif ind.HasField('intf_oper_ind'): reactor.callFromThread(self.intf_oper_indication, ind.intf_oper_ind) elif ind.HasField('onu_disc_ind'): reactor.callFromThread(self.onu_discovery_indication, ind.onu_disc_ind) elif ind.HasField('onu_ind'): reactor.callFromThread(self.onu_indication, ind.onu_ind) elif ind.HasField('omci_ind'): reactor.callFromThread(self.omci_indication, ind.omci_ind) elif ind.HasField('pkt_ind'): reactor.callFromThread(self.packet_indication, ind.pkt_ind) elif ind.HasField('port_stats'): reactor.callFromThread(self.port_statistics_indication, ind.port_stats) elif ind.HasField('flow_stats'): reactor.callFromThread(self.flow_statistics_indication, ind.flow_stats) else: self.log.warn('unknown indication type') self.log.debug('stopping-indications-thread', device_id=self.device_id)
def process_indication(self): self.indications = self.stub.EnableIndication(openolt_pb2.Empty()) while 1: # get the next indication from olt ind = next(self.indications) self.log.debug("rx indication", indication=ind) # schedule indication handlers to be run in the main event loop if ind.HasField('olt_ind'): reactor.callFromThread(self.olt_indication, ind.olt_ind) elif ind.HasField('intf_ind'): reactor.callFromThread(self.intf_indication, ind.intf_ind) elif ind.HasField('intf_oper_ind'): reactor.callFromThread(self.intf_oper_indication, ind.intf_oper_ind) elif ind.HasField('onu_disc_ind'): reactor.callFromThread(self.onu_discovery_indication, ind.onu_disc_ind) elif ind.HasField('onu_ind'): reactor.callFromThread(self.onu_indication, ind.onu_ind) elif ind.HasField('omci_ind'): reactor.callFromThread(self.omci_indication, ind.omci_ind)
def do_state_connected(self, event): self.log.debug("do_state_connected") device = self.adapter_agent.get_device(self.device_id) self.stub = openolt_pb2_grpc.OpenoltStub(self.channel) device_info = self.stub.GetDeviceInfo(openolt_pb2.Empty()) self.log.info('Device connected', device_info=device_info) self.create_logical_device(device_info) device.serial_number = self.serial_number self.resource_mgr = self.resource_mgr_class(self.device_id, self.host_and_port, self.extra_args, device_info) self.platform = self.platform_class(self.log, self.resource_mgr) self.flow_mgr = self.flow_mgr_class(self.adapter_agent, self.log, self.stub, self.device_id, self.logical_device_id, self.platform, self.resource_mgr) self.alarm_mgr = self.alarm_mgr_class(self.log, self.adapter_agent, self.device_id, self.logical_device_id, self.platform) self.stats_mgr = self.stats_mgr_class(self, self.log, self.platform) self.bw_mgr = self.bw_mgr_class(self.log, self.proxy) device.vendor = device_info.vendor device.model = device_info.model device.hardware_version = device_info.hardware_version device.firmware_version = device_info.firmware_version # TODO: check for uptime and reboot if too long (VOL-1192) device.connect_status = ConnectStatus.REACHABLE self.adapter_agent.update_device(device)
def do_state_connected(self, event): self.log.debug("do_state_connected") device = self.adapter_agent.get_device(self.device_id) device_info = self.stub.GetDeviceInfo(openolt_pb2.Empty()) self.log.info('Device connected', device_info=device_info) device.vendor = device_info.vendor device.model = device_info.model device.hardware_version = device_info.hardware_version device.firmware_version = device_info.firmware_version self.platform = BBSimOltPlatform(self.log) self.flow_mgr = BBSimOltFlowMgr(self.log, self.stub, self.device_id, self.logical_device_id) # TODO: use content of device_info for Resource manager (VOL-948) # TODO: check for uptime and reboot if too long (VOL-1192) device.connect_status = ConnectStatus.REACHABLE self.adapter_agent.update_device(device)
def process_indications(self): self.channel_ready_future.result() # blocks till gRPC connection is complete self.stub = openolt_pb2_grpc.OpenoltStub(self.channel) self.indications = self.stub.EnableIndication(openolt_pb2.Empty()) while True: # get the next indication from olt ind = next(self.indications) self.log.debug("rx indication", indication=ind) # schedule indication handlers to be run in the main event loop if ind.HasField('olt_ind'): reactor.callFromThread(self.olt_indication, ind.olt_ind) elif ind.HasField('intf_ind'): reactor.callFromThread(self.intf_indication, ind.intf_ind) elif ind.HasField('intf_oper_ind'): reactor.callFromThread(self.intf_oper_indication, ind.intf_oper_ind) elif ind.HasField('onu_disc_ind'): reactor.callFromThread(self.onu_discovery_indication, ind.onu_disc_ind) elif ind.HasField('onu_ind'): reactor.callFromThread(self.onu_indication, ind.onu_ind) elif ind.HasField('omci_ind'): reactor.callFromThread(self.omci_indication, ind.omci_ind) elif ind.HasField('pkt_ind'): reactor.callFromThread(self.packet_indication, ind.pkt_ind)
def process_indications(host_and_port): channel = grpc.insecure_channel(host_and_port) stub = openolt_pb2_grpc.OpenoltStub(channel) stream = stub.EnableIndication(openolt_pb2.Empty()) default_topic = 'openolt.ind-{}'.format(host_and_port.split(':')[0]) pktin_topic = 'openolt.pktin-{}'.format(host_and_port.split(':')[0]) while True: try: # get the next indication from olt ind = next(stream) except Exception as e: log.warn('openolt grpc connection lost', error=e) ind = openolt_pb2.Indication() ind.olt_ind.oper_state = 'down' kafka_send_pb(default_topic, ind) break else: log.debug("openolt grpc rx indication", indication=ind) if ind.HasField('pkt_ind'): kafka_send_pb(pktin_topic, ind) else: kafka_send_pb(default_topic, ind)
def heartbeat(self): self.channel_ready_future.result( ) # blocks till gRPC connection is complete while self.heartbeat_thread_active: try: heartbeat = self.stub.HeartbeatCheck(openolt_pb2.Empty(), timeout=GRPC_TIMEOUT) except Exception as e: self.heartbeat_miss += 1 self.log.warn('heartbeat-miss', missed_heartbeat=self.heartbeat_miss, error=e) if self.heartbeat_miss == MAX_HEARTBEAT_MISS: self.log.error('lost-connectivity-to-olt') #TODO : send alarm/notify monitoring system # Using reactor to synchronize update # flagging it as unreachable and in unknow state reactor.callFromThread( self.olt_down, oper_state=OperStatus.UNKNOWN, connect_state=ConnectStatus.UNREACHABLE) else: # heartbeat received if self.heartbeat_signature is None: # Initialize heartbeat signature self.heartbeat_signature = heartbeat.heartbeat_signature self.log.debug( 'heartbeat-signature', device_id=self.device_id, heartbeat_signature=self.heartbeat_signature) # Check if signature is different if self.heartbeat_signature != heartbeat.heartbeat_signature: # OLT has rebooted self.log.warn('OLT-was-rebooted', device_id=self.device_id) #TODO: notify monitoring system self.heartbeat_signature = heartbeat.heartbeat_signature else: self.log.debug('valid-heartbeat-received') if self.heartbeat_miss > MAX_HEARTBEAT_MISS: self.log.info('OLT-connection-restored') #TODO : suppress alarm/notify monitoring system # flagging it as reachable again reactor.callFromThread(self.olt_reachable) if not self.indications_thread_active: self.log.info('(re)starting-indications-thread') # reset indications thread self.indications_thread = threading.Thread( target=self.process_indications) self.indications_thread.setDaemon(True) self.indications_thread_active = True self.indications_thread.start() self.heartbeat_miss = 0 time.sleep(HEARTBEAT_PERIOD) self.log.debug('stopping-heartbeat-thread', device_id=self.device_id)
def indications_thread(self): self.log.debug('starting-indications-thread') self.log.debug('connecting to olt') self.stub = openolt_pb2_grpc.OpenoltStub(self.channel) timeout = 60 * 60 delay = 1 exponential_back_off = False while True: try: self.device_info = self.stub.GetDeviceInfo(openolt_pb2.Empty()) break except Exception as e: if delay > timeout: self.log.error("timed out connecting to olt") return else: self.log.warn("retry connecting to olt in %ds: %s" % (delay, repr(e))) time.sleep(delay) if exponential_back_off: delay += delay else: delay += 1 self.log.info('connected to olt', device_info=self.device_info) self.go_state_connected() self.indications = self.stub.EnableIndication(openolt_pb2.Empty()) while True: try: # get the next indication from olt ind = next(self.indications) except Exception as e: self.log.warn('gRPC connection lost', error=e) reactor.callFromThread(self.go_state_down) reactor.callFromThread(self.go_state_init) break else: self.log.debug("rx indication", indication=ind) if self.admin_state is "down": if ind.HasField('intf_oper_ind') \ and (ind.intf_oper_ind.type == "nni"): self.log.warn('olt is admin down, allow nni ind', admin_state=self.admin_state, indications=ind) else: self.log.warn('olt is admin down, ignore indication', admin_state=self.admin_state, indications=ind) continue # indication handlers run in the main event loop if ind.HasField('olt_ind'): reactor.callFromThread(self.olt_indication, ind.olt_ind) elif ind.HasField('intf_ind'): reactor.callFromThread(self.intf_indication, ind.intf_ind) elif ind.HasField('intf_oper_ind'): reactor.callFromThread(self.intf_oper_indication, ind.intf_oper_ind) elif ind.HasField('onu_disc_ind'): reactor.callFromThread(self.onu_discovery_indication, ind.onu_disc_ind) elif ind.HasField('onu_ind'): reactor.callFromThread(self.onu_indication, ind.onu_ind) elif ind.HasField('omci_ind'): reactor.callFromThread(self.omci_indication, ind.omci_ind) elif ind.HasField('pkt_ind'): reactor.callFromThread(self.packet_indication, ind.pkt_ind) elif ind.HasField('port_stats'): reactor.callFromThread( self.stats_mgr.port_statistics_indication, ind.port_stats) elif ind.HasField('flow_stats'): reactor.callFromThread( self.stats_mgr.flow_statistics_indication, ind.flow_stats) elif ind.HasField('alarm_ind'): reactor.callFromThread(self.alarm_mgr.process_alarms, ind.alarm_ind) else: self.log.warn('unknown indication type')