OSSIM项目研究记录(五)

本文介绍了ASECDBModelSuggestion类及其相关类,包括数据库连接管理、监听器设计和数据操作方法。ASEC类实现了连接数据库、设置锁以及增删查改Suggestion的功能,同时监听器用于检查数据库连接的活性。通过对数据库的连接重试机制和并发控制,确保了数据操作的稳定性和一致性。
摘要由CSDN通过智能技术生成

2021SC@SDUSC

源码分析之framework/ASECDBModel


Suggestion类

映射到asec

class AsecDb_Suggestion(Base):
    __tablename__ = 'suggestions'
    __table_args__= {
        'mysql_engine':'InnoDB',
        'mysql_charset':'utf8'
        }
    id=          Column(MEDIUMINT, primary_key=True)
    suggestion_group_id =   Column(BINARY(16),nullable=False)
    filename      = Column(VARCHAR(255),nullable=False)
    location     = Column(VARCHAR(255),nullable=False)
    datetime =  Column(DATETIME,default= datetime.now)

    def __repr__(self):
        return "<Suggestions('%s','%s','%s','%s')>" % (self.id,str(UUID(bytes=self.suggestion_group_id)),self.filename,self.location)

类侦听器

管理连接池中的连接,检查它们是否实际处于活动状态

class Listener (sqlalchemy.interfaces.PoolListener):
  def __init__(self):
    self.retried = False
  def checkout (self, dbapi_con, con_record, con_proxy):
    try:
      dbapi_con.cursor().execute('select now()')
    except _mysql_exceptions.OperationalError:
      if self.retried:
        self.retried = False
        raise
      self.retried = True
      raise sqlalchemy.exc.DisconnectionError
'''

类ASEC

定义了若干方法:
连接数据库,同时返回数据并设置锁
检索suggestionid作为输入参数传递的suggestion
获取suggestion
删除suggerstion

class ASECModel:
    __db_name = None
    __db_user = None
    __db_pass = None
  
    # Connect to database (call only once)
    def connect (self, db_host, db_name, db_user, db_pass):
        self.__db_host = db_host
        self.__db_name = db_name
        self.__db_user = db_user
        self.__db_pass = db_pass
  
        delay = 0
  
        # Try to connect 10 times
        for i in range(1, MAX_RETRIES + 1):
            time.sleep(delay)
            try:
                self.__engine = create_engine ('mysql+mysqldb://%s:%s@%s/%s' % (self.__db_user, self.__db_pass, self.__db_host, self.__db_name), echo=False, listeners = [Listener()], pool_size=10)
  
                # Create our sessionmaker class.
                Base.metadata.create_all (self.__engine)
                self.__SessionMaker = sessionmaker(bind=self.__engine)
                self.__session = self.__SessionMaker ()
                break
            except Exception, str:
                delay = i * 5
                logger.info ("Couldn't connect to ASEC DB, trying again in %d seconds" % delay)
  
        if i == MAX_RETRIES:
            logger.error ("Cannot connect to database, exiting...")
            return
        else:
            logger.info ("Connected to database")
  
        # Create locks to preven race conditions.
        self.__lock = Lock ()

    def set_sample_log(self,obj):
        return self.__set_data(obj)


    def set_alarm_coincidence(self,obj):
        return self.__set_data(obj)


    def __set_data(self,obj):
        obj_id = 0
        tries = 0
        while tries < MAX_RETRIES:
            if isinstance(obj,AsecDb_AlarmCoincidence) or \
               isinstance(obj,AsecDb_Notification) or \
               isinstance(obj,AsecDb_Suggestion) or \
               isinstance(obj,AsecDb_Suggestion_pattern):
                try:
                    self.__lock.acquire()
                    merged_data = self.__session.merge(obj)
                    self.__session.flush()
                    obj_id = obj.id
                    self.__session.commit()
                except Exception,msg:
                    self.__session.rollback ()
                    self.__lock.release ()
                    tries += 1
                    time.sleep(1)
                    continue
                else:
                    logger.debug ('Commited log')
                    self.__lock.release()
                    break
            else:
                logger.error ('Type of object is not AsecDb_SampleLog: %s' % type(obj))
        if tries >= MAX_RETRIES:
            logger.error ('Cannot commit new samplelog ')
            raise
        return obj_id


    def set_notification(self,obj):
        return self.__set_data(obj)


    def set_suggestion(self,obj):
        return self.__set_data(obj)

    def set_suggestion_pattern(self,obj):
        return self.__set_data(obj)


    def get_suggestion(self, suggestion_id):
        """Retrieves the suggestion with the suggestion group id passed as input param
        @param suggestion_id: The suggestion to look for.
        """
        tries = 0
        suggestion = None
        self.__lock.acquire ()
        while tries < MAX_RETRIES:
            try:
                suggestion = self.__session.query(AsecDb_Suggestion).filter(AsecDb_Suggestion.suggestion_group_id==UUID(suggestion_id).bytes).one()
                tries = MAX_RETRIES
            except _mysql_exceptions.OperationalError, (code, msg):
                self.__session.rollback ()
                self.__lock.release ()
                logger.error ("Unrecoverable error connecting to database: %s" % msg)
            except Exception, msg:
                self.__session.rollback ()
                tries += 1
                time.sleep (1)
                continue
        self.__lock.release ()
        return suggestion


    def get_suggestions_patterns(self,suggestion_id):
        tries = 0
        patterns = []
        self.__lock.acquire ()
        while tries < MAX_RETRIES:
            try:
                patterns = self.__session.query(AsecDb_Suggestion_pattern).\
                                            filter(AsecDb_Suggestion_pattern.suggestion_group_id==UUID(suggestion_id).bytes).all()
                tries = MAX_RETRIES
            except _mysql_exceptions.OperationalError, (code, msg):
                self.__session.rollback ()
                self.__lock.release ()
                logger.error ("Unrecoverable error connecting to database: %s" % msg)
            except Exception, msg:
                logger.error("Error: :%s"% str(msg))
                self.__session.rollback ()
                tries += 1
                time.sleep (1)
                continue
        self.__lock.release ()
        return patterns


    def delete_suggestion(self,suggestion_id):

        tries = 0
        self.__lock.acquire ()
        logger.info("Suggestion_id_ %s" % suggestion_id)
        while tries < MAX_RETRIES:
            try:
                sid_uuid = UUID(suggestion_id)
                self.__session.query(AsecDb_Suggestion_pattern).\
                                            filter(AsecDb_Suggestion_pattern.suggestion_group_id==sid_uuid.bytes).delete()
                self.__session.query(AsecDb_Suggestion).filter(AsecDb_Suggestion.suggestion_group_id==sid_uuid.bytes).delete()
                self.__session.flush()
                self.__session.commit()
                tries = MAX_RETRIES
            except _mysql_exceptions.OperationalError, (code, msg):
                self.__session.rollback ()
                self.__lock.release ()
                logger.error ("Unrecoverable error connecting to database: %s" % msg)
            except Exception, msg:
                logger.error("Error: %s"% str(msg))
                logger.error(traceback.format_exc())
                self.__session.rollback ()
                tries += 1
                time.sleep (1)
                continue
        self.__lock.release ()



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值