CheckRunner implements Runnable { @Override public final void run() { if (!check.isEnabled()) { return; } try { Map<String, Optional<BigDecimal>> targetValues = targetChecker.check(check); DateTime now = new DateTime(); BigDecimal warn = check.getWarn(); BigDecimal error = check.getError(); AlertType worstState; if (check.isAllowNoData()) { worstState = AlertType.OK; } else { worstState = AlertType.UNKNOWN; } List<Alert> interestingAlerts = new ArrayList<Alert>(); for (Entry<String, Optional<BigDecimal>> entry : targetValues.entrySet()) { String target = entry.getKey(); Optional<BigDecimal> value = entry.getValue(); if (!value.isPresent()) { if (!check.isAllowNoData()) { LOGGER.warn("No value present for {} and check must have data", target); } continue; } BigDecimal currentValue = value.get(); Alert lastAlert = alertsStore.getLastAlertForTargetOfCheck(target, check.getId()); AlertType lastState; if (lastAlert == null) { lastState = AlertType.OK; } else { lastState = lastAlert.getToType(); } AlertType currentState = valueChecker.checkValue(currentValue, warn, error); if (currentState.isWorseThan(worstState)) { worstState = currentState; } if (isStillOk(lastState, currentState)) { continue; } Alert alert = createAlert(target, currentValue, warn, error, lastState, currentState, now); alertsStore.createAlert(check.getId(), alert); if (stateIsTheSame(lastState, currentState)) { continue; } interestingAlerts.add(alert); } Check updatedCheck = checksStore.updateStateAndLastCheck(check.getId(), worstState, DateTime.now()); if (interestingAlerts.isEmpty()) { return; } for (Subscription subscription : updatedCheck.getSubscriptions()) { if (!subscription.shouldNotify(now, worstState)) { continue; } for (NotificationService notificationService : notificationServices) { if (notificationService.canHandle(subscription.getType())) { try { notificationService.sendNotification(updatedCheck, subscription, interestingAlerts); } catch (Exception e) { LOGGER.warn("Notifying {} by {} failed.", subscription.getTarget(), subscription.getType(), e); } } } } } catch (Exception e) { LOGGER.warn("{} failed", check.getName(), e); } } CheckRunner(Check check, AlertsStore alertsStore, ChecksStore checksStore, TargetChecker targetChecker, ValueChecker valueChecker,
            Iterable<NotificationService> notificationServices); @Override final void run();  }
@Test public void checkWhichIsNotEnabledDoesNothing() { when(mockCheck.isEnabled()).thenReturn(false); checkRunner.run(); }
@Test public void noTargetValuesUpdatesLastCheckWithUnknown() throws Exception { when(mockCheck.getId()).thenReturn("id"); when(mockCheck.isEnabled()).thenReturn(true); when(mockCheck.isAllowNoData()).thenReturn(false); when(mockTargetChecker.check(mockCheck)).thenReturn(new HashMap<String, Optional<BigDecimal>>()); when(mockChecksStore.updateStateAndLastCheck(eq("id"), eq(AlertType.UNKNOWN), any(DateTime.class))).thenReturn(mockCheck); checkRunner.run(); verify(mockChecksStore).updateStateAndLastCheck(eq("id"), eq(AlertType.UNKNOWN), any(DateTime.class)); }
@Test public void noTargetValuesButAllowNoDataUpdatesLastCheckWithOk() throws Exception { when(mockCheck.getId()).thenReturn("id"); when(mockCheck.isEnabled()).thenReturn(true); when(mockCheck.isAllowNoData()).thenReturn(true); when(mockTargetChecker.check(mockCheck)).thenReturn(new HashMap<String, Optional<BigDecimal>>()); when(mockChecksStore.updateStateAndLastCheck(eq("id"), eq(AlertType.OK), any(DateTime.class))).thenReturn(mockCheck); checkRunner.run(); verify(mockChecksStore).updateStateAndLastCheck(eq("id"), eq(AlertType.OK), any(DateTime.class)); }
@Test public void anExceptionWhileRunningIsHandled() throws Exception { when(mockCheck.isEnabled()).thenReturn(true); when(mockTargetChecker.check(mockCheck)).thenThrow(new Exception("Boom!")); checkRunner.run(); }
@Test public void emptyTargetValueDoesNothing() throws Exception { when(mockCheck.isEnabled()).thenReturn(true); Map<String, Optional<BigDecimal>> targetValues = new HashMap<String, Optional<BigDecimal>>(); targetValues.put("target", Optional.<BigDecimal>absent()); when(mockTargetChecker.check(mockCheck)).thenReturn(targetValues); checkRunner.run(); }
@Test public void noPreviousAlertAndHappyCurrentValueDoesNothing() throws Exception { BigDecimal value = BigDecimal.ONE; BigDecimal warn = BigDecimal.valueOf(2); BigDecimal error = BigDecimal.valueOf(3); when(mockCheck.getId()).thenReturn("id"); when(mockCheck.isEnabled()).thenReturn(true); when(mockCheck.getWarn()).thenReturn(warn); when(mockCheck.getError()).thenReturn(error); Map<String, Optional<BigDecimal>> targetValues = new HashMap<String, Optional<BigDecimal>>(); targetValues.put("target", Optional.of(value)); when(mockTargetChecker.check(mockCheck)).thenReturn(targetValues); when(mockAlertsStore.getLastAlertForTargetOfCheck("target", "id")).thenReturn(null); when(mockValueChecker.checkValue(value, warn, error)).thenReturn(AlertType.OK); checkRunner.run(); }