def load_servers(self,filters=None): if getattr(self,'servers',None) is None: self.servers = ServersDict() [self.servers.load_by_name(k) for k in (filters or self.ArchivingClasses)] self.servers.refresh() self.proxies = self.servers.proxies return self.servers
class CommonAPI(Object,fn.SingletonMap): """ This class provides common methods for managing a Soleil-like database (for either archiving or snapshoting) The methods starting by "get" retrieve values using ArchivingDSs The methods starting by "load" access directly to MySQL database """ #ArchivingTypes = ARCHIVING_TYPES #ArchivingClasses = ARCHIVING_CLASSES MAX_SERVERS_FOR_CLASS=5 MIN_ARCHIVING_PERIOD=10 def __init__(self,schema,host=None,user='******',passwd='browser', classes=[],LogLevel='WARNING',load=True,logger=None): """ """ self.log = logger or Logger('ArchivingAPI(%s)'%schema,format='%(levelname)-8s %(asctime)s %(name)s: %(message)s') self.log.setLogLevel(LogLevel) self.log.debug('Logger streams initialized (error,warning,info,debug)') self.tango = fn.get_database() #access to Tango database self.api = self #hook used by legacy packages self.servers = None self.schema = str(schema).lower() self.user,self.passwd = user,passwd if host is None: prop = self.tango.get_class_property('%sArchiver'%schema,['DbHost'])['DbHost'] if not prop: print('ERROR: %sArchiver.DbHost property not defined!'%schema) self.host = None else: self.host = prop[0] #if 'TANGO_HOST' in os.environ: # self.host=os.environ['TANGO_HOST'].split(':')[0] else: self.host=host self.dbs={} #pointers to Archiving databases self.ArchivingClasses = classes or self.get_archiving_classes() self.ArchiverClass = fn.first((k for k in self.ArchivingClasses if 'Archiver' in k),'') self.ManagerClass = fn.first((k for k in self.ArchivingClasses if 'Manager' in k),'') self.ExtractorClass = fn.first((k for k in self.ArchivingClasses if 'Extractor' in k),'') try: self.WatcherClass = fn.first((k for k in self.ArchivingClasses if 'Watcher' in k),'') except: self.WatcherClass = None self.loads=CaselessDefaultDict(lambda k:0) #a dict with the archiving load for each device self.attributes=CaselessDict() #a dict of ArchivedAttribute objects self.dedicated = CaselessDefaultDict(lambda k:set()) #Dictionary for keeping the attributes reserved for each archiver if load and self.host and self.ArchivingClasses: self.load_servers() ## The ArchivingAPI is an iterator through archived attributes def __getitem__(self,k): k = k if k.count('/')<=3 else fn.tango.get_normal_name(k) return self.attributes.__getitem__(k) def __contains__(self,k): k = k if k.count('/')<=3 else fn.tango.get_normal_name(k) return self.attributes.__contains__(k) def get(self,k): k = k if k.count('/')<=3 else fn.tango.get_normal_name(k) return self.attributes.get(k) def has_key(self,k): k = k if k.count('/')<=3 else fn.tango.get_normal_name(k) return self.attributes.has_key(k) #[setattr(self,method,lambda k,meth=method:getattr(self.attributes,meth)(k)) for method in ('__getitem__','__contains__','get','has_key')] def __iter__(self): return self.attributes.__iter__() def iteritems(self): return self.attributes.iteritems() def keys(self): return self.attributes.keys() def values(self): return self.attributes.values() def __len__(self): return len(self.attributes.keys()) def items(self): return self.attributes.items() #[setattr(self,method,lambda meth=method:getattr(self.attributes,meth)()) for method in ('__iter__','iteritems','items','keys','values')] def load_servers(self,filters=None): if getattr(self,'servers',None) is None: self.servers = ServersDict() [self.servers.load_by_name(k) for k in (filters or self.ArchivingClasses)] self.servers.refresh() self.proxies = self.servers.proxies return self.servers def get_servers(self): if not getattr(self,'servers',None): return self.load_servers() return self.servers def get_archiving_classes(self): self.ArchivingClasses = [k for k in ARCHIVING_CLASSES if self.schema in k.lower()] if self.schema!='snap': self.ArchivingClasses.append('ArchivingManager') return self.ArchivingClasses def __del__(self): try: self.log.debug( 'Deleting ArchivingAPI ...') for p in self.proxies.values(): del p del self.tango for d in self.dbs.values(): del d except: pass #print('Unable to delete API object') def __repr__(self): '''The status of Archiving device servers ''' return '%s(%s[%s])' % (type(self),self.schema,len(self)) #if self.servers: #report='The status of %s Archiving device servers is:\n'%self.schema #for k,v in self.servers.items(): #report+='%s:\t%s\n'%(k,v.state) #if self.WatcherClass: #try: report+=self.proxies( #self.servers.get_class_devices(self.WatcherClass)[0] #).command_inout('GetReportCurrent')+'\n' #except: pass #return report #################################################################################################### def get_random_device(self,klass,timeout=300000): device = None if not getattr(self,'servers',None): self.load_servers(filters=[klass]) remaining = self.servers.get_class_devices(klass) if not remaining: self.servers.load_by_name(klass) remaining = self.servers.get_class_devices(klass) while remaining: #for i in range(len(self.extractors)): next = randrange(len(remaining)) devname = remaining.pop(next) device = self.servers.proxies[devname] print devname try: device.ping() device.set_timeout_millis(timeout) break except Exception,e: self.log.info('%s unreachable: %s'%(devname,str(e))) return device
class CommonAPI(Object,fandango.SingletonMap): """ This class provides common methods for managing a Soleil-like database (for either archiving or snapshoting) The methods starting by "get" retrieve values using ArchivingDSs The methods starting by "load" access directly to MySQL database """ #ArchivingTypes = ARCHIVING_TYPES #ArchivingClasses = ARCHIVING_CLASSES MAX_SERVERS_FOR_CLASS=5 MIN_ARCHIVING_PERIOD=10 def __init__(self,schema,host=None,user='******',passwd='browser',classes=[],LogLevel='info',load=True,logger=None): """ """ self.log = logger or Logger('ArchivingAPI(%s)'%schema,format='%(levelname)-8s %(asctime)s %(name)s: %(message)s') self.log.setLogLevel(LogLevel) self.log.debug('Logger streams initialized (error,warning,info,debug)') self.tango = fandango.get_database() #access to Tango database self.api = self #hook used by legacy packages self.servers = None self.schema = str(schema).lower() self.user,self.passwd = user,passwd if host is None: prop = self.tango.get_class_property('%sArchiver'%schema,['DbHost'])['DbHost'] if not prop: print('ERROR: %sArchiver.DbHost property not defined!'%schema) self.host = None else: self.host = prop[0] #if 'TANGO_HOST' in os.environ: # self.host=os.environ['TANGO_HOST'].split(':')[0] else: self.host=host self.dbs={} #pointers to Archiving databases self.ArchivingClasses = classes or self.get_archiving_classes() self.ArchiverClass = (k for k in self.ArchivingClasses if 'Archiver' in k).next() self.ManagerClass = (k for k in self.ArchivingClasses if 'Manager' in k).next() self.ExtractorClass = (k for k in self.ArchivingClasses if 'Extractor' in k).next() try: self.WatcherClass = (k for k in self.ArchivingClasses if 'Watcher' in k).next() except: self.WatcherClass = None self.loads=CaselessDefaultDict(lambda k:0) #a dict with the archiving load for each device self.attributes=CaselessDict() #a dict of ArchivedAttribute objects self.dedicated = CaselessDefaultDict(lambda k:set()) #Dictionary for keeping the attributes reserved for each archiver if load and self.host and self.ArchivingClasses: self.load_servers() ## The ArchivingAPI is an iterator through archived attributes def __getitem__(self,k): k = k if k.count('/')<=3 else fandango.tango.get_normal_name(k) return self.attributes.__getitem__(k) def __contains__(self,k): k = k if k.count('/')<=3 else fandango.tango.get_normal_name(k) return self.attributes.__contains__(k) def get(self,k): k = k if k.count('/')<=3 else fandango.tango.get_normal_name(k) return self.attributes.get(k) def has_key(self,k): k = k if k.count('/')<=3 else fandango.tango.get_normal_name(k) return self.attributes.has_key(k) #[setattr(self,method,lambda k,meth=method:getattr(self.attributes,meth)(k)) for method in ('__getitem__','__contains__','get','has_key')] def __iter__(self): return self.attributes.__iter__() def iteritems(self): return self.attributes.iteritems() def keys(self): return self.attributes.keys() def values(self): return self.attributes.values() def __len__(self): return len(self.attributes.keys()) def items(self): return self.attributes.items() #[setattr(self,method,lambda meth=method:getattr(self.attributes,meth)()) for method in ('__iter__','iteritems','items','keys','values')] def load_servers(self,filters=None): if getattr(self,'servers',None) is None: self.servers = ServersDict() [self.servers.load_by_name(k) for k in (filters or self.ArchivingClasses)] self.servers.refresh() self.proxies = self.servers.proxies return self.servers def get_servers(self): if not getattr(self,'servers',None): return self.load_servers() return self.servers def get_archiving_classes(self): self.ArchivingClasses = [k for k in ARCHIVING_CLASSES if self.schema in k.lower()] if self.schema!='snap': self.ArchivingClasses.append('ArchivingManager') return self.ArchivingClasses def __del__(self): try: self.log.debug( 'Deleting ArchivingAPI ...') for p in self.proxies.values(): del p del self.tango for d in self.dbs.values(): del d except: pass #print('Unable to delete API object') def __repr__(self): '''The status of Archiving device servers ''' return '%s(%s[%s])' % (type(self),self.schema,len(self)) #if self.servers: #report='The status of %s Archiving device servers is:\n'%self.schema #for k,v in self.servers.items(): #report+='%s:\t%s\n'%(k,v.state) #if self.WatcherClass: #try: report+=self.proxies( #self.servers.get_class_devices(self.WatcherClass)[0] #).command_inout('GetReportCurrent')+'\n' #except: pass #return report #################################################################################################### def get_random_device(self,klass,timeout=300000): device = None if not getattr(self,'servers',None): self.load_servers(filters=[klass]) remaining = self.servers.get_class_devices(klass) if not remaining: self.servers.load_by_name(klass) remaining = self.servers.get_class_devices(klass) while remaining: #for i in range(len(self.extractors)): next = randrange(len(remaining)) devname = remaining.pop(next) device = self.servers.proxies[devname] print devname try: device.ping() device.set_timeout_millis(timeout) break except Exception,e: self.log.info('%s unreachable: %s'%(devname,str(e))) return device