DefaultAlertService extends DefaultJPAService implements AlertService { public Long getTriggerFiredDatapointTime(Trigger trigger, Metric metric, String queryExpression, Long alertEnqueueTimestamp) { List<Map.Entry<Long, Double>> sortedDatapoints = new ArrayList<>(metric.getDatapoints().entrySet()); if (metric.getDatapoints().isEmpty()) { return null; } else if (metric.getDatapoints().size() == 1) { if (trigger.getInertia().compareTo(0L) <= 0) { if (Trigger.evaluateTrigger(trigger, sortedDatapoints.get(0).getValue())) { return sortedDatapoints.get(0).getKey(); } else { return null; } } else { return null; } } Collections.sort(sortedDatapoints, new Comparator<Map.Entry<Long, Double>>() { @Override public int compare(Entry<Long, Double> e1, Entry<Long, Double> e2) { return e1.getKey().compareTo(e2.getKey()); } }); int endIndex = sortedDatapoints.size(); if(trigger.getType().equals(TriggerType.NO_DATA)) { if(trigger.getInertia()>0) { Long[] queryTimes = AlertUtils.getStartAndEndTimes(queryExpression, alertEnqueueTimestamp); if(((sortedDatapoints.get(0).getKey()-queryTimes[0]) > trigger.getInertia())){ return sortedDatapoints.get(0).getKey(); } if((queryTimes[1] - sortedDatapoints.get(sortedDatapoints.size()-1).getKey()) > trigger.getInertia()) { return sortedDatapoints.get(sortedDatapoints.size()-1).getKey(); } if(sortedDatapoints.size()>1) { for(int i=1; i<sortedDatapoints.size(); i++) { if((sortedDatapoints.get(i).getKey()-sortedDatapoints.get(i-1).getKey()) > trigger.getInertia()) { return sortedDatapoints.get(i-1).getKey(); } } } } }else { for(int startIndex=sortedDatapoints.size()-1; startIndex>=0; startIndex--){ if(Trigger.evaluateTrigger(trigger, sortedDatapoints.get(startIndex).getValue())){ Long interval = sortedDatapoints.get(endIndex-1).getKey() - sortedDatapoints.get(startIndex).getKey(); if(interval >= trigger.getInertia()) return sortedDatapoints.get(endIndex-1).getKey(); }else{ endIndex=startIndex; } } } return null; } @Inject  DefaultAlertService(SystemConfiguration configuration, MQService mqService, MetricService metricService,
							   AuditService auditService, TSDBService tsdbService, MailService mailService, HistoryService historyService,
							   MonitorService monitorService, ImageDataRetriever imageDataRetriever, NotifierFactory notifierFactory, Provider<EntityManager> emProvider); @Override @Transactional Alert updateAlert(Alert alert); @Override @Transactional void deleteAlert(String name, PrincipalUser owner); @Override @Transactional void deleteAlert(Alert alert); @Override @Transactional void markAlertForDeletion(String name, PrincipalUser owner); @Override @Transactional void markAlertForDeletion(Alert alert); @Override List<Alert> findAlertsMarkedForDeletion(); @Override List<Alert> findAlertsMarkedForDeletion(final int limit); @Override List<Alert> findAlertsByOwner(PrincipalUser owner, boolean metadataOnly); @Override List<Alert> findAlertsByOwnerPaged(PrincipalUser owner, Integer limit, Integer offset, String searchText, String sortField, String sortOrder); @Override Alert findAlertByPrimaryKey(BigInteger id); @Override List<Alert> findAlertsByPrimaryKeys(List<BigInteger> ids); @Override void updateNotificationsActiveStatusAndCooldown(List<Notification> notifications); @Override @Transactional Integer executeScheduledAlerts(int alertCount, int timeout); void _processNotification(INotificationHandler notificationHandler,
									 Alert alert,
									 History history,
									 List<Metric> metrics,
									 Map<BigInteger, Map<Metric, Long>> triggerFiredTimesAndMetricsByTrigger,
									 Notification notification,
									 Long alertEnqueueTimestamp); void _processTriggerlessNotification(INotificationHandler notificationHandler,
												Alert alert,
												History history,
												List<Metric> metrics,
												Notification notification,
												Long alertEnqueueTimestamp); void _processMissingDataNotification(INotificationHandler notificationHandler,
												Alert alert,
												History history,
												Set<Trigger> triggers,
												Notification notification,
												boolean isDataMissing,
												Long alertEnqueueTimestamp); void sendNotification(Trigger trigger, Metric metric, History history, Notification notification, Alert alert,
			Long triggerFiredTime, Long alertEnqueueTime, String action); void sendClearNotification(Trigger trigger, Metric metric, History history, Notification notification, Alert alert, Long alertEnqueueTime, String action); @Override @Transactional Alert findAlertByNameAndOwner(String name, PrincipalUser owner); @Override void enqueueAlerts(List<Alert> alerts); @Override // IMPORTANT - @Transactional ?? - should not be as it shouldn't talk to the DB void testEvaluateAlert(String serializedAlert, Long when, String testUuid); @VisibleForTesting boolean testEvaluateAlert(Alert alert, Long alertEvaluationTime, AlertTestResults testResults); @Override List<Alert> findAllAlerts(boolean metadataOnly); @Override List<Alert> findAlertsByStatus(boolean enabled); @Override List<BigInteger> findAlertIdsByStatus(boolean enabled); @Override List<Alert> findAlertsByRangeAndStatus(BigInteger fromId, BigInteger toId, boolean enabled); @Override List<Alert> findAlertsModifiedAfterDate(Date modifiedDate); @Override int alertCountByStatus(boolean enabled); @Override List<Alert> findAlertsByLimitOffsetStatus(int limit, int offset,
			boolean enabled); @Override List<Alert> findAlertsByNameWithPrefix(String prefix); @Override List<String> getSupportedNotifiers(); @Override List<Alert> findSharedAlerts(boolean metadataOnly, PrincipalUser owner, Integer limit); @Override List<Alert> findSharedAlertsPaged(Integer limit, Integer offset, String searchText, String sortField, String sortOrder); @Override List<Alert> findPrivateAlertsForPrivilegedUserPaged(PrincipalUser owner, Integer limit, Integer offset, String searchText,
		String sortField, String sortOrder); @Override int countAlerts(AlertsCountContext context); @Override Notifier getNotifier(SupportedNotifier notifier); @Override void dispose(); Long getTriggerFiredDatapointTime(Trigger trigger, Metric metric, String queryExpression, Long alertEnqueueTimestamp); Long getLatestDatapointTime(Metric metric, String queryExpression, Long alertEnqueueTimestamp); @Override @Transactional void deleteTrigger(Trigger trigger); @Override @Transactional void deleteNotification(Notification notification); @Override void exportMetric(Metric metric, Double value); @Override void updateCounter(Counter counter, Double value);  }
@Test public void testGetTriggerFiredDatapointTime() { UserService userService = system.getServiceFactory().getUserService(); Alert alert = new Alert(userService.findAdminUser(), userService.findAdminUser(), "alert-name_test", EXPRESSION, "* * * * *"); Metric metric = new Metric("scope", "metric"); double thresholdValue = 90; long inertia = 10; long startTime = 1; long expectedTriggerTime; Trigger trigger = new Trigger(alert, TriggerType.GREATER_THAN_OR_EQ, "name_test", thresholdValue, inertia); Map<Long, String> datapoints = new HashMap<Long, String>(); datapoints.putAll(_createDatapoints(inertia + 1, thresholdValue, startTime, true)); metric.setDatapoints(_convertDatapoints(datapoints)); expectedTriggerTime = datapoints.size(); long actualValue = alertService.getTriggerFiredDatapointTime(trigger, metric, alert.getExpression(), startTime); assertEquals(expectedTriggerTime, actualValue); startTime = datapoints.size() + 1; datapoints.putAll(_createDatapoints(201, thresholdValue, startTime, false)); metric.setDatapoints(_convertDatapoints(datapoints)); actualValue = alertService.getTriggerFiredDatapointTime(trigger, metric, alert.getExpression(), startTime); assertEquals(expectedTriggerTime, actualValue); startTime = datapoints.size() + 1; datapoints.putAll(_createDatapoints(inertia - 1, thresholdValue, startTime, true)); metric.setDatapoints(_convertDatapoints(datapoints)); actualValue = alertService.getTriggerFiredDatapointTime(trigger, metric, alert.getExpression(), startTime); assertEquals(expectedTriggerTime, actualValue); startTime = datapoints.size() + 1; datapoints.putAll(_createDatapoints(inertia + 1, thresholdValue, startTime, true)); metric.setDatapoints(_convertDatapoints(datapoints)); actualValue = alertService.getTriggerFiredDatapointTime(trigger, metric, alert.getExpression(), startTime); expectedTriggerTime = datapoints.size(); assertEquals(expectedTriggerTime, actualValue); startTime = datapoints.size() + 1; datapoints.putAll(_createDatapoints(201, thresholdValue, startTime, false)); metric.setDatapoints(_convertDatapoints(datapoints)); actualValue = alertService.getTriggerFiredDatapointTime(trigger, metric, alert.getExpression(), startTime); assertEquals(expectedTriggerTime, actualValue); }
@Test public void testGetTriggerFiredDatapointTimeWhenOneDatapointAndZeroInertia() { UserService userService = system.getServiceFactory().getUserService(); Alert alert = new Alert(userService.findAdminUser(), userService.findAdminUser(), "alert-name_test", EXPRESSION, "* * * * *"); Metric metric = new Metric("scope", "metric"); double thresholdValue = 90; long inertia = 0; long startTime = 1000; long expectedTriggerTime; Trigger trigger = new Trigger(alert, TriggerType.GREATER_THAN_OR_EQ, "name_test", thresholdValue, inertia); Map<Long, String> datapoints = new HashMap<Long, String>(); datapoints.putAll(_createDatapoints(1, thresholdValue, startTime, true)); metric.setDatapoints(_convertDatapoints(datapoints)); expectedTriggerTime = startTime; long actualValue = alertService.getTriggerFiredDatapointTime(trigger, metric, alert.getExpression(), startTime); assertEquals(expectedTriggerTime, actualValue); }
@Test public void testGetTriggerFiredDatapointTimeWhenOneDatapointAndInertiaOne() { UserService userService = system.getServiceFactory().getUserService(); Alert alert = new Alert(userService.findAdminUser(), userService.findAdminUser(), "alert-name_test", EXPRESSION, "* * * * *"); Metric metric = new Metric("scope", "metric"); double thresholdValue = 90; long inertia = 1; long startTime = 1000; Trigger trigger = new Trigger(alert, TriggerType.GREATER_THAN_OR_EQ, "name_test", thresholdValue, inertia); Map<Long, String> datapoints = new HashMap<Long, String>(); datapoints.putAll(_createDatapoints(1, thresholdValue, startTime, true)); metric.setDatapoints(_convertDatapoints(datapoints)); Long actualValue = alertService.getTriggerFiredDatapointTime(trigger, metric, alert.getExpression(), startTime); assertNull(actualValue); }
@Test public void testGetTriggerFiredDatapointTimeWhenNoDatapoints() { UserService userService = system.getServiceFactory().getUserService(); Alert alert = new Alert(userService.findAdminUser(), userService.findAdminUser(), "alert-name_test", EXPRESSION, "* * * * *"); Metric metric = new Metric("scope", "metric"); double thresholdValue = 90; long inertia = 0; long startTime = 1000; Trigger trigger = new Trigger(alert, TriggerType.GREATER_THAN_OR_EQ, "name_test", thresholdValue, inertia); Map<Long, String> datapoints = new HashMap<Long, String>(); datapoints.putAll(_createDatapoints(0, thresholdValue, startTime, true)); metric.setDatapoints(_convertDatapoints(datapoints)); Long actualValue = alertService.getTriggerFiredDatapointTime(trigger, metric, alert.getExpression(), startTime); assertNull(actualValue); }
@Test public void testGetTriggerFiredDatapointTimeWhenMissingTimeStamps() { UserService userService = system.getServiceFactory().getUserService(); Alert alert = new Alert(userService.findAdminUser(), userService.findAdminUser(), "alert-name_test", EXPRESSION, "* * * * *"); Metric metric = new Metric("scope", "metric"); double thresholdValue = 1; long inertia = 5*60*1000; Trigger trigger = new Trigger(alert, TriggerType.GREATER_THAN_OR_EQ, "name_test", thresholdValue, inertia); Map<Long, String> datapoints = new HashMap<Long, String>(); datapoints.put(0L, "1"); datapoints.put(inertia, "1"); metric.setDatapoints(_convertDatapoints(datapoints)); long actualValue = alertService.getTriggerFiredDatapointTime(trigger, metric, alert.getExpression(), 1L); long expectedTriggerTime=5*60*1000; assertEquals(expectedTriggerTime, actualValue); }
@Test public void testGetTriggerFiredDatapointTimeWhenMissingTimeStamps2() { UserService userService = system.getServiceFactory().getUserService(); Alert alert = new Alert(userService.findAdminUser(), userService.findAdminUser(), "alert-name_test", EXPRESSION, "* * * * *"); Metric metric = new Metric("scope", "metric"); double thresholdValue = 1; long inertia = 5*60*1000; Trigger trigger = new Trigger(alert, TriggerType.GREATER_THAN_OR_EQ, "name_test", thresholdValue, inertia); Map<Long, String> datapoints = new HashMap<Long, String>(); datapoints.put(0L, "1"); datapoints.put(3*60*1000L, "1"); datapoints.put(inertia, "1"); metric.setDatapoints(_convertDatapoints(datapoints)); long actualValue = alertService.getTriggerFiredDatapointTime(trigger, metric, alert.getExpression(), 1L); long expectedTriggerTime=5*60*1000; assertEquals(expectedTriggerTime, actualValue); }
@Test public void testGetTriggerFiredDatapointTimeWhenMissingTimeStamps3() { UserService userService = system.getServiceFactory().getUserService(); Alert alert = new Alert(userService.findAdminUser(), userService.findAdminUser(), "alert-name_test", EXPRESSION, "* * * * *"); Metric metric = new Metric("scope", "metric"); double thresholdValue = 1; long inertia = 5*60*1000; Trigger trigger = new Trigger(alert, TriggerType.GREATER_THAN_OR_EQ, "name_test", thresholdValue, inertia); Map<Long, String> datapoints = new HashMap<Long, String>(); datapoints.put(0L, "1"); datapoints.put(9*60*1000L, "1"); metric.setDatapoints(_convertDatapoints(datapoints)); long actualValue = alertService.getTriggerFiredDatapointTime(trigger, metric, alert.getExpression(), 1L); long expectedTriggerTime=9*60*1000; assertEquals(expectedTriggerTime, actualValue); }
@Test public void testGetTriggerFiredDatapointTimeWhenMissingTimeStamps4() { UserService userService = system.getServiceFactory().getUserService(); Alert alert = new Alert(userService.findAdminUser(), userService.findAdminUser(), "alert-name_test", EXPRESSION, "* * * * *"); Metric metric = new Metric("scope", "metric"); double thresholdValue = 1; long inertia = 5*60*1000; Trigger trigger = new Trigger(alert, TriggerType.GREATER_THAN_OR_EQ, "name_test", thresholdValue, inertia); Map<Long, Double> datapoints = new HashMap<Long, Double>(); datapoints.put(0L, 2.0); datapoints.put(3*60*1000L, 2.0); datapoints.put(6*60*1000L, 2.0); datapoints.put(7*60*1000L, 0.0); datapoints.put(9*60*1000L, 2.0); metric.setDatapoints(datapoints); long actualValue = alertService.getTriggerFiredDatapointTime(trigger, metric, alert.getExpression(), 1L); long expectedTriggerTime = 6 * 60 * 1000; assertEquals(expectedTriggerTime, actualValue); }
@Test public void testGetTriggerFiredDatapointTimeWhenMissingTimeStamps5() { UserService userService = system.getServiceFactory().getUserService(); Alert alert = new Alert(userService.findAdminUser(), userService.findAdminUser(), "alert-name_test", EXPRESSION, "* * * * *"); Metric metric = new Metric("scope", "metric"); double thresholdValue = 1; long inertia = 5*60*1000; Trigger trigger = new Trigger(alert, TriggerType.GREATER_THAN_OR_EQ, "name_test", thresholdValue, inertia); Map<Long, Double> datapoints = new HashMap<>(); datapoints.put(0L, 2.0); datapoints.put(3*60*1000L, 0.0); datapoints.put(6*60*1000L, 2.0); datapoints.put(7*60*1000L, 0.0); datapoints.put(9*60*1000L, 2.0); metric.setDatapoints(datapoints); Long actualValue = alertService.getTriggerFiredDatapointTime(trigger, metric, alert.getExpression(), 1L); assertNull(actualValue); }
@Test public void testGetTriggerFiredDatapointTimeWhenMissingTimeStampsReturnNull() { UserService userService = system.getServiceFactory().getUserService(); Alert alert = new Alert(userService.findAdminUser(), userService.findAdminUser(), "alert-name_test", EXPRESSION, "* * * * *"); Metric metric = new Metric("scope", "metric"); double thresholdValue = 1; long inertia = 5*60*1000; Trigger trigger = new Trigger(alert, TriggerType.GREATER_THAN_OR_EQ, "name_test", thresholdValue, inertia); Map<Long, Double> datapoints = new HashMap<>(); datapoints.put(0L, 1.0); datapoints.put(2*60*1000L, 0.0); datapoints.put(inertia, 1.0); metric.setDatapoints(datapoints); Long actualValue = alertService.getTriggerFiredDatapointTime(trigger, metric, alert.getExpression(), 1L); assertNull(actualValue); }