ThresholdChecker.java 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. package cz.senslog.analytics.utils.validator;
  2. import cz.senslog.analytics.domain.*;
  3. import java.time.OffsetDateTime;
  4. import java.util.*;
  5. import java.util.function.Consumer;
  6. import java.util.function.Predicate;
  7. import static java.util.Collections.emptyList;
  8. public class ThresholdChecker<DS extends TimeSeriesDatasource> {
  9. public static <T extends TimeSeriesDatasource> ThresholdChecker<T> disabled() {
  10. return ThresholdChecker.create(emptyList(), null, null);
  11. }
  12. private final Map<Long, List<Threshold>> thresholds;
  13. private final Validator<DS> validator;
  14. private final Consumer<ViolationReport> ifViolated;
  15. private final Map<Long, NotifyTrigger> notifyTriggerMap;
  16. public static <DS extends TimeSeriesDatasource> ThresholdChecker<DS> create(List<Threshold> thresholds,
  17. Validator<DS> validator,
  18. Consumer<ViolationReport> ifViolated)
  19. {
  20. return new ThresholdChecker<>(thresholds, validator, ifViolated);
  21. }
  22. public ThresholdChecker(List<Threshold> thresholds,
  23. Validator<DS> validator,
  24. Consumer<ViolationReport> ifViolated
  25. ) {
  26. this.validator = validator;
  27. this.ifViolated = ifViolated;
  28. this.notifyTriggerMap = new HashMap<>();
  29. this.thresholds = new HashMap<>();
  30. for (Threshold th : thresholds) {
  31. long sourceId = th.groupId();
  32. if (!notifyTriggerMap.containsKey(sourceId)) {
  33. this.notifyTriggerMap.put(sourceId, th.notifyTriggerType().createInstance());
  34. }
  35. this.thresholds.computeIfAbsent(th.groupId(), k -> new ArrayList<>()).add(th);
  36. }
  37. }
  38. public Predicate<DS> check() {
  39. return this::validateThreshold;
  40. }
  41. private boolean validateThreshold(DS data) {
  42. long sourceId = data.datasourceId();
  43. OffsetDateTime timestamp = data.timestamp();
  44. if (!thresholds.containsKey(sourceId)) {
  45. return true;
  46. }
  47. boolean process = true;
  48. List<Threshold> rules = thresholds.get(sourceId);
  49. NotifyTrigger notifier = notifyTriggerMap.get(sourceId);
  50. for (Threshold th : rules) {
  51. ValidationResult res = validator.validate(data, th);
  52. notifier.accept(res);
  53. if (res.isNotValid() && !th.allowProcess()) {
  54. process = false;
  55. }
  56. }
  57. if (notifier.shouldNotify()) {
  58. ifViolated.accept(new ViolationReport(sourceId, timestamp, notifier.resultsToNotify()));
  59. }
  60. return process;
  61. }
  62. }