Guest User

Untitled

a guest
Jun 3rd, 2014
207
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. #
  4. # LookupSessionDB module
  5. #
  6. # $Id$
  7. #
  8. import logging
  9. from twisted.enterprise import adbapi
  10. from Base import Base, ParamError
  11.  
  12.  
  13. __version__ = "$Revision$"
  14.  
  15.  
  16. class LookupSessionDB(Base):
  17.     """LookupSessionDB module
  18.  
  19.    Module arguments (see output of getParams method):
  20.    param, recipient
  21.  
  22.    Check arguments:
  23.        data ... all input data in dict
  24.  
  25.    Check returns:
  26.        1 .... ok
  27.        0 .... undefined (default for this module)
  28.        -1 ... failed
  29.  
  30.    Examples:
  31.        # make instance of LookupSessionDB module
  32.        modules['lists_client_address'] = ( 'LookupSessionDB', {'table': 'recipient_results'} )
  33.    """
  34.  
  35.     PARAMS = { 'table': ('database where to dump the recipient results', 'recipient_results'),
  36.                }
  37.  
  38.     # copied from protocol.py
  39.     def _getDbPool(self):
  40.         if self.factory.config.get('databaseAPI') == None:
  41.            raise Exception("undefined databaseAPI")
  42.  
  43.         if self.dbPool == None:
  44.             self.dbPool = adbapi.ConnectionPool(self.factory.config.get('databaseAPI'),
  45.                                                 **self.factory.config.get('database_session'))
  46. #            self.dbPool.start()
  47.         return self.dbPool
  48.  
  49.     def _getDbConnection(self):
  50.         return self._getDbPool().connect()
  51.  
  52.     def start(self):
  53.         """Called when changing state to 'started'. Right now it is called
  54.        only when you start ppolicy daemon (but in future it can be called
  55.        e.g. during reloading configuration files).
  56.  
  57.        You can check here e.g. module parameters (test1, test2, ...)
  58.        if values defined in ppolicy.conf doesn't contain wrong values."""
  59.  
  60.         if self.factory == None:
  61.             raise ParamError("this module need reference to factory and database connection pool")
  62.  
  63.         table = self.getParam('table')
  64.         if table == None:
  65.             raise ParamError('table has to be specified for this module')
  66.  
  67.         self.dbPool = None
  68.  
  69.     def stop(self):
  70.         """Called when changing state to 'stopped'. As for start this is
  71.        called only during exit of ppolicy daemon.
  72.  
  73.        You can cleanly release resources used by this module (e.g. close
  74.        opened file hanles, network connections, ...)."""
  75.         pass
  76.  
  77.  
  78.     def hashArg(self, data, *args, **keywords):
  79.         """Compute hash from data which is then used as index
  80.        to the result cache. Changing this function in subclasses
  81.        and using only required fields for computing hash can
  82.        improve cache usage and performance.
  83.        arguments:
  84.            data -- input data
  85.            args -- array of arguments defined in ppolicy.conf
  86.            keywords -- dict of arguments defined in ppolicy.conf
  87.        example:
  88.            If your check method use only sender address than the result
  89.            is only dependend on this one parameter (and not on recipient,
  90.            client_address, ...). So for best cache performance you should
  91.            return value that depends only on sender address:
  92.  
  93.            return hash(data.get('sender', ''))
  94.  
  95.            If you return 0 it means that check method result will not
  96.            be cached.
  97.        """
  98.         return 0
  99.  
  100.  
  101.     def check(self, data, *args, **keywords):
  102.         """check request data againts policy and returns tuple of status
  103.        code and optional info. The meaning of status codes is folloving:
  104.            < 0 check failed
  105.            = 0 check uknown (e.g. required resource not available)
  106.            > 0 check succeded
  107.        parameters:
  108.            data -- input data
  109.            args -- array of arguments defined in ppolicy.conf
  110.            keywords -- dict of arguments defined in ppolicy.conf
  111.        """
  112.  
  113.         # default return values
  114.         ret, retEx = 0, None
  115.  
  116.         table = self.getParam('table')
  117.  
  118.         sql = "SELECT `res`, `resEx` FROM `%s` WHERE `instance` = '%s'" % (table, data.get('instance'))
  119.  
  120.         logging.getLogger().debug("sql: %s" % (sql))
  121.  
  122.         try:
  123.             conn = self._getDbConnection()
  124.             cursor = conn.cursor()
  125.             conn.commit()
  126.         except Exception, e:
  127.             logging.getLogger().error("database error %s" % (e))
  128.             ret, retEx = 0, "database error %s" % (e)
  129.         else:
  130.             retryCounter = 2
  131.  
  132.             while retryCounter > 0:
  133.                 try:
  134.                     retryCounter -= 1
  135.  
  136.                     cursor.execute(sql)
  137.  
  138.                     rows = cursor.fetchall()
  139.  
  140.                     for row in rows:
  141.                         logging.getLogger().debug(row)
  142.  
  143.                         if row[0] == 'OK':
  144.                             ret, retEx = 1, 0
  145.                             cursor.close()
  146.                             break
  147.  
  148.                     cursor.close()
  149.  
  150.                     # No exception until now, don't retry
  151.                     retryCounter = 0
  152.                 except Exception, e:
  153.                     if e.__class__.__name__ == 'OperationalError' and (e.args[0] == 2013 or e.args[0] == 2006):
  154.                         # Reconnect
  155.                         try:
  156.                             conn.ping(True)
  157.                         except:
  158.                             pass
  159.                         logging.getLogger().error("database error %s - reconnecting" % (e))
  160.                     else:
  161.                         try:
  162.                             cursor.close()
  163.                         except:
  164.                             pass
  165.  
  166.                         logging.getLogger().error("database error %s" % (e))
  167.  
  168.                         # Retry on MySQLdb.OperationalError, only
  169.                         retryCounter = 0
  170.  
  171.                         ret, retEx = 0, "database error %s" % (e)
  172.  
  173.         return ret, retEx
RAW Paste Data