def _aggregate_successors(self, ctx, idcorrevent): """ Procède à l'agrégation des successeurs de l'événement corrélé courant. @param ctx: Contexte de corrélation. @type ctx: L{Context} @param idcorrevent: Identifiant de l'événement corrélé courant. @type idcorrevent: C{int} """ # Si un ou plusieurs agrégats dépendant de l'alerte sont # spécifiés dans le contexte par la règle de corrélation # topologique des services de bas niveau (lls_dep), alors # on rattache ces agrégats à l'agrégat nouvellement créé. aggregates_id = yield ctx.get('successors_aggregates') if aggregates_id: event_id_list = [] for aggregate_id in aggregates_id: events_id = yield merge_aggregates( int(aggregate_id), idcorrevent, self.database, ctx ) if events_id: event_id_list.extend(events_id) # On publie sur le bus la liste des alertes brutes # à rattacher à l'événement corrélé nouvellement créé. yield self.publisher.publish_aggregate([idcorrevent], event_id_list) yield self.publisher.delete_published_aggregates(aggregates_id)
def _aggregate_topologically(self, ctx, correvent, raw_event_id, item_id): """ Procède à une première passe d'agrégation topologique, basée sur les agrégats prédécesseurs de l'alerte courante. @param ctx: Contexte de corrélation. @type ctx: L{Context} @param raw_event_id: Identifiant de l'événement brut. @type raw_event_id: C{int} @param item_id: Identifiant de l'objet supervisé concerné. @type item_id: C{int} @return: Deferred indiquant si l'événement corrélé a été agrégé dans un autre (C{True}) ou non (C{False}). @rtype: L{bool} """ # Ajoute l'alerte aux agrégats prédécesseurs dont elle dépend. predecessing_aggregates_id = yield ctx.get('predecessors_aggregates') if not predecessing_aggregates_id: defer.returnValue(False) succeeding_aggregates_id = yield ctx.get('successors_aggregates') dependent_event_list = set() is_built_dependent_event_list = False predecessors_count = 0 # Pour chaque agrégat dont l'alerte dépend, for predecessing_aggregate_id in predecessing_aggregates_id: predecessing_aggregate_id = int(predecessing_aggregate_id) try: yield self.database.run( DBSession.query(CorrEvent).filter( CorrEvent.idcorrevent == predecessing_aggregate_id ).one, transaction=False, ) predecessors_count += 1 except NoResultFound: LOGGER.error(_('Got a reference to a nonexistent ' 'correlated event (%r), skipping this aggregate'), int(predecessing_aggregate_id)) else: # D'abord on rattache l'alerte # courante à cet agrégat dans la BDD. yield add_to_aggregate( raw_event_id, predecessing_aggregate_id, self.database, ctx, item_id, merging=True ) # Ensuite on fusionne les éventuels agrégats # dépendant de l'alerte courante avec cet agrégat. if succeeding_aggregates_id: for succeeding_aggregate_id in succeeding_aggregates_id: events = yield merge_aggregates( int(succeeding_aggregate_id), predecessing_aggregate_id, self.database, ctx ) if not is_built_dependent_event_list: dependent_event_list.update(events) is_built_dependent_event_list = True # On rattache l'alerte courante aux agrégats sur le bus. yield self.publisher.publish_aggregate( predecessing_aggregates_id, [raw_event_id]) if succeeding_aggregates_id: # On publie également sur le bus la # liste des alertes brutes (dépendantes de # l'alerte courante) à rattacher à ces agrégats. yield self.publisher.publish_aggregate( predecessing_aggregates_id, list(dependent_event_list)) # Enfin on supprime du bus les agrégats # qui dépendaient de l'alerte courante. yield self.publisher.delete_published_aggregates(succeeding_aggregates_id) if correvent: # On supprime l'agrégat courant (fusionné dans ses prédécesseurs). LOGGER.debug('Deleting obsolete aggregate #%d', correvent.idcorrevent) yield self.database.run( DBSession.query(CorrEvent).filter( CorrEvent.idcorrevent == correvent.idcorrevent).delete, transaction=False ) yield self.publisher.delete_published_aggregates(correvent.idcorrevent) yield self.database.run(DBSession.flush, transaction=False) defer.returnValue(predecessors_count != 0)