Exemplo n.º 1
0
    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)
Exemplo n.º 2
0
    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)