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]
Exemple #2
0
    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