| 250 | } |
| 251 | |
| 252 | void Notification::BeginExecuteNotification(NotificationType type, const CheckResult::Ptr& cr, bool force, bool reminder, const String& author, const String& text) |
| 253 | { |
| 254 | String notificationName = GetName(); |
| 255 | String notificationTypeName = NotificationTypeToString(type); |
| 256 | |
| 257 | Log(LogNotice, "Notification") |
| 258 | << "Attempting to send " << (reminder ? "reminder " : "") |
| 259 | << "notifications of type '" << notificationTypeName |
| 260 | << "' for notification object '" << notificationName << "'."; |
| 261 | |
| 262 | Checkable::Ptr checkable = GetCheckable(); |
| 263 | |
| 264 | // Clear the last notified problem state per user if we're sending a recovery notification or if we're sending a |
| 265 | // flapping end notification and the checkable is already in an OK state. This is necessary since we might have |
| 266 | // missed the recovery notification due to the flapping state. |
| 267 | if (IsRecoveryOrFlappingEndAndCheckableIsOK(checkable, cr, type)) { |
| 268 | auto states (GetLastNotifiedStatePerUser()); |
| 269 | |
| 270 | states->Clear(); |
| 271 | OnLastNotifiedStatePerUserCleared(this, nullptr); |
| 272 | } |
| 273 | |
| 274 | if (!force) { |
| 275 | TimePeriod::Ptr tp = GetPeriod(); |
| 276 | |
| 277 | if (tp && !tp->IsInside(Utility::GetTime())) { |
| 278 | Log(LogNotice, "Notification") |
| 279 | << "Not sending " << (reminder ? "reminder " : "") << "notifications for notification object '" << notificationName |
| 280 | << "': not in timeperiod '" << tp->GetName() << "'"; |
| 281 | |
| 282 | if (!reminder) { |
| 283 | switch (type) { |
| 284 | case NotificationProblem: |
| 285 | case NotificationRecovery: |
| 286 | case NotificationFlappingStart: |
| 287 | case NotificationFlappingEnd: |
| 288 | { |
| 289 | /* If a non-reminder notification was suppressed, but just because of its time period, |
| 290 | * stash it into a notification types bitmask for maybe re-sending later. |
| 291 | */ |
| 292 | |
| 293 | ObjectLock olock (this); |
| 294 | int suppressedTypesBefore (GetSuppressedNotifications()); |
| 295 | int suppressedTypesAfter (suppressedTypesBefore | type); |
| 296 | |
| 297 | for (int conflict : {NotificationProblem | NotificationRecovery, NotificationFlappingStart | NotificationFlappingEnd}) { |
| 298 | /* E.g. problem and recovery notifications neutralize each other. */ |
| 299 | |
| 300 | if ((suppressedTypesAfter & conflict) == conflict) { |
| 301 | suppressedTypesAfter &= ~conflict; |
| 302 | } |
| 303 | } |
| 304 | |
| 305 | if (suppressedTypesAfter != suppressedTypesBefore) { |
| 306 | SetSuppressedNotifications(suppressedTypesAfter); |
| 307 | } |
| 308 | } |
| 309 | default: |
no test coverage detected