Beispiel #1
0
 def _update( self, cmd, conn=False ):
   start = time.time()
   ret = DB._update( self, cmd, conn )
   if DEBUG:
     print >> debugFile, time.time() - start, cmd.replace('\n','')
     debugFile.flush()
   return ret
Beispiel #2
0
 def _update(self, cmd, conn=False):
     start = time.time()
     ret = DB._update(self, cmd, conn)
     if DEBUG:
         print >> debugFile, time.time() - start, cmd.replace('\n', '')
         debugFile.flush()
     return ret
Beispiel #3
0
 def _update( self, cmd, conn=False ):
   """ Update MPIJob Database
   """ 
   print "DB4"
   start = Time.time()
   ret = DB._update( self, cmd, conn )
   if DEBUG:
     print >> debugFile, Time.time() - start, cmd.replace('\n','')
     debugFile.flush()
   print ret
   return ret
Beispiel #4
0
 def _update(self, cmd, conn=False):
     """ Update MPIJob Database
 """
     print "DB4"
     start = Time.time()
     ret = DB._update(self, cmd, conn)
     if DEBUG:
         print >> debugFile, Time.time() - start, cmd.replace('\n', '')
         debugFile.flush()
     print ret
     return ret
class ResourceManagementDB:
  """ 
  The ResourceManagementDB class is a front-end to the Resource Management Database.
  
  The simplest way to instantiate an object of type :class:`ResourceManagementDB` 
  is simply by calling 

   >>> rpDB = ResourceManagementDB()

  This way, it will use the standard :mod:`DIRAC.Core.Base.DB`. 
  But there's the possibility to use other DB classes. 
  For example, we could pass custom DB instantiations to it, 
  provided the interface is the same exposed by :mod:`DIRAC.Core.Base.DB`.

   >>> AnotherDB = AnotherDBClass()
   >>> rmDB = ResourceManagementDB(DBin = AnotherDB)

  Alternatively, for testing purposes, you could do:

   >>> from DIRAC.ResourceStatusSystem.Utilities.mock import Mock
   >>> mockDB = Mock()
   >>> rmDB = ResourceManagementDB(DBin = mockDB)

  Or, if you want to work with a local DB, providing it's mySQL:

   >>> rmDB = ResourceManagementDB(DBin = ['UserName', 'Password'])

  """

  
  def __init__(self, *args, **kwargs):

    if len(args) == 1:
      if isinstance(args[0], str):
#        systemInstance=args[0]
        maxQueueSize=10
      if isinstance(args[0], int):
        maxQueueSize=args[0]
#        systemInstance='Default'
    elif len(args) == 2:
#      systemInstance=args[0]
      maxQueueSize=args[1]
    elif len(args) == 0:
#      systemInstance='Default'
      maxQueueSize=10
    
    if 'DBin' in kwargs.keys():
      DBin = kwargs['DBin']
      if isinstance(DBin, list):
        from DIRAC.Core.Utilities.MySQL import MySQL
        self.db = MySQL('localhost', DBin[0], DBin[1], 'ResourceManagementDB')
      else:
        self.db = DBin
    else:
      from DIRAC.Core.Base.DB import DB
      self.db = DB('ResourceManagementDB','ResourceStatus/ResourceManagementDB',maxQueueSize) 
#      self.db = DB('ResourceStatusDB','ResourceStatus/ResourceStatusDB',maxQueueSize)


#############################################################################

#############################################################################
# Policy functions
#############################################################################

#############################################################################

  def addOrModifyPolicyRes(self, granularity, name, policyName, 
                           status, reason, dateEffective = None):
    """
    Add or modify a Policy Result to the PolicyRes table.
    
    :params:
      :attr:`granularity`: string - a ValidRes
      see :mod:`DIRAC.ResourceStatusSystem.Utilities.Utils`
    
      :attr:`name`: string - name of the ValidRes
      
      :attr:`policyName`: string - the policy name
    
      :attr:`status`: string - a ValidStatus: 
      see :mod:`DIRAC.ResourceStatusSystem.Utilities.Utils`
      
      :attr:`reason`: string - free
      
      :attr:`dateEffective`: datetime.datetime - 
      date from which the result is effective
    """
    
    now = datetime.datetime.utcnow().replace(microsecond = 0).isoformat(' ')
    
    if dateEffective is None:
      dateEffective = now
    
    req = "SELECT Granularity, Name, PolicyName, Status, Reason FROM PolicyRes "
    req = req + "WHERE Granularity = '%s' AND Name = '%s' AND " %(granularity, name)
    req = req + "PolicyName = '%s'" %(policyName)
    resQuery = self.db._query(req)
    if not resQuery['OK']:
      raise RSSManagementDBException, where(self, self.addOrModifyPolicyRes) + resQuery['Message']

    if resQuery['Value']: 
      req = "UPDATE PolicyRes SET "
      if resQuery['Value'][0][3] != status:
        req = req + "Status = '%s', Reason = '%s', DateEffective = '%s', " %(status, reason, dateEffective)
      elif resQuery['Value'][0][4] != reason:
        req = req + "Reason = '%s', " %(reason)
      req = req + "LastCheckTime = '%s' WHERE Granularity = '%s' " %(now, granularity)
      req = req + "AND Name = '%s' AND PolicyName = '%s'" %(name, policyName)
      
      resUpdate = self.db._update(req)
      if not resUpdate['OK']:
        raise RSSManagementDBException, where(self, self.addOrModifyPolicyRes) + resUpdate['Message']
    else:
      req = "INSERT INTO PolicyRes (Granularity, Name, PolicyName, Status, Reason, DateEffective, "
      req = req + "LastCheckTime) VALUES ('%s', '%s', '%s', " %(granularity, name, policyName)
      req = req + "'%s', '%s', '%s', '%s')" %(status, reason, dateEffective, now)
      resUpdate = self.db._update(req)
      if not resUpdate['OK']:
        raise RSSManagementDBException, where(self, self.addOrModifyPolicyRes) + resUpdate['Message']
    
#############################################################################

  def getPolicyRes(self, name, policyName, lastCheckTime = False):
    """ 
    Get a Policy Result from the PolicyRes table.
    
    :params:
      :attr:`name`: string - name of the ValidRes
      
      :attr:`policyName`: string - the policy name
      
      :attr:`lastCheckTime`: optional - if TRUE, it will get also the 
      LastCheckTime 
    """
    
    req = "SELECT Status, Reason"
    if lastCheckTime:
      req = req + ", LastCheckTime"  
    req = req + " FROM PolicyRes WHERE"
    req = req + " Name = '%s' AND PolicyName = '%s'" %(name, policyName)

    resQuery = self.db._query(req)
    if not resQuery['OK']:
      raise RSSManagementDBException, where(self, self.getPolicyRes) + resQuery['Message']
    if not resQuery['Value']:
      return []
    
    return resQuery['Value'][0]
    
#############################################################################

#############################################################################
# ClientsCache functions
#############################################################################
  
#############################################################################
  
  def addOrModifyClientsCacheRes(self, name, commandName, value, result, 
                                 opt_ID = None, dateEffective = None):
    """
    Add or modify a Client Result to the ClientCache table.
    
    :params:
      :attr:`name`: string - name of the ValidRes
      
      :attr:`commandName`: string - the command name
    
      :attr:`value`: string - the value
    
      :attr:`result`: string - command result
      
      :attr:`opt_ID`: string or integer - optional ID (e.g. used for downtimes)
      
      :attr:`dateEffective`: datetime.datetime - 
      date from which the result is effective
    """
    
    now = datetime.datetime.utcnow().replace(microsecond = 0).isoformat(' ')
    
    if dateEffective is None:
      dateEffective = now
    
    if opt_ID is not None:
      if isinstance(opt_ID, int):
        opt_ID = str(opt_ID)
    
    req = "SELECT Name, CommandName, "
    if opt_ID is not None:
      req = req + "Opt_ID, "
    req = req + "Value, Result FROM ClientsCache WHERE "
    req = req + "Name = '%s' AND CommandName = '%s' " %(name, commandName)
    if opt_ID is not None:
      req = req + "AND Opt_ID = '%s' " %opt_ID
    req = req + "AND Value = '%s' " %value
    resQuery = self.db._query(req)
    if not resQuery['OK']:
      raise RSSManagementDBException, where(self, self.addOrModifyClientsCacheRes) + resQuery['Message']

    if resQuery['Value']: 
      req = "UPDATE ClientsCache SET "
      if resQuery['Value'][0][3] != result:
        req = req + "Result = '%s', DateEffective = '%s', " %(result, dateEffective)
      req = req + "LastCheckTime = '%s' WHERE " %(now)
      req = req + "Name = '%s' AND CommandName = '%s' AND Value = '%s'" %(name, commandName, value)
      if opt_ID is not None:
        req = req + "AND Opt_ID = '%s' " %opt_ID
      
      resUpdate = self.db._update(req)
      if not resUpdate['OK']:
        raise RSSManagementDBException, where(self, self.addOrModifyClientsCacheRes) + resUpdate['Message']
    else:
      req = "INSERT INTO ClientsCache (Name, CommandName, "
      if opt_ID is not None:
        req = req + "Opt_ID, "
      req = req + "Value, Result, DateEffective, "
      req = req + "LastCheckTime) VALUES ('%s', '%s', " %(name, commandName)
      if opt_ID is not None:
        req = req + "'%s', " %opt_ID
      req = req + "'%s', '%s', '%s', '%s')" %(value, result, dateEffective, now)
      
      resUpdate = self.db._update(req)
      if not resUpdate['OK']:
        raise RSSManagementDBException, where(self, self.addOrModifyClientsCacheRes) + resUpdate['Message']
    
#############################################################################

  def getClientsCacheStuff(self, paramsList = None, ccID = None, name = None, commandName = None,
                           opt_ID = None, value = None, result = None, dateEffective = None, 
                           lastCheckTime = None):
    """
    Generic function to get values from the ClientsCache table.
    
    :params:
      :attr:`paramsList` - string or list of strings
    
      :attr:`ccID` - string or list of strings
    
      :attr:`name` - string or list of strings
    
      :attr:`commandName` - string or list of strings
    
      :attr:`opt_ID` - string or list of strings
    
      :attr:`value` - string or list of strings
    
      :attr:`result` - string or list of strings
    
      :attr:`dateEffective` - string or list of strings
    
      :attr:`lastCheckTime` - string or list of strings
    """
    
    if (paramsList == None or paramsList == []):
      params = "ccID, Name, CommandName, Opt_ID, Value, Result, DateEffective "
    else:
      if type(paramsList) is not type([]):
        paramsList = [paramsList]
      params = ','.join([x.strip()+' ' for x in paramsList])
      
    req = "SELECT " + params + "FROM ClientsCache "
    
    if not (ccID == name == commandName == opt_ID == value == 
            result == dateEffective == lastCheckTime == None):
      req = req + "WHERE "
    
    if ccID is not None:
      if type(ccID) is not type([]):
        ccID = [ccID]
      req = req + "ccID IN (" + ','.join([str(x).strip() + ' ' for x in ccID]) + ")"
    
    if name is not None:
      if ccID is not None:
        req = req + " AND "
      if type(name) is not type([]):
        name = [name]
      req = req + "Name IN (" + ','.join(['"' + x.strip() + '"' + ' ' for x in name]) + ")"
    
    if commandName is not None:
      if ccID is not None or name is not None:
        req = req + " AND "
      if type(commandName) is not type([]):
        commandName = [commandName]
      req = req + "CommandName IN (" + ','.join(['"' + x.strip() + '"' + ' ' for x in commandName]) + ")"
    
    if opt_ID is not None:
      if ccID is not None or name is not None or commandName is not None:
        req = req + " AND "
      if type(opt_ID) is not type([]):
        opt_ID = [opt_ID]
      req = req + "Opt_ID IN (" + ','.join(['"' + str(x).strip() + '"' + ' ' for x in opt_ID]) + ")"
    
    if value is not None:
      if ccID is not None or name is not None or commandName is not None or opt_ID is not None:
        req = req + " AND "
      if type(value) is not type([]):
        value = [value]
      req = req + "Value IN (" + ','.join(['"' + x.strip() + '"' + ' ' for x in value]) + ")"
    
    if result is not None:
      if (ccID is not None or name is not None or commandName is not None or opt_ID is not None or value is not None):
        req = req + " AND "
      if type(result) is not type([]):
        result = [result]
      req = req + "result IN (" + ','.join(['"' + x.strip() + '"' + ' ' for x in result]) + ")"
    
    if dateEffective is not None:
      if (ccID is not None or name is not None or commandName is not None or opt_ID is not None or value is not None or result is not None):
        req = req + " AND "
      if type(dateEffective) is not type([]):
        dateEffective = [dateEffective]
      req = req + "dateEffective IN (" + ','.join(['"' + x.strip() + '"' + ' ' for x in dateEffective]) + ")"
    
    if lastCheckTime is not None:
      if (ccID is not None or name is not None or commandName is not None or opt_ID is not None or value is not None or result is not None or dateEffective is not None):
        req = req + " AND "
      if type(lastCheckTime) is not type([]):
        lastCheckTime = [lastCheckTime]
      req = req + "lastCheckTime IN (" + ','.join(['"' + x.strip() + '"' + ' ' for x in lastCheckTime]) + ")"
    
    resQuery = self.db._query(req)
    if not resQuery['OK']:
      raise RSSManagementDBException, where(self, self.getClientsCacheStuff) + resQuery['Message']
    if not resQuery['Value']:
      return []
    
    return resQuery['Value']

#############################################################################

#############################################################################
# AccountingCache functions
#############################################################################

#############################################################################

  def addOrModifyAccountingCacheRes(self, name, plotType, plotName, result, dateEffective = None):
    """
    Add or modify an Accounting Result to the AccountingCache table.
    
    :params:
      :attr:`name`: string - name of the ValidRes
      
      :attr:`plotType`: string - the plotType name (e.g. 'Pilot')
    
      :attr:`plotName`: string - the plot name
    
      :attr:`result`: string - command result
      
      :attr:`dateEffective`: datetime.datetime - 
      date from which the result is effective
    """
    
    now = datetime.datetime.utcnow().replace(microsecond = 0).isoformat(' ')
    
    if dateEffective is None:
      dateEffective = now
    
    req = "SELECT Name, PlotType, PlotName, Result FROM AccountingCache WHERE "
    req = req + "Name = '%s' AND PlotType = '%s' AND PlotName = '%s' " %(name, plotType, plotName)
    resQuery = self.db._query(req)
    if not resQuery['OK']:
      raise RSSManagementDBException, where(self, self.addOrModifyAccountingCacheRes) + resQuery['Message']

    if resQuery['Value']: 
      req = "UPDATE AccountingCache SET "
      if resQuery['Value'][0][3] != result:
        req = req + "Result = \"%s\", DateEffective = '%s', " %(result, dateEffective)
      req = req + "LastCheckTime = '%s' WHERE " %(now)
      req = req + "Name = '%s' AND PlotType = '%s' AND PlotName = '%s'" %(name, plotType, plotName)
      
      resUpdate = self.db._update(req)
      if not resUpdate['OK']:
        raise RSSManagementDBException, where(self, self.addOrModifyAccountingCacheRes) + resUpdate['Message']
    else:
      req = "INSERT INTO AccountingCache (Name, PlotType, PlotName, Result, DateEffective, "
      req = req + "LastCheckTime) VALUES ('%s', '%s', '%s', " %(name, plotType, plotName)
      req = req + "\"%s\", '%s', '%s')" %(result, dateEffective, now)
      
      resUpdate = self.db._update(req)
      if not resUpdate['OK']:
        raise RSSManagementDBException, where(self, self.addOrModifyAccountingCacheRes) + resUpdate['Message']
    
#############################################################################

  def getAccountingCacheStuff(self, paramsList = None, acID = None, name = None, plotType = None, 
                              plotName = None, result = None, dateEffective = None, 
                              lastCheckTime = None):
    """
    Generic function to get values from the AccountingCache table.
    
    :params:
      :attr:`paramsList` - string or list of strings
    
      :attr:`acID` - string or list of strings
    
      :attr:`name` - string or list of strings
    
      :attr:`plotName` - string or list of strings
    
      :attr:`result` - string or list of strings
    
      :attr:`dateEffective` - string or list of strings
    
      :attr:`lastCheckTime` - string or list of strings
    """
    if (paramsList == None or paramsList == []):
      params = "acID, Name, PlotType, PlotName, Result, DateEffective "
    else:
      if type(paramsList) != type([]):
        paramsList = [paramsList]
      params = ','.join([x.strip()+' ' for x in paramsList])
      
    req = "SELECT " + params + "FROM AccountingCache "
    
    if not (acID == name == plotType == plotName == result == dateEffective == lastCheckTime == None):
      req = req + "WHERE "
    
    if acID is not None:
      if type(acID) is not type([]):
        acID = [acID]
      req = req + "acID IN (" + ','.join([str(x).strip() + ' ' for x in acID]) + ")"
    
    if name is not None:
      if acID is not None:
        req = req + " AND "
      if type(name) is not type([]):
        name = [name]
      req = req + "Name IN (" + ','.join(['"' + x.strip() + '"' + ' ' for x in name]) + ")"
    
    if plotName is not None:
      if acID is not None or name is not None:
        req = req + " AND "
      if type(plotName) is not type([]):
        plotName = [plotName]
      req = req + "PlotName IN (" + ','.join(['"' + x.strip() + '"' + ' ' for x in plotName]) + ")"
    
    if plotType is not None:
      if acID is not None or name is not None or plotName is not None:
        req = req + " AND "
      if type(plotType) is not type([]):
        plotType = [plotType]
      req = req + "PlotType IN (" + ','.join(['"' + x.strip() + '"' + ' ' for x in plotType]) + ")"
    
    if result is not None:
      if (acID is not None or name is not None or plotName is not None or plotType is not None):
        req = req + " AND "
      if type(result) is not type([]):
        result = [result]
      req = req + "Result IN (" + ','.join(['"' + x.strip() + '"' + ' ' for x in result]) + ")"
    
    if dateEffective is not None:
      if (acID is not None or name is not None or plotName is not None or plotType is not None or result is not None):
        req = req + " AND "
      if type(dateEffective) is not type([]):
        dateEffective = [dateEffective]
      req = req + "DateEffective IN (" + ','.join(['"' + x.strip() + '"' + ' ' for x in dateEffective]) + ")"
    
    if lastCheckTime is not None:
      if (acID is not None or name is not None or plotName is not None or plotType is not None or result is not None or dateEffective is not None):
        req = req + " AND "
      if type(lastCheckTime) is not type([]):
        lastCheckTime = [lastCheckTime]
      req = req + "LastCheckTime IN (" + ','.join(['"' + x.strip() + '"' + ' ' for x in lastCheckTime]) + ")"
    
    resQuery = self.db._query(req)
    if not resQuery['OK']:
      raise RSSManagementDBException, where(self, self.getAccountingCacheStuff) + resQuery['Message']
    if not resQuery['Value']:
      return []
    
    return resQuery['Value']

#############################################################################

#############################################################################
# Status functions
#############################################################################

#############################################################################

  #usata solo nell'handler
  def addStatus(self, status, description=''):
    """ 
    Add a status.
    
    :params:
      :attr:`status`: string - a new status
      
      :attr:`description`: string - optional description
    """

    req = "INSERT INTO Status (Status, Description)"
    req = req + "VALUES ('%s', '%s');" % (status, description)

    resUpdate = self.db._update(req)
    if not resUpdate['OK']:
      raise RSSManagementDBException, where(self, self.addStatus) + resUpdate['Message']

#############################################################################

  #usata solo nell'handler
  def removeStatus(self, status):
    """ 
    Remove a status from the Status table.
    
    :params:
      :attr:`status`: string - status
    """

    req = "DELETE from Status WHERE Status = '%s';" % (status)
    resDel = self.db._update(req)
    if not resDel['OK']:
      raise RSSManagementDBException, where(self, self.removeStatus) + resDel['Message']

#############################################################################
  
  def getStatusList(self):
    """ 
    Get list of status with no descriptions.
    """

    req = "SELECT Status from Status"

    resQuery = self.db._query(req)
    if not resQuery['OK']:
      raise RSSManagementDBException, where(self, self.getStatusList) + resQuery['Message']
    if not resQuery['Value']:
      return []
    l = [ x[0] for x in resQuery['Value']]
    return l
      
#############################################################################      
# Web functions      
#############################################################################
      
#############################################################################

  def getDownTimesWeb(self, selectDict, sortList = [], startItem = 0, maxItems = 1000):
    """
    Get downtimes registered in the RSS DB (with a web layout)

    :params:
      :attr:`selectDict`: { 'Granularity':['Site', 'Resource'], 'Severity': ['OUTAGE', 'AT_RISK']}
            
      :attr:`sortList` 
      
      :attr:`startItem` 
      
      :attr:`maxItems`
    """
    
    granularity = selectDict['Granularity']
    severity = selectDict['Severity']
    
    if not isinstance(granularity, list):
      granularity = [granularity]
    if not isinstance(severity, list):
      severity = [severity]
    
    paramNames = ['Granularity', 'Name', 'Severity', 'When']
    
    req = "SELECT Granularity, Name, Reason FROM PolicyRes WHERE "
    req = req + "PolicyName LIKE 'DT_%' AND Reason LIKE \'%found%\' "
    req = req + "AND Granularity in (%s)" %(','.join(['"'+x.strip()+'"' for x in granularity]))
    resQuery = self.db._query(req)
    if not resQuery['OK']:
      raise RSSManagementDBException, resQuery['Message']
    if not resQuery['Value']:
      records = []
    else:
      resQuery = resQuery['Value']
      records = []
      for tuple in resQuery:
        sev = tuple[2].split()[2]
        if sev not in severity: 
          continue
        when = tuple[2].split(sev)[1][1:]
        if when == '':
          when = 'Ongoing'
        records.append([tuple[0], tuple[1], sev, when])
    
    finalDict = {}
    finalDict['TotalRecords'] = len(records)
    finalDict['ParameterNames'] = paramNames

    # Return all the records if maxItems == 0 or the specified number otherwise
    if maxItems:
      finalDict['Records'] = records[startItem:startItem+maxItems]
    else:
      finalDict['Records'] = records

    finalDict['Extras'] = None
 
    return finalDict
 
#############################################################################
Beispiel #6
0
class ResourceManagementDB:
    """ 
  The ResourceManagementDB class is a front-end to the Resource Management Database.
  
  The simplest way to instantiate an object of type :class:`ResourceManagementDB` 
  is simply by calling 

   >>> rpDB = ResourceManagementDB()

  This way, it will use the standard :mod:`DIRAC.Core.Base.DB`. 
  But there's the possibility to use other DB classes. 
  For example, we could pass custom DB instantiations to it, 
  provided the interface is the same exposed by :mod:`DIRAC.Core.Base.DB`.

   >>> AnotherDB = AnotherDBClass()
   >>> rmDB = ResourceManagementDB(DBin = AnotherDB)

  Alternatively, for testing purposes, you could do:

   >>> from DIRAC.ResourceStatusSystem.Utilities.mock import Mock
   >>> mockDB = Mock()
   >>> rmDB = ResourceManagementDB(DBin = mockDB)

  Or, if you want to work with a local DB, providing it's mySQL:

   >>> rmDB = ResourceManagementDB(DBin = ['UserName', 'Password'])

  """
    def __init__(self, *args, **kwargs):

        if len(args) == 1:
            if isinstance(args[0], str):
                #        systemInstance=args[0]
                maxQueueSize = 10
            if isinstance(args[0], int):
                maxQueueSize = args[0]
#        systemInstance='Default'
        elif len(args) == 2:
            #      systemInstance=args[0]
            maxQueueSize = args[1]
        elif len(args) == 0:
            #      systemInstance='Default'
            maxQueueSize = 10

        if 'DBin' in kwargs.keys():
            DBin = kwargs['DBin']
            if isinstance(DBin, list):
                from DIRAC.Core.Utilities.MySQL import MySQL
                self.db = MySQL('localhost', DBin[0], DBin[1],
                                'ResourceManagementDB')
            else:
                self.db = DBin
        else:
            from DIRAC.Core.Base.DB import DB
            self.db = DB('ResourceManagementDB',
                         'ResourceStatus/ResourceManagementDB', maxQueueSize)
#      self.db = DB('ResourceStatusDB','ResourceStatus/ResourceStatusDB',maxQueueSize)

#############################################################################

#############################################################################
# Policy functions
#############################################################################

#############################################################################

    def addOrModifyPolicyRes(self,
                             granularity,
                             name,
                             policyName,
                             status,
                             reason,
                             dateEffective=None):
        """
    Add or modify a Policy Result to the PolicyRes table.
    
    :params:
      :attr:`granularity`: string - a ValidRes
      see :mod:`DIRAC.ResourceStatusSystem.Utilities.Utils`
    
      :attr:`name`: string - name of the ValidRes
      
      :attr:`policyName`: string - the policy name
    
      :attr:`status`: string - a ValidStatus: 
      see :mod:`DIRAC.ResourceStatusSystem.Utilities.Utils`
      
      :attr:`reason`: string - free
      
      :attr:`dateEffective`: datetime.datetime - 
      date from which the result is effective
    """

        now = datetime.datetime.utcnow().replace(microsecond=0).isoformat(' ')

        if dateEffective is None:
            dateEffective = now

        req = "SELECT Granularity, Name, PolicyName, Status, Reason FROM PolicyRes "
        req = req + "WHERE Granularity = '%s' AND Name = '%s' AND " % (
            granularity, name)
        req = req + "PolicyName = '%s'" % (policyName)
        resQuery = self.db._query(req)
        if not resQuery['OK']:
            raise RSSManagementDBException, where(
                self, self.addOrModifyPolicyRes) + resQuery['Message']

        if resQuery['Value']:
            req = "UPDATE PolicyRes SET "
            if resQuery['Value'][0][3] != status:
                req = req + "Status = '%s', Reason = '%s', DateEffective = '%s', " % (
                    status, reason, dateEffective)
            elif resQuery['Value'][0][4] != reason:
                req = req + "Reason = '%s', " % (reason)
            req = req + "LastCheckTime = '%s' WHERE Granularity = '%s' " % (
                now, granularity)
            req = req + "AND Name = '%s' AND PolicyName = '%s'" % (name,
                                                                   policyName)

            resUpdate = self.db._update(req)
            if not resUpdate['OK']:
                raise RSSManagementDBException, where(
                    self, self.addOrModifyPolicyRes) + resUpdate['Message']
        else:
            req = "INSERT INTO PolicyRes (Granularity, Name, PolicyName, Status, Reason, DateEffective, "
            req = req + "LastCheckTime) VALUES ('%s', '%s', '%s', " % (
                granularity, name, policyName)
            req = req + "'%s', '%s', '%s', '%s')" % (status, reason,
                                                     dateEffective, now)
            resUpdate = self.db._update(req)
            if not resUpdate['OK']:
                raise RSSManagementDBException, where(
                    self, self.addOrModifyPolicyRes) + resUpdate['Message']

#############################################################################

    def getPolicyRes(self, name, policyName, lastCheckTime=False):
        """ 
    Get a Policy Result from the PolicyRes table.
    
    :params:
      :attr:`name`: string - name of the ValidRes
      
      :attr:`policyName`: string - the policy name
      
      :attr:`lastCheckTime`: optional - if TRUE, it will get also the 
      LastCheckTime 
    """

        req = "SELECT Status, Reason"
        if lastCheckTime:
            req = req + ", LastCheckTime"
        req = req + " FROM PolicyRes WHERE"
        req = req + " Name = '%s' AND PolicyName = '%s'" % (name, policyName)

        resQuery = self.db._query(req)
        if not resQuery['OK']:
            raise RSSManagementDBException, where(
                self, self.getPolicyRes) + resQuery['Message']
        if not resQuery['Value']:
            return []

        return resQuery['Value'][0]

#############################################################################

#############################################################################
# ClientsCache functions
#############################################################################

#############################################################################

    def addOrModifyClientsCacheRes(self,
                                   name,
                                   commandName,
                                   value,
                                   result,
                                   opt_ID=None,
                                   dateEffective=None):
        """
    Add or modify a Client Result to the ClientCache table.
    
    :params:
      :attr:`name`: string - name of the ValidRes
      
      :attr:`commandName`: string - the command name
    
      :attr:`value`: string - the value
    
      :attr:`result`: string - command result
      
      :attr:`opt_ID`: string or integer - optional ID (e.g. used for downtimes)
      
      :attr:`dateEffective`: datetime.datetime - 
      date from which the result is effective
    """

        now = datetime.datetime.utcnow().replace(microsecond=0).isoformat(' ')

        if dateEffective is None:
            dateEffective = now

        if opt_ID is not None:
            if isinstance(opt_ID, int):
                opt_ID = str(opt_ID)

        req = "SELECT Name, CommandName, "
        if opt_ID is not None:
            req = req + "Opt_ID, "
        req = req + "Value, Result FROM ClientsCache WHERE "
        req = req + "Name = '%s' AND CommandName = '%s' " % (name, commandName)
        if opt_ID is not None:
            req = req + "AND Opt_ID = '%s' " % opt_ID
        req = req + "AND Value = '%s' " % value
        resQuery = self.db._query(req)
        if not resQuery['OK']:
            raise RSSManagementDBException, where(
                self, self.addOrModifyClientsCacheRes) + resQuery['Message']

        if resQuery['Value']:
            req = "UPDATE ClientsCache SET "
            if resQuery['Value'][0][3] != result:
                req = req + "Result = '%s', DateEffective = '%s', " % (
                    result, dateEffective)
            req = req + "LastCheckTime = '%s' WHERE " % (now)
            req = req + "Name = '%s' AND CommandName = '%s' AND Value = '%s'" % (
                name, commandName, value)
            if opt_ID is not None:
                req = req + "AND Opt_ID = '%s' " % opt_ID

            resUpdate = self.db._update(req)
            if not resUpdate['OK']:
                raise RSSManagementDBException, where(
                    self,
                    self.addOrModifyClientsCacheRes) + resUpdate['Message']
        else:
            req = "INSERT INTO ClientsCache (Name, CommandName, "
            if opt_ID is not None:
                req = req + "Opt_ID, "
            req = req + "Value, Result, DateEffective, "
            req = req + "LastCheckTime) VALUES ('%s', '%s', " % (name,
                                                                 commandName)
            if opt_ID is not None:
                req = req + "'%s', " % opt_ID
            req = req + "'%s', '%s', '%s', '%s')" % (value, result,
                                                     dateEffective, now)

            resUpdate = self.db._update(req)
            if not resUpdate['OK']:
                raise RSSManagementDBException, where(
                    self,
                    self.addOrModifyClientsCacheRes) + resUpdate['Message']

#############################################################################

    def getClientsCacheStuff(self,
                             paramsList=None,
                             ccID=None,
                             name=None,
                             commandName=None,
                             opt_ID=None,
                             value=None,
                             result=None,
                             dateEffective=None,
                             lastCheckTime=None):
        """
    Generic function to get values from the ClientsCache table.
    
    :params:
      :attr:`paramsList` - string or list of strings
    
      :attr:`ccID` - string or list of strings
    
      :attr:`name` - string or list of strings
    
      :attr:`commandName` - string or list of strings
    
      :attr:`opt_ID` - string or list of strings
    
      :attr:`value` - string or list of strings
    
      :attr:`result` - string or list of strings
    
      :attr:`dateEffective` - string or list of strings
    
      :attr:`lastCheckTime` - string or list of strings
    """

        if (paramsList == None or paramsList == []):
            params = "ccID, Name, CommandName, Opt_ID, Value, Result, DateEffective "
        else:
            if type(paramsList) is not type([]):
                paramsList = [paramsList]
            params = ','.join([x.strip() + ' ' for x in paramsList])

        req = "SELECT " + params + "FROM ClientsCache "

        if not (ccID == name == commandName == opt_ID == value == result ==
                dateEffective == lastCheckTime == None):
            req = req + "WHERE "

        if ccID is not None:
            if type(ccID) is not type([]):
                ccID = [ccID]
            req = req + "ccID IN (" + ','.join(
                [str(x).strip() + ' ' for x in ccID]) + ")"

        if name is not None:
            if ccID is not None:
                req = req + " AND "
            if type(name) is not type([]):
                name = [name]
            req = req + "Name IN (" + ','.join(
                ['"' + x.strip() + '"' + ' ' for x in name]) + ")"

        if commandName is not None:
            if ccID is not None or name is not None:
                req = req + " AND "
            if type(commandName) is not type([]):
                commandName = [commandName]
            req = req + "CommandName IN (" + ','.join(
                ['"' + x.strip() + '"' + ' ' for x in commandName]) + ")"

        if opt_ID is not None:
            if ccID is not None or name is not None or commandName is not None:
                req = req + " AND "
            if type(opt_ID) is not type([]):
                opt_ID = [opt_ID]
            req = req + "Opt_ID IN (" + ','.join(
                ['"' + str(x).strip() + '"' + ' ' for x in opt_ID]) + ")"

        if value is not None:
            if ccID is not None or name is not None or commandName is not None or opt_ID is not None:
                req = req + " AND "
            if type(value) is not type([]):
                value = [value]
            req = req + "Value IN (" + ','.join(
                ['"' + x.strip() + '"' + ' ' for x in value]) + ")"

        if result is not None:
            if (ccID is not None or name is not None or commandName is not None
                    or opt_ID is not None or value is not None):
                req = req + " AND "
            if type(result) is not type([]):
                result = [result]
            req = req + "result IN (" + ','.join(
                ['"' + x.strip() + '"' + ' ' for x in result]) + ")"

        if dateEffective is not None:
            if (ccID is not None or name is not None or commandName is not None
                    or opt_ID is not None or value is not None
                    or result is not None):
                req = req + " AND "
            if type(dateEffective) is not type([]):
                dateEffective = [dateEffective]
            req = req + "dateEffective IN (" + ','.join(
                ['"' + x.strip() + '"' + ' ' for x in dateEffective]) + ")"

        if lastCheckTime is not None:
            if (ccID is not None or name is not None or commandName is not None
                    or opt_ID is not None or value is not None
                    or result is not None or dateEffective is not None):
                req = req + " AND "
            if type(lastCheckTime) is not type([]):
                lastCheckTime = [lastCheckTime]
            req = req + "lastCheckTime IN (" + ','.join(
                ['"' + x.strip() + '"' + ' ' for x in lastCheckTime]) + ")"

        resQuery = self.db._query(req)
        if not resQuery['OK']:
            raise RSSManagementDBException, where(
                self, self.getClientsCacheStuff) + resQuery['Message']
        if not resQuery['Value']:
            return []

        return resQuery['Value']

#############################################################################

#############################################################################
# AccountingCache functions
#############################################################################

#############################################################################

    def addOrModifyAccountingCacheRes(self,
                                      name,
                                      plotType,
                                      plotName,
                                      result,
                                      dateEffective=None):
        """
    Add or modify an Accounting Result to the AccountingCache table.
    
    :params:
      :attr:`name`: string - name of the ValidRes
      
      :attr:`plotType`: string - the plotType name (e.g. 'Pilot')
    
      :attr:`plotName`: string - the plot name
    
      :attr:`result`: string - command result
      
      :attr:`dateEffective`: datetime.datetime - 
      date from which the result is effective
    """

        now = datetime.datetime.utcnow().replace(microsecond=0).isoformat(' ')

        if dateEffective is None:
            dateEffective = now

        req = "SELECT Name, PlotType, PlotName, Result FROM AccountingCache WHERE "
        req = req + "Name = '%s' AND PlotType = '%s' AND PlotName = '%s' " % (
            name, plotType, plotName)
        resQuery = self.db._query(req)
        if not resQuery['OK']:
            raise RSSManagementDBException, where(
                self, self.addOrModifyAccountingCacheRes) + resQuery['Message']

        if resQuery['Value']:
            req = "UPDATE AccountingCache SET "
            if resQuery['Value'][0][3] != result:
                req = req + "Result = \"%s\", DateEffective = '%s', " % (
                    result, dateEffective)
            req = req + "LastCheckTime = '%s' WHERE " % (now)
            req = req + "Name = '%s' AND PlotType = '%s' AND PlotName = '%s'" % (
                name, plotType, plotName)

            resUpdate = self.db._update(req)
            if not resUpdate['OK']:
                raise RSSManagementDBException, where(
                    self,
                    self.addOrModifyAccountingCacheRes) + resUpdate['Message']
        else:
            req = "INSERT INTO AccountingCache (Name, PlotType, PlotName, Result, DateEffective, "
            req = req + "LastCheckTime) VALUES ('%s', '%s', '%s', " % (
                name, plotType, plotName)
            req = req + "\"%s\", '%s', '%s')" % (result, dateEffective, now)

            resUpdate = self.db._update(req)
            if not resUpdate['OK']:
                raise RSSManagementDBException, where(
                    self,
                    self.addOrModifyAccountingCacheRes) + resUpdate['Message']

#############################################################################

    def getAccountingCacheStuff(self,
                                paramsList=None,
                                acID=None,
                                name=None,
                                plotType=None,
                                plotName=None,
                                result=None,
                                dateEffective=None,
                                lastCheckTime=None):
        """
    Generic function to get values from the AccountingCache table.
    
    :params:
      :attr:`paramsList` - string or list of strings
    
      :attr:`acID` - string or list of strings
    
      :attr:`name` - string or list of strings
    
      :attr:`plotName` - string or list of strings
    
      :attr:`result` - string or list of strings
    
      :attr:`dateEffective` - string or list of strings
    
      :attr:`lastCheckTime` - string or list of strings
    """
        if (paramsList == None or paramsList == []):
            params = "acID, Name, PlotType, PlotName, Result, DateEffective "
        else:
            if type(paramsList) != type([]):
                paramsList = [paramsList]
            params = ','.join([x.strip() + ' ' for x in paramsList])

        req = "SELECT " + params + "FROM AccountingCache "

        if not (acID == name == plotType == plotName == result == dateEffective
                == lastCheckTime == None):
            req = req + "WHERE "

        if acID is not None:
            if type(acID) is not type([]):
                acID = [acID]
            req = req + "acID IN (" + ','.join(
                [str(x).strip() + ' ' for x in acID]) + ")"

        if name is not None:
            if acID is not None:
                req = req + " AND "
            if type(name) is not type([]):
                name = [name]
            req = req + "Name IN (" + ','.join(
                ['"' + x.strip() + '"' + ' ' for x in name]) + ")"

        if plotName is not None:
            if acID is not None or name is not None:
                req = req + " AND "
            if type(plotName) is not type([]):
                plotName = [plotName]
            req = req + "PlotName IN (" + ','.join(
                ['"' + x.strip() + '"' + ' ' for x in plotName]) + ")"

        if plotType is not None:
            if acID is not None or name is not None or plotName is not None:
                req = req + " AND "
            if type(plotType) is not type([]):
                plotType = [plotType]
            req = req + "PlotType IN (" + ','.join(
                ['"' + x.strip() + '"' + ' ' for x in plotType]) + ")"

        if result is not None:
            if (acID is not None or name is not None or plotName is not None
                    or plotType is not None):
                req = req + " AND "
            if type(result) is not type([]):
                result = [result]
            req = req + "Result IN (" + ','.join(
                ['"' + x.strip() + '"' + ' ' for x in result]) + ")"

        if dateEffective is not None:
            if (acID is not None or name is not None or plotName is not None
                    or plotType is not None or result is not None):
                req = req + " AND "
            if type(dateEffective) is not type([]):
                dateEffective = [dateEffective]
            req = req + "DateEffective IN (" + ','.join(
                ['"' + x.strip() + '"' + ' ' for x in dateEffective]) + ")"

        if lastCheckTime is not None:
            if (acID is not None or name is not None or plotName is not None
                    or plotType is not None or result is not None
                    or dateEffective is not None):
                req = req + " AND "
            if type(lastCheckTime) is not type([]):
                lastCheckTime = [lastCheckTime]
            req = req + "LastCheckTime IN (" + ','.join(
                ['"' + x.strip() + '"' + ' ' for x in lastCheckTime]) + ")"

        resQuery = self.db._query(req)
        if not resQuery['OK']:
            raise RSSManagementDBException, where(
                self, self.getAccountingCacheStuff) + resQuery['Message']
        if not resQuery['Value']:
            return []

        return resQuery['Value']

#############################################################################

#############################################################################
# Status functions
#############################################################################

#############################################################################

#usata solo nell'handler

    def addStatus(self, status, description=''):
        """ 
    Add a status.
    
    :params:
      :attr:`status`: string - a new status
      
      :attr:`description`: string - optional description
    """

        req = "INSERT INTO Status (Status, Description)"
        req = req + "VALUES ('%s', '%s');" % (status, description)

        resUpdate = self.db._update(req)
        if not resUpdate['OK']:
            raise RSSManagementDBException, where(
                self, self.addStatus) + resUpdate['Message']

#############################################################################

#usata solo nell'handler

    def removeStatus(self, status):
        """ 
    Remove a status from the Status table.
    
    :params:
      :attr:`status`: string - status
    """

        req = "DELETE from Status WHERE Status = '%s';" % (status)
        resDel = self.db._update(req)
        if not resDel['OK']:
            raise RSSManagementDBException, where(
                self, self.removeStatus) + resDel['Message']

#############################################################################

    def getStatusList(self):
        """ 
    Get list of status with no descriptions.
    """

        req = "SELECT Status from Status"

        resQuery = self.db._query(req)
        if not resQuery['OK']:
            raise RSSManagementDBException, where(
                self, self.getStatusList) + resQuery['Message']
        if not resQuery['Value']:
            return []
        l = [x[0] for x in resQuery['Value']]
        return l

#############################################################################
# Web functions
#############################################################################

#############################################################################

    def getDownTimesWeb(self,
                        selectDict,
                        sortList=[],
                        startItem=0,
                        maxItems=1000):
        """
    Get downtimes registered in the RSS DB (with a web layout)

    :params:
      :attr:`selectDict`: { 'Granularity':['Site', 'Resource'], 'Severity': ['OUTAGE', 'AT_RISK']}
            
      :attr:`sortList` 
      
      :attr:`startItem` 
      
      :attr:`maxItems`
    """

        granularity = selectDict['Granularity']
        severity = selectDict['Severity']

        if not isinstance(granularity, list):
            granularity = [granularity]
        if not isinstance(severity, list):
            severity = [severity]

        paramNames = ['Granularity', 'Name', 'Severity', 'When']

        req = "SELECT Granularity, Name, Reason FROM PolicyRes WHERE "
        req = req + "PolicyName LIKE 'DT_%' AND Reason LIKE \'%found%\' "
        req = req + "AND Granularity in (%s)" % (','.join(
            ['"' + x.strip() + '"' for x in granularity]))
        resQuery = self.db._query(req)
        if not resQuery['OK']:
            raise RSSManagementDBException, resQuery['Message']
        if not resQuery['Value']:
            records = []
        else:
            resQuery = resQuery['Value']
            records = []
            for tuple in resQuery:
                sev = tuple[2].split()[2]
                if sev not in severity:
                    continue
                when = tuple[2].split(sev)[1][1:]
                if when == '':
                    when = 'Ongoing'
                records.append([tuple[0], tuple[1], sev, when])

        finalDict = {}
        finalDict['TotalRecords'] = len(records)
        finalDict['ParameterNames'] = paramNames

        # Return all the records if maxItems == 0 or the specified number otherwise
        if maxItems:
            finalDict['Records'] = records[startItem:startItem + maxItems]
        else:
            finalDict['Records'] = records

        finalDict['Extras'] = None

        return finalDict


#############################################################################
Beispiel #7
0
class RSSConfigurationDB(object):

  def __init__(self, DBin = None, maxQueueSize = 10):
    if DBin: self.db = DBin
    else:
      from DIRAC.Core.Base.DB import DB
      self.db = DB('RSSConfigurationDB',
                   'ResourceStatus/RSSConfigurationDB', maxQueueSize)

  def _delete(self, tableName, inFields, inValues):
    # FIXME: Should go in DIRAC.Core.Utilities.MySQL
    zipped = zip(inFields, inValues)
    where_clause = ''
    for i,(l,v) in enumerate(zipped):
      if i == 0:
        where_clause = where_clause + l + '="' + v + '" '
      else:
        where_clause = where_clause + 'AND ' + l + '="' + v + '" '

    return self.db._update('DELETE FROM ' + tableName + ' WHERE ' + where_clause)

  def _addValue(self, table, vdict):
    keys, values = list_split(vdict.items())
    return self.db._insert(table, keys, values)

  def _delValue(self, table, vdict):
    keys, values = list_split(vdict.items())
    return self._delete(table, keys, values)

  def _addValues(self, table, vdicts):
    res = []
    for d in vdicts:
      res.append(self._addValue(table, d))
    return res

  def _delValues(self, table, vdicts):
    res = []
    for d in vdicts:
      res.append(self._delValue(table, d))
    return res

  def _query(self, table):
    """
    Returns values in a list instead of a tuple, i.e. retval[1] is a
    list of tuples, one per line of result.
    """
    retval = self.db._query("SELECT * from " + table)
    return retval['OK'], list(retval['Value'])

  # Helper functions.

  def addUsers(self, unames):
    """Add users. The argument is a list of strings representing
    usernames."""
    unames = [{'login':u} for u in unames]
    return self._addValues(t_users, unames)

  def addUser(self, uname):
    """Add one user. The argument is a string representing the
    username"""
    return self.addUsers([uname])[0]

  def delUsers(self, unames):
    """Delete users. The argument is a list of strings representing
    usernames."""
    unames = [{'login': u} for u in unames]
    return self._delValues(t_users, unames)

  def delUser(self, uname):
    """Delete a user. The argument is a string representing
    username."""
    return self.delUsers([uname])[0]

  def getUsers(self):
    """Return users registered in database. Return S_OK() with Value:
    a dict representing users with (for now) only a field 'login'.
    TODO: This function is not supposed to fail in normal conditions,
    and result incorrect if it fails. Fix this.
    """
    ret, users = self._query(t_users)
    users = [{'login': u} for u in users]
    return {'OK':ret, 'Value':users}

  def addStatuses(self, statuses):
    """Add statuses. Argument is a list of tuples (label, priority)"""
    statuses = [{'label':l, 'priority':p} for (l,p) in statuses]
    return self._addValues(t_statuses, statuses)

  def addStatus(self, label, priority):
    """Add a status. The argument is respectively a string and an
    integer, representing the name of the status and the priority"""
    return self.addStatuses([(label, priority)])[0]

  def delStatuses(self, statuses):
    """Delete statuses. Argument is a list of strings (labels)"""
    statuses = [{'label':l} for l in statuses]
    return self._delValues(t_statuses, statuses)

  def delStatus(self, status):
    return self.delStatuses([status])[0]

  def getStatuses(self):
    ret, statuses = self._query(t_statuses)
    statuses = [{'label':l, 'priority':p} for (l,p) in statuses]
    return {'OK':ret, 'Value':statuses}

  def addCheckFreq(self, kwargs):
    """
    Add a new check frequency. Arguments must be a dict with fields:
    granularity, site_type, status, freq.
    """
    return self._addValue(t_checkfreqs, kwargs)

  def delCheckFreq(self, kwargs):
    """
    Delete check frequencies. Arguments must be a dict with fields
    part or all of: granularity, site_type, status, freq.
    """
    return self._delValue(t_checkfreqs, kwargs)

  def getCheckFreqs(self):
    ret, freqs = self._query(t_checkfreqs)
    freqs = [{'granularity':g, 'site_type':st,'status':sta, 'freq':f}
             for (g,st,sta,f) in freqs]
    return {'OK':ret, 'Value':freqs}

  def addAssigneeGroup(self, kwargs):
    """
    Add new assignee groups. Argument must be a dict with fields:
    label, login, granularity, site_type, service_type, resource_type,
    notification.
    """
    return self._addValue(t_assigneegroups, kwargs)

  def delAssigneeGroup(self, kwargs):
    """
    Delete assignee groups. Argument must be a dict with fields all or
    part of: label, login, granularity, site_type, service_type,
    resource_type, notification.
    """
    return self._delValue(t_assigneegroups, kwargs)

  def getAssigneeGroups(self):
    ret, groups = self._query(t_assigneegroups)
    groups = [{'label':label, 'login':login, 'granularity':granularity,
               'site_type':site_type, 'service_type':service_type,
               'resource_type':resource_type, 'notification':notification}
              for (label, login, granularity, site_type,
                   service_type, resource_type, notification) in groups
              ]
    return {'OK':ret, 'Value':groups}

  def addPolicy(self, kwargs):
    """
    Add new policies. Argument must be a dict with fiels: label,
    description, status, former_status, site_type, service_type,
    resource_type.
    """
    return self._addValue(t_policies, kwargs)

  def delPolicy(self, kwargs):
    """
    Delete policies. Argument must be a dict with fields all or part
    of: label, description, status, former_status, site_type,
    service_type, resource_type, or a list of labels.
    """
    return self._delValue(t_policies, kwargs)


  def getPolicies(self):
    ret, policies = self._query(t_policies)
    policies = [{'label':label, 'description':description, 'status':status,
                 'former_status':former_status, 'site_type':site_type,
                 'service_type':service_type, 'resource_type':resource_type}
                for (label, description, status, former_status,
                     site_type, service_type, resource_type) in policies
                ]
    return {'OK':ret, 'Value':policies}