def stop_uve_partition(self, part): for tk in self.ptab_info[part].keys(): for rkey in self.ptab_info[part][tk].keys(): uk = tk + ":" + rkey if tk in self.tab_alarms: if uk in self.tab_alarms[tk]: del self.tab_alarms[tk][uk] ustruct = UVEAlarms(name=rkey, deleted=True) alarm_msg = AlarmTrace(data=ustruct, table=tk) self._logger.error('send del alarm for stop: %s' % \ (alarm_msg.log())) alarm_msg.send(sandesh=self._sandesh) del self.ptab_info[part][tk][rkey] self._logger.error("UVE %s deleted in stop" % (uk)) del self.ptab_info[part][tk] del self.ptab_info[part]
def handle_uve_notif(self, part, uves): """ Call this function when a UVE has changed. This can also happed when taking ownership of a partition, or when a generator is deleted. Args: part : Partition Number uve : dict, where the key is the UVE Name. The value is either a dict of UVE structs, or "None", which means that all UVE structs should be processed. Returns: status of operation (True for success) """ self._logger.debug("Changed part %d UVEs : %s" % (part, str(uves))) success = True output = {} for uv, types in uves.iteritems(): tab = uv.split(':', 1)[0] if tab not in self.tab_perf: self.tab_perf[tab] = AGTabStats() uve_name = uv.split(':', 1)[1] prevt = UTCTimestampUsec() filters = {} if types: filters["cfilt"] = {} for typ in types.keys(): filters["cfilt"][typ] = set() failures, uve_data = self._us.get_uve(uv, True, filters) if failures: success = False self.tab_perf[tab].record_get(UTCTimestampUsec() - prevt) # Handling Agg UVEs if not part in self.ptab_info: self._logger.error("Creating UVE table for part %s" % str(part)) self.ptab_info[part] = {} if not tab in self.ptab_info[part]: self.ptab_info[part][tab] = {} if uve_name not in self.ptab_info[part][tab]: self.ptab_info[part][tab][uve_name] = AGKeyInfo(part) prevt = UTCTimestampUsec() output[uv] = {} touched = False if not types: self.ptab_info[part][tab][uve_name].update(uve_data) if len(self.ptab_info[part][tab][uve_name].removed()): touched = True self._logger.info("UVE %s removed structs %s" % (uve_name, \ self.ptab_info[part][tab][uve_name].removed())) for rems in self.ptab_info[part][tab][uve_name].removed(): output[uv][rems] = None if len(self.ptab_info[part][tab][uve_name].changed()): touched = True self._logger.debug("UVE %s changed structs %s" % (uve_name, \ self.ptab_info[part][tab][uve_name].changed())) for chgs in self.ptab_info[part][tab][uve_name].changed(): output[uv][chgs] = \ self.ptab_info[part][tab][uve_name].values()[chgs] if len(self.ptab_info[part][tab][uve_name].added()): touched = True self._logger.debug("UVE %s added structs %s" % (uve_name, \ self.ptab_info[part][tab][uve_name].added())) for adds in self.ptab_info[part][tab][uve_name].added(): output[uv][adds] = \ self.ptab_info[part][tab][uve_name].values()[adds] else: for typ in types: val = None if typ in uve_data: val = uve_data[typ] self.ptab_info[part][tab][uve_name].update_single(typ, val) if len(self.ptab_info[part][tab][uve_name].removed()): touched = True self._logger.info("UVE %s removed structs %s" % (uve_name, \ self.ptab_info[part][tab][uve_name].removed())) for rems in self.ptab_info[part][tab][ uve_name].removed(): output[uv][rems] = None if len(self.ptab_info[part][tab][uve_name].changed()): touched = True self._logger.debug("UVE %s changed structs %s" % (uve_name, \ self.ptab_info[part][tab][uve_name].changed())) for chgs in self.ptab_info[part][tab][ uve_name].changed(): output[uv][chgs] = \ self.ptab_info[part][tab][uve_name].values()[chgs] if len(self.ptab_info[part][tab][uve_name].added()): touched = True self._logger.debug("UVE %s added structs %s" % (uve_name, \ self.ptab_info[part][tab][uve_name].added())) for adds in self.ptab_info[part][tab][uve_name].added( ): output[uv][adds] = \ self.ptab_info[part][tab][uve_name].values()[adds] if not touched: del output[uv] local_uve = self.ptab_info[part][tab][uve_name].values() self.tab_perf[tab].record_pub(UTCTimestampUsec() - prevt) if len(local_uve.keys()) == 0: self._logger.info("UVE %s deleted in proc" % (uv)) del self.ptab_info[part][tab][uve_name] output[uv] = None # Both alarm and non-alarm contents are gone. # We do not need to do alarm evaluation continue # Withdraw the alarm if the UVE has no non-alarm structs if len(local_uve.keys()) == 1 and "UVEAlarms" in local_uve: if tab in self.tab_alarms: if uv in self.tab_alarms[tab]: del self.tab_alarms[tab][uv] ustruct = UVEAlarms(name=uve_name, deleted=True) alarm_msg = AlarmTrace(data=ustruct, table=tab, \ sandesh=self._sandesh) self._logger.info('send del alarm: %s' % (alarm_msg.log())) alarm_msg.send(sandesh=self._sandesh) continue # Handing Alarms if not self.mgrs.has_key(tab): continue prevt = UTCTimestampUsec() #TODO: We may need to remove alarm from local_uve before # alarm evaluation # if "UVEAlarms" in uve_data: # del uve_data["UVEAlarms"] results = self.mgrs[tab].map_method("__call__", uv, local_uve) self.tab_perf[tab].record_call(UTCTimestampUsec() - prevt) new_uve_alarms = {} for res in results: nm, sev, errs = res self._logger.debug("Alarm[%s] %s: %s" % (tab, nm, str(errs))) elems = [] for ae in errs: rule, val = ae rv = AlarmElement(rule, val) elems.append(rv) if len(elems): new_uve_alarms[nm] = UVEAlarmInfo(type=nm, severity=sev, timestamp=0, token="", description=elems, ack=False) del_types = [] if self.tab_alarms[tab].has_key(uv): for nm, uai in self.tab_alarms[tab][uv].iteritems(): uai2 = copy.deepcopy(uai) uai2.timestamp = 0 uai2.token = "" # This type was present earlier, but is now gone if not new_uve_alarms.has_key(nm): del_types.append(nm) else: # This type has no new information if uai2 == new_uve_alarms[nm]: del new_uve_alarms[nm] if len(del_types) != 0 or \ len(new_uve_alarms) != 0: self._logger.debug("Alarm[%s] Deleted %s" % \ (tab, str(del_types))) self._logger.debug("Alarm[%s] Updated %s" % \ (tab, str(new_uve_alarms))) # These alarm types are new or updated for nm, uai2 in new_uve_alarms.iteritems(): uai = copy.deepcopy(uai2) uai.timestamp = UTCTimestampUsec() uai.token = Controller.token(self._sandesh, uai.timestamp) if not self.tab_alarms[tab].has_key(uv): self.tab_alarms[tab][uv] = {} self.tab_alarms[tab][uv][nm] = uai # These alarm types are now gone for dnm in del_types: del self.tab_alarms[tab][uv][dnm] ustruct = None if len(self.tab_alarms[tab][uv]) == 0: ustruct = UVEAlarms(name=uve_name, deleted=True) del self.tab_alarms[tab][uv] else: alm_copy = copy.deepcopy(self.tab_alarms[tab][uv]) ustruct = UVEAlarms(name=uve_name, alarms=alm_copy.values(), deleted=False) alarm_msg = AlarmTrace(data=ustruct, table=tab, \ sandesh=self._sandesh) self._logger.info('send alarm: %s' % (alarm_msg.log())) alarm_msg.send(sandesh=self._sandesh) if success: return output else: return None