class NotificationManager {

    @Transactional(propagation = Propagation.REQUIRED)
    public void notifyIdleRuns(List<Pair<PipelineRun, Double>> pipelineCpuRatePairs,
                               NotificationType notificationType) {
        if (CollectionUtils.isEmpty(pipelineCpuRatePairs)) {
            return;
        }

        Assert.isTrue(NotificationGroup.IDLE_RUN == notificationType.getGroup(),
                      "Only IDLE_RUN group notification types are allowed");

        NotificationSettings idleRunSettings = notificationSettingsManager.load(notificationType);
        if (idleRunSettings == null || !idleRunSettings.isEnabled()) {
            LOGGER.info("No template configured for idle pipeline run notifications or it was disabled!");
            return;
        }

        final List<Long> ccUserIds = getCCUsers(idleRunSettings);
        final Map<String, PipelineUser> pipelineOwners = getPipelinesOwners(pipelineCpuRatePairs);

        final double idleCpuLevel = preferenceManager.getPreference(
                SystemPreferences.SYSTEM_IDLE_CPU_THRESHOLD_PERCENT);
        final String instanceTypesToExclude = preferenceManager.getPreference(SystemPreferences
                .SYSTEM_NOTIFICATIONS_EXCLUDE_INSTANCE_TYPES);

        final List<Pair<PipelineRun, Double>> filtered = pipelineCpuRatePairs.stream()
                .filter(pair -> shouldNotifyIdleRun(pair.getLeft().getId(), notificationType, idleRunSettings))
                .filter(pair -> noneMatchExcludedInstanceType(pair.getLeft(), instanceTypesToExclude))
                .collect(Collectors.toList());
        final List<NotificationMessage> messages = filtered.stream()
                .map(pair -> buildMessageForIdleRun(idleRunSettings, ccUserIds, pipelineOwners, idleCpuLevel, pair))
                .collect(Collectors.toList());
        monitoringNotificationDao.createMonitoringNotifications(messages);

        if (NotificationType.IDLE_RUN.equals(notificationType)) {
            final List<Long> runIds = filtered.stream()
                    .map(pair -> pair.getLeft().getId()).collect(Collectors.toList());
            monitoringNotificationDao.updateNotificationTimestamp(runIds, NotificationType.IDLE_RUN);
        }
    }

}