Ejemplo n.º 1
0
    def __send_request_to_ne(self):
        """
        Method: __send_request_to_ne
        Description: 发送导出命令给网元
        Parameter: 无
        Return: 
        Others: 
        """

        ne_pid = NEInfoMgr.get_ne_pid_by_id(self.ne_id)
        if ne_pid is None:
            tracelog.error("get_ne_pid_by_id(%d) failed." % self.ne_id)
            return 

        req = db_sync_base.SyncFullRequest()
        req.ne_id = self.ne_id
        req.ftp_ip = self.get_worker().get_app().get_device_cfg_info().get_device_external_ip()
        req.ftp_port = db_sync_update_const.FTP_SERVER_PORT
        req.file_path = db_sync_update_const.NE_DB_DUMP_COMPRESSED_PATH % self.ne_id  # 位于data/ftp目录中
        req.ftp_user = "******" # TODO
        req.ftp_pwd = "ftp_user" # TODO

       
        frame = bf.AppFrame()
        frame.set_cmd_code(cmd_code_def.CMD_SYNC_NE_EXP_FULL)
        frame.add_data(req.serialize())
        frame.set_receiver_pid(ne_pid)

        
        
        frame.set_next_pid(self.get_worker().get_pid("EAUGate"))

        mocs = self.get_worker().get_app().get_synchronized_mocs()
        timeout = len(mocs)*400 + 400
        self.wait_for_ack(frame, timeout) # 超时时间,单位秒
Ejemplo n.º 2
0
 def __handle_full_sync_ntf(self, frame, ne_id, sync_object, event):
     """
     Method: __handle_full_sync_ntf
     Description: 处理全同步事件通知
     Parameter:
         frame: 数据帧
         ne_id: 网元的ID
         sync_object: 同步传输对象
         event: 事件通知
     Return: 
     Others: 
     """
     
     tracelog.info('receive full sync notification from NE(%d)' % ne_id)
     
     error_code = NEInfoMgr.set_ne_need_sync_full(ne_id
                 , self.get_worker().get_app().get_mit_manager()
                 , True)
                 
     if error_code != 0:
         tracelog.error("set_ne_need_sync_full() failed: %d" % error_code)
         # 不给EAU回应答;EAU收到收不到应答后,下次重试
         return
         
     result = DBSyncResult()
     result.id = sync_object.id
     result.return_code = error_code
     result.error_message = ''
     result.event_ids = []
     self.__send_ack(frame, result.serialize())
Ejemplo n.º 3
0
    def handle_cmd(self, frame):
        """
        Method:    handle_cmd
        Description: 处理消息
        Parameter: 
            frame: AppFrame
        Return: 
        Others: 
        """
        ne_id = int(frame.get_data())
        self.ne_id = ne_id

        # 获取内存中的状态
        # 如果已经在同步了,那么就不用理会本次请求
        ret = NEInfoMgr.change_ne_state_to_exp(ne_id, self.get_worker().get_mit())        
        if ret != 0:
            tracelog.error("can not start sync full task. ne_id: %d" % ne_id)
            return
        
        tracelog.info("start sync full, ne_id:%d" % ne_id)

        # 如果不存在需要同步的MOC,那么就直接退出
        mocs = self.get_worker().get_app().get_synchronized_mocs()
        if len(mocs) == 0:
            tracelog.info("NE has no MOC to sync, ne_id:%d" % ne_id)
            NEInfoMgr.change_ne_state_to_normal(self.ne_id
                                                , self.get_worker().get_mit()
                                                , False)
            return
            
        if self.__prepare_file_dir() != 0:
            tracelog.error("can not start sync full task. ne_id: %d" % ne_id)
            self.__change_ne_state_when_exp_failed(True)
            return

        
        # 获取NE的pid,向其发起同步
        self.__send_request_to_ne()
Ejemplo n.º 4
0
    def _on_round_over(self, round_id, r):
        """
        Method:    _on_round_over
        Description: 响应round结束的事件
        Parameter: 
            round_id: round的id
            r: round对象
        Return: 
        Others: 
        """
        try:
            frame = r.get_response_frame()            
            rep = db_sync_base.SyncFullResponse.deserialize(frame.get_data())                           
        except:        
            tracelog.exception("_on_round_over error, NE id:%d" % self.ne_id)
            self.__change_ne_state_when_exp_failed(True)
            return

        if rep.return_code == err_code_mgr.ER_SYNC_NO_TABLE_NEED_SYNC:
            tracelog.info("the NE has no table to sync.")
            # 这种情况下,直接认为同步结束,并且不用再重试
            self.__change_ne_state_when_exp_failed(False)
            return
            
        
        if rep.return_code != 0:
            tracelog.error("NE export data failed. ne id:%d, error:%d,%s" % (
                              self.ne_id
                            , rep.return_code
                            , rep.description))
                            
            self.__change_ne_state_when_exp_failed(True)
            return
        
        tracelog.info("NE export data ok. ne id:%d" % (self.ne_id))

        # 将NE的状态修改为导入中
        ret = NEInfoMgr.change_ne_state_to_imp(self.ne_id
                                               , self.get_worker().get_mit())
        if ret != 0:
            tracelog.error("change_ne_state_to_imp failed. ne_id:%d" % self.ne_id)
        
        
        # 开始执行导入
        frame = bf.AppFrame()
        frame.set_cmd_code(cmd_code_def.CMD_START_IMP_FULL)
        frame.add_data(str(self.ne_id))
        self.get_worker().dispatch_frame_to_worker("SyncFullImpWorker", frame)
Ejemplo n.º 5
0
    def __change_ne_state_when_exp_failed(self, need_retry):
        """
        Method: __change_ne_state_when_exp_failed
        Description: 当网元导出失败时,修改网元状态
        Parameter: 
            need_retry: 是否需要下次全同步
        Return: 
        Others: 
        """

        ret = NEInfoMgr.change_ne_state_to_normal(self.ne_id
                                                , self.get_worker().get_mit()
                                                , need_retry)
        if ret != 0:
            tracelog.error("__change_ne_state_when_exp_failed failed."
                            "ne_id:%d" % self.ne_id)
Ejemplo n.º 6
0
    def __change_ne_state_when_imp_ok(self):
        """
        Method: __change_ne_state_when_imp_ok
        Description: 当导入网元的数据成功时修改网元的状态
        Parameter: 无
        Return: 
        Others: 
        """

        ret = NEInfoMgr.change_ne_state_to_normal(self.ne_id
                                            , self.get_worker().get_mit()
                                            , False)  

        if ret != 0:
            tracelog.error("__change_ne_state_when_imp_failed failed."
                            "ne_id:%d" % self.ne_id)
Ejemplo n.º 7
0
    def handle_cmd(self, frame):
        """
        Method: handle_cmd
        Description: 同步消息处理函数
        Parameter:
            frame: 请求消息
        Return: 无
        Others:
        """
        buf = frame.get_data()
        tracelog.info('received data from client at %s' % datetime.datetime.now().isoformat())
        ne_id = NEInfoMgr.get_ne_id_by_pid(frame.get_sender_pid())

        if ne_id is None:
            tracelog.error("received unknow data sync notification from NE, "
                            "pid:%d" % frame.get_sender_pid())
            return

        debug.info('ne id: %d' % (ne_id))

        # 如果网元正处于全同步中,那么直接忽视本次事件通知
        if not NEInfoMgr.is_ne_state_normal(ne_id):
            tracelog.info('database is full-synchonizing')
            return

        sync_object = DBSyncObject.deserialize(buf)
        result = DBSyncResult()
        result.id = sync_object.id
        debug.info('sync object id: %d' % sync_object.id)
       
        for event in sync_object.sync_events:
            if event.type == DBSyncType.FULL:
                self.__handle_full_sync_ntf(frame, ne_id, sync_object, event)
                self.get_worker().get_app().set_sync_sn(ne_id, event.priority, event.id)
                return

        events = []
        for event in sync_object.sync_events:
            sync_sn = self.get_worker().get_app().get_sync_sn(ne_id, event.priority)
            debug.info('ne_id: %d, priority: %d, event_id: %d sync_sn: %d' % (ne_id, event.priority, event.id, sync_sn))
            if event.id <= sync_sn:
                #该Event已经同步成功,重复提交将被忽略
                tracelog.info('event#%d was already synchonized.current sn: %d' % (event.id, sync_sn))
                result.event_ids.append(event.id)
            else:
                events.append(event)

        manager = self.get_worker().get_app().get_data_manager()
        debug.info('incremental sync starts')
        ret_code = manager.sync_data(events, ne_id)
        if ret_code != DBSyncStatus.ERROR_SUCCESS:
            tracelog.info('sync data failed. exit code: %d' % ret_code)
            if ret_code == DBSyncStatus.ERROR_CONFLICT:
                # 将EAU的状态设置为需要全同步
                NEInfoMgr.set_ne_need_sync_full(ne_id
                       , self.get_worker().get_app().get_mit_manager()
                       , True)
            # 不给EAU回应答;EAU收到收不到应答超时后,下次重试
            return

        for event in events:
            self.get_worker().get_app().set_sync_sn(ne_id, event.priority, event.id)
            debug.info('  event#%04d: return %d' % (event.id, ret_code))
            result.event_ids.append(event.id)

        self.__send_ack(frame, result.serialize())
        tracelog.info(result.event_ids)
        tracelog.info('sync processing completed.')