package com.intrbiz.bergamot.model; import java.util.Calendar; import java.util.Collections; import java.util.EnumSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; import com.intrbiz.bergamot.data.BergamotDB; import com.intrbiz.bergamot.model.adapter.StatusesAdapter; import com.intrbiz.bergamot.model.message.NotificationsMO; import com.intrbiz.data.db.compiler.meta.Action; import com.intrbiz.data.db.compiler.meta.SQLColumn; import com.intrbiz.data.db.compiler.meta.SQLForeignKey; import com.intrbiz.data.db.compiler.meta.SQLPrimaryKey; import com.intrbiz.data.db.compiler.meta.SQLTable; import com.intrbiz.data.db.compiler.meta.SQLVersion; @SQLTable(schema = BergamotDB.class, name = "notifications", since = @SQLVersion({ 1, 0, 0 })) public class Notifications extends BergamotObject<NotificationsMO> { private static final long serialVersionUID = 1L; @SQLColumn(index = 1, name = "id", since = @SQLVersion({ 1, 0, 0 })) @SQLPrimaryKey private UUID id; @SQLColumn(index = 2, name = "enabled", since = @SQLVersion({ 1, 0, 0 })) private boolean enabled = true; @SQLColumn(index = 3, name = "timeperiod_id", since = @SQLVersion({ 1, 0, 0 })) @SQLForeignKey(references = TimePeriod.class, on = "id", onDelete = Action.RESTRICT, onUpdate = Action.RESTRICT, since = @SQLVersion({ 1, 0, 0 })) private UUID timePeriodId; @SQLColumn(index = 4, name = "alerts_enabled", since = @SQLVersion({ 1, 0, 0 })) private boolean alertsEnabled = true; @SQLColumn(index = 5, name = "recovery_enabled", since = @SQLVersion({ 1, 0, 0 })) private boolean recoveryEnabled = true; @SQLColumn(index = 6, name = "ignore", type = "TEXT[]", adapter = StatusesAdapter.class, since = @SQLVersion({ 1, 0, 0 })) private List<Status> ignore = new LinkedList<Status>(); @SQLColumn(index = 7, name = "all_engines_enabled", since = @SQLVersion({ 1, 0, 0 })) private boolean allEnginesEnabled = true; @SQLColumn(index = 8, name = "acknowledge_enabled", since = @SQLVersion({ 3, 2, 0 })) private boolean acknowledgeEnabled = true; public Notifications() { super(); } public UUID getId() { return id; } public void setId(UUID id) { this.id = id; } public List<NotificationEngine> getEngines() { try (BergamotDB db = BergamotDB.connect()) { return db.getNotificationEngines(this.getId()); } } public void addEngine(NotificationEngine engine) { try (BergamotDB db = BergamotDB.connect()) { engine.setNotificationsId(this.getId()); db.setNotificationEngine(engine); } } public boolean isEnabled() { return enabled; } public void setEnabled(boolean enabled) { this.enabled = enabled; } public TimePeriod getTimePeriod() { if (this.getTimePeriodId() == null) return null; try (BergamotDB db = BergamotDB.connect()) { return db.getTimePeriod(this.getTimePeriodId()); } } public UUID getTimePeriodId() { return timePeriodId; } public void setTimePeriodId(UUID timePeriodId) { this.timePeriodId = timePeriodId; } public boolean isAlertsEnabled() { return alertsEnabled; } public void setAlertsEnabled(boolean alertsEnabled) { this.alertsEnabled = alertsEnabled; } public boolean isRecoveryEnabled() { return recoveryEnabled; } public void setRecoveryEnabled(boolean recoveryEnabled) { this.recoveryEnabled = recoveryEnabled; } public boolean isAcknowledgeEnabled() { return acknowledgeEnabled; } public void setAcknowledgeEnabled(boolean acknowledgeEnabled) { this.acknowledgeEnabled = acknowledgeEnabled; } public List<Status> getIgnore() { return ignore; } public void setIgnore(List<Status> ignore) { this.ignore = ignore; } public boolean isAllEnginesEnabled() { return allEnginesEnabled; } public void setAllEnginesEnabled(boolean allEnginesEnabled) { this.allEnginesEnabled = allEnginesEnabled; } /** * Are notifications enabled for the given notification type, the given check statue and a point in time * @param type the notification type * @param status the status of the check * @param time the time * @return true if notifications are enabled */ public boolean isEnabledAt(NotificationType type, Status status, Calendar time) { TimePeriod timePeriod = this.getTimePeriod(); return this.enabled && this.isNotificationTypeEnabled(type) && (!this.isStatusIgnored(status)) && (timePeriod == null ? true : timePeriod.isInTimeRange(time)) && (this.allEnginesEnabled || this.getEngines().stream().anyMatch((e) -> e.isEnabledAt(type, status, time))); } public boolean isStatusIgnored(Status status) { return this.ignore.stream().anyMatch((e) -> e == status); } public boolean isNotificationTypeEnabled(NotificationType type) { return (type == NotificationType.ALERT && this.alertsEnabled) || (type == NotificationType.RECOVERY && this.recoveryEnabled) || (type == NotificationType.ACKNOWLEDGE && this.acknowledgeEnabled); } public Set<String> getEnginesEnabledAt(NotificationType type, Status status, Calendar time) { return this.getEngines().stream() .filter((e) -> e.isEnabledAt(type, status, time)) .map(NotificationEngine::getEngine) .collect(Collectors.toSet()); } public boolean isEngineEnabledAt(NotificationType type, Status status, Calendar time, String engine) { return this.getEngines().stream() .filter((e) -> engine.equals(e.getEngine())) .anyMatch((e) -> e.isEnabledAt(type, status, time)); } public List<Escalation> getEscalations() { try (BergamotDB db = BergamotDB.connect()) { return db.getEscalations(this.getId()); } } public Escalation evalEscalations(long alertDuration, Status status, Calendar time) { // process the escalations in descending order List<Escalation> escalations = this.getEscalations(); Collections.sort(escalations); for (Escalation escalation : escalations) { if (alertDuration > escalation.getAfter() && escalation.isActiveFor(status, time)) return escalation; } return null; } public void evalEscalations(long alertDuration, Status status, Calendar time, List<Escalation> escalations) { Escalation escalation = this.evalEscalations(alertDuration, status, time); if (escalation != null) escalations.add(escalation); } @Override public NotificationsMO toMO(Contact contact, EnumSet<MOFlag> options) { NotificationsMO mo = new NotificationsMO(); mo.setEnabled(this.isEnabled()); mo.setAlertsEnabled(this.isAlertsEnabled()); mo.setAllEnginesEnabled(this.isAllEnginesEnabled()); mo.setIgnore(this.getIgnore().stream().map(Status::toString).collect(Collectors.toSet())); mo.setRecoveryEnabled(this.isRecoveryEnabled()); mo.setAcknowledgeEnabled(this.isAcknowledgeEnabled()); TimePeriod timePeriod = this.getTimePeriod(); if (timePeriod != null) { if (contact == null || contact.hasPermission("read", timePeriod)) mo.setTimePeriod(timePeriod.toStubMO(contact)); } mo.setEngines(this.getEngines().stream().map((x) -> x.toStubMO(contact)).collect(Collectors.toList())); mo.setEscalations(this.getEscalations().stream().map((e) -> e.toStubMO(contact)).collect(Collectors.toList())); return mo; } }