Merge pull request #9212 from Icinga/bugfix/multi-ido-notification-id

IDO: fix incorrect contacts in notification history with multiple IDO instances on a single node
This commit is contained in:
Julian Brost 2022-02-21 11:40:46 +01:00 committed by GitHub
commit 5383df3c79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 79 additions and 54 deletions

View File

@ -45,8 +45,19 @@ void DbConnection::Start(bool runtimeCreated)
Log(LogInformation, "DbConnection") Log(LogInformation, "DbConnection")
<< "'" << GetName() << "' started."; << "'" << GetName() << "' started.";
DbObject::OnQuery.connect([this](const DbQuery& query) { ExecuteQuery(query); }); auto onQuery = [this](const DbQuery& query) { ExecuteQuery(query); };
DbObject::OnMultipleQueries.connect([this](const std::vector<DbQuery>& multiQueries) { ExecuteMultipleQueries(multiQueries); }); DbObject::OnQuery.connect(onQuery);
auto onMultipleQueries = [this](const std::vector<DbQuery>& multiQueries) { ExecuteMultipleQueries(multiQueries); };
DbObject::OnMultipleQueries.connect(onMultipleQueries);
DbObject::QueryCallbacks queryCallbacks;
queryCallbacks.Query = onQuery;
queryCallbacks.MultipleQueries = onMultipleQueries;
DbObject::OnMakeQueries.connect([queryCallbacks](const std::function<void (const DbObject::QueryCallbacks&)>& queryFunc) {
queryFunc(queryCallbacks);
});
} }
void DbConnection::Stop(bool runtimeRemoved) void DbConnection::Stop(bool runtimeRemoved)

View File

@ -837,6 +837,12 @@ void DbEvents::AddAcknowledgementInternal(const Checkable::Ptr& checkable, Ackno
void DbEvents::AddNotificationHistory(const Notification::Ptr& notification, const Checkable::Ptr& checkable, const std::set<User::Ptr>& users, NotificationType type, void DbEvents::AddNotificationHistory(const Notification::Ptr& notification, const Checkable::Ptr& checkable, const std::set<User::Ptr>& users, NotificationType type,
const CheckResult::Ptr& cr, const String& author, const String& text) const CheckResult::Ptr& cr, const String& author, const String& text)
{ {
/* NotificationInsertID has to be tracked per IDO instance, therefore the OnQuery and OnMultipleQueries signals
* cannot be called directly as all IDO instances would insert rows with the same ID which is (most likely) only
* correct in one database. Instead, pass a lambda which generates the queries with new DbValue for
* NotificationInsertID each IDO instance.
*/
DbObject::OnMakeQueries([&checkable, &users, &type, &cr](const DbObject::QueryCallbacks& callbacks) {
/* start and end happen at the same time */ /* start and end happen at the same time */
std::pair<unsigned long, unsigned long> timeBag = ConvertTimestamp(Utility::GetTime()); std::pair<unsigned long, unsigned long> timeBag = ConvertTimestamp(Utility::GetTime());
@ -879,7 +885,7 @@ void DbEvents::AddNotificationHistory(const Notification::Ptr& notification, con
fields1->Set("endpoint_object_id", endpoint); fields1->Set("endpoint_object_id", endpoint);
query1.Fields = fields1; query1.Fields = fields1;
DbObject::OnQuery(query1); callbacks.Query(query1);
std::vector<DbQuery> queries; std::vector<DbQuery> queries;
@ -902,7 +908,8 @@ void DbEvents::AddNotificationHistory(const Notification::Ptr& notification, con
queries.emplace_back(std::move(query2)); queries.emplace_back(std::move(query2));
} }
DbObject::OnMultipleQueries(queries); callbacks.MultipleQueries(queries);
});
} }
/* statehistory */ /* statehistory */

View File

@ -25,6 +25,7 @@ using namespace icinga;
boost::signals2::signal<void (const DbQuery&)> DbObject::OnQuery; boost::signals2::signal<void (const DbQuery&)> DbObject::OnQuery;
boost::signals2::signal<void (const std::vector<DbQuery>&)> DbObject::OnMultipleQueries; boost::signals2::signal<void (const std::vector<DbQuery>&)> DbObject::OnMultipleQueries;
boost::signals2::signal<void (const std::function<void (const DbObject::QueryCallbacks&)>&)> DbObject::OnMakeQueries;
INITIALIZE_ONCE(&DbObject::StaticInitialize); INITIALIZE_ONCE(&DbObject::StaticInitialize);

View File

@ -61,8 +61,14 @@ public:
static DbObject::Ptr GetOrCreateByObject(const ConfigObject::Ptr& object); static DbObject::Ptr GetOrCreateByObject(const ConfigObject::Ptr& object);
struct QueryCallbacks {
std::function<void(const DbQuery&)> Query;
std::function<void(const std::vector<DbQuery>&)> MultipleQueries;
};
static boost::signals2::signal<void (const DbQuery&)> OnQuery; static boost::signals2::signal<void (const DbQuery&)> OnQuery;
static boost::signals2::signal<void (const std::vector<DbQuery>&)> OnMultipleQueries; static boost::signals2::signal<void (const std::vector<DbQuery>&)> OnMultipleQueries;
static boost::signals2::signal<void (const std::function<void (const QueryCallbacks&)>&)> OnMakeQueries;
void SendConfigUpdateHeavy(const Dictionary::Ptr& configFields); void SendConfigUpdateHeavy(const Dictionary::Ptr& configFields);
void SendConfigUpdateLight(); void SendConfigUpdateLight();