def __init__(self, host_and_port, device): super(OpenoltGrpc, self).__init__() log.debug('openolt grpc init') self.device = device self.host_and_port = host_and_port self.channel = grpc.insecure_channel(self.host_and_port) self.stub = openolt_pb2_grpc.OpenoltStub(self.channel)
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 __init__(self, **kwargs): super(OpenoltDevice, self).__init__() self.adapter_agent = kwargs['adapter_agent'] self.device_num = kwargs['device_num'] device = kwargs['device'] is_reconciliation = kwargs.get('reconciliation', False) self.device_id = device.id self.host_and_port = device.host_and_port self.log = structlog.get_logger(id=self.device_id, ip=self.host_and_port) self.nni_oper_state = dict() #intf_id -> oper_state self.proxy = registry('core').get_proxy('/') # Device already set in the event of reconciliation if not is_reconciliation: # It is a new device # Update device device.root = True device.serial_number = self.host_and_port # FIXME device.connect_status = ConnectStatus.REACHABLE device.oper_status = OperStatus.ACTIVATING self.adapter_agent.update_device(device) # Initialize the OLT state machine self.machine = Machine(model=self, states=OpenoltDevice.states, transitions=OpenoltDevice.transitions, send_event=True, initial='down', ignore_invalid_triggers=True) self.machine.add_transition(trigger='olt_ind_up', source='down', dest='up') self.machine.add_transition(trigger='olt_ind_loss', source='up', dest='down') # Initialize gRPC self.channel = grpc.insecure_channel(self.host_and_port) self.channel_ready_future = grpc.channel_ready_future(self.channel) self.stub = openolt_pb2_grpc.OpenoltStub(self.channel) self.flow_mgr = OpenOltFlowMgr(self.log, self.stub) # Indications thread plcaholder (started by heartbeat thread) self.indications_thread = None self.indications_thread_active = False # Start heartbeat thread self.heartbeat_thread = threading.Thread(target=self.heartbeat) self.heartbeat_thread.setDaemon(True) self.heartbeat_thread_active = True self.heartbeat_miss = 0 self.heartbeat_signature = None self.heartbeat_thread.start() self.log.debug('openolt-device-created', device_id=self.device_id)
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 do_state_init(self, event): # Initialize gRPC self.channel = grpc.insecure_channel(self.host_and_port) self.stub = openolt_pb2_grpc.OpenoltStub(self.channel) self.channel_ready_future = grpc.channel_ready_future(self.channel) self.alarm_mgr = BBSimOltAlarmMgr(self.log, self.adapter_agent, self.device_id, self.logical_device_id) self.stats_mgr = BBSimOltStatisticsMgr(self, self.log) self.bw_mgr = BBSimOltBW(self.log, self.proxy) self.log.info('openolt-device-created', device_id=self.device_id)
def __init__(self, **kwargs): super(OpenoltDevice, self).__init__() self.adapter_agent = kwargs['adapter_agent'] device = kwargs['device'] self.device_id = device.id self.host_and_port = device.host_and_port self.log = structlog.get_logger(id=self.device_id, ip=self.host_and_port) self.oper_state = 'unknown' self.nni_oper_state = dict() #intf_id -> oper_state self.onus = {} # Onu -> serial_number self.uni_port_num = 20 # FIXME # Create logical device ld = LogicalDevice( desc=ofp_desc(mfr_desc='FIXME', hw_desc='FIXME', sw_desc='FIXME', serial_num='FIXME', dp_desc='n/a'), switch_features=ofp_switch_features( n_buffers=256, n_tables=2, capabilities=(OFPC_FLOW_STATS | OFPC_TABLE_STATS | OFPC_GROUP_STATS | OFPC_PORT_STATS)), root_device_id=self.device_id) # FIXME ld_initialized = self.adapter_agent.create_logical_device( ld, dpid='de:ad:be:ef:fe:ed') # FIXME self.logical_device_id = ld_initialized.id # Update device device.root = True device.vendor = 'Edgecore' device.model = 'ASFvOLT16' device.serial_number = self.host_and_port # FIXME device.parent_id = self.logical_device_id device.connect_status = ConnectStatus.REACHABLE device.oper_status = OperStatus.ACTIVATING self.adapter_agent.update_device(device) # Initialize gRPC self.channel = grpc.insecure_channel(self.host_and_port) self.stub = openolt_pb2_grpc.OpenoltStub(self.channel) # Start indications thread self.indications_thread = threading.Thread( target=self.process_indication) self.indications_thread.daemon = True self.indications_thread.start()
def do_state_connected(self, event): self.log.debug("do_state_connected") device = self.adapter_agent.get_device(self.device_id) device.connect_status = ConnectStatus.REACHABLE self.adapter_agent.update_device(device) self.stub = openolt_pb2_grpc.OpenoltStub(self.channel) self.flow_mgr = OpenOltFlowMgr(self.log, self.stub, self.device_id) self.alarm_mgr = OpenOltAlarmMgr(self.log, self.adapter_agent, self.device_id, self.logical_device_id) self.stats_mgr = OpenOltStatisticsMgr(self, self.log) self.bw_mgr = OpenOltBW(self.log, self.proxy)
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 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 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')
def __init__(self, **kwargs): super(OpenoltDevice, self).__init__() self.adapter_agent = kwargs['adapter_agent'] self.device_num = kwargs['device_num'] device = kwargs['device'] is_reconciliation = kwargs.get('reconciliation', False) self.device_id = device.id self.host_and_port = device.host_and_port self.log = structlog.get_logger(id=self.device_id, ip=self.host_and_port) self.proxy = registry('core').get_proxy('/') # Device already set in the event of reconciliation if not is_reconciliation: # It is a new device # Update device device.root = True device.serial_number = self.host_and_port # FIXME device.connect_status = ConnectStatus.REACHABLE device.oper_status = OperStatus.ACTIVATING self.adapter_agent.update_device(device) # Initialize the OLT state machine self.machine = Machine(model=self, states=OpenoltDevice.states, transitions=OpenoltDevice.transitions, send_event=True, initial='down', ignore_invalid_triggers=True) self.machine.add_transition(trigger='olt_ind_up', source='down', dest='up') self.machine.add_transition(trigger='olt_ind_loss', source='up', dest='down') # If logical device does not exist create it if len(device.parent_id) == 0: dpid = '00:00:' + self.ip_hex(self.host_and_port.split(":")[0]) # Create logical OF device ld = LogicalDevice( root_device_id=self.device_id, switch_features=ofp_switch_features( n_buffers=256, # TODO fake for now n_tables=2, # TODO ditto capabilities=( # TODO and ditto OFPC_FLOW_STATS | OFPC_TABLE_STATS | OFPC_PORT_STATS | OFPC_GROUP_STATS))) ld_init = self.adapter_agent.create_logical_device(ld, dpid=dpid) self.logical_device_id = ld_init.id else: # logical device already exists self.logical_device_id = device.parent_id if is_reconciliation: self.adapter_agent.reconcile_logical_device( self.logical_device_id) # Initialize gRPC self.channel = grpc.insecure_channel(self.host_and_port) self.channel_ready_future = grpc.channel_ready_future(self.channel) self.stub = openolt_pb2_grpc.OpenoltStub(self.channel) self.flow_mgr = OpenOltFlowMgr(self.log, self.stub, self.device_id) # Indications thread plcaholder (started by heartbeat thread) self.indications_thread = None self.indications_thread_active = False # Start heartbeat thread self.heartbeat_thread = threading.Thread(target=self.heartbeat) self.heartbeat_thread.setDaemon(True) self.heartbeat_thread_active = True self.heartbeat_miss = 0 self.heartbeat_signature = None self.heartbeat_thread.start() if is_reconciliation: # Put state machine in state up reactor.callFromThread(self.olt_up, reconciliation=True) self.log.debug('openolt-device-created', device_id=self.device_id)