class NotificationManager {

    @Transactional(propagation = Propagation.REQUIRED)
    public void notifyStuckInStatusRuns(final List<PipelineRun> runs) {
        final NotificationSettings settings = notificationSettingsManager.load(NotificationType.LONG_STATUS);

        if (settings == null || !settings.isEnabled() || settings.getTemplateId() == 0) {
            LOGGER.info("No template configured for stuck status notifications or it was disabled!");
            return;
        }

        final LocalDateTime now = DateUtils.nowUTC();
        final Long threshold = settings.getThreshold();
        if (threshold == null || threshold <= 0) {
            return;
        }
        runs.stream()
                .filter(run -> isRunStuckInStatus(settings, now, threshold, run))
                .forEach(run -> {
                    LOGGER.debug("Sending stuck status {} notification for run {}.",
                            run.getStatus(), run.getId());
                    final NotificationMessage notificationMessage = new NotificationMessage();
                    if (settings.isKeepInformedOwner()) {
                        PipelineUser pipelineOwner = userManager.loadUserByName(run.getOwner());
                        notificationMessage.setToUserId(pipelineOwner.getId());
                    }
                    notificationMessage.setCopyUserIds(getCCUsers(settings));
                    notificationMessage.setTemplate(new NotificationTemplate(settings.getTemplateId()));
                    notificationMessage.setTemplateParameters(PipelineRunMapper.map(run, settings.getThreshold()));
                    monitoringNotificationDao.createMonitoringNotification(notificationMessage);
                });
    }

}