package com.intrbiz.bergamot.model; import java.util.Calendar; import java.util.EnumSet; import java.util.HashSet; 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.config.model.CheckCfg; import com.intrbiz.bergamot.data.BergamotDB; import com.intrbiz.bergamot.model.message.CheckMO; import com.intrbiz.bergamot.model.message.ContactMO; import com.intrbiz.bergamot.model.message.VirtualCheckMO; import com.intrbiz.bergamot.model.state.CheckState; import com.intrbiz.data.db.compiler.meta.SQLColumn; import com.intrbiz.data.db.compiler.meta.SQLVersion; /** * An something which should be checked */ public abstract class Check<T extends CheckMO, C extends CheckCfg<C>> extends SecuredObject<T, C> implements Commented { private static final long serialVersionUID = 1L; /** * Is the result of this check suppressed */ @SQLColumn(index = 2, name = "suppressed", since = @SQLVersion({ 1, 0, 0 })) protected boolean suppressed = false; /** * Is this check currently scheduled */ @SQLColumn(index = 3, name = "enabled", since = @SQLVersion({ 1, 0, 0 })) protected boolean enabled = true; /** * Teams to notify */ @SQLColumn(index = 4, name = "team_ids", type = "UUID[]", since = @SQLVersion({ 1, 0, 0 })) protected List<UUID> teamIds = new LinkedList<UUID>(); /** * Contacts to notify */ @SQLColumn(index = 5, name = "contact_ids", type = "UUID[]", since = @SQLVersion({ 1, 0, 0 })) protected List<UUID> contactIds = new LinkedList<UUID>(); /** * The groups this check is a member of */ @SQLColumn(index = 7, name = "group_ids", type = "UUID[]", since = @SQLVersion({ 1, 0, 0 })) protected List<UUID> groupIds = new LinkedList<UUID>(); /** * The processing pool to which this check is assigned */ @SQLColumn(index = 8, name = "pool", notNull = true, since = @SQLVersion({ 1, 0, 0 })) protected int pool = 0; @SQLColumn(index = 9, name = "external_ref", since = @SQLVersion({ 2, 1, 0 })) protected String externalRef; public Check() { super(); } public abstract String getType(); public boolean isSuppressed() { return suppressed; } public void setSuppressed(boolean suppressed) { this.suppressed = suppressed; } public boolean isEnabled() { return enabled; } public void setEnabled(boolean enabled) { this.enabled = enabled; } public List<VirtualCheck<?, ?>> getReferencedBy() { try (BergamotDB db = BergamotDB.connect()) { return db.getVirtualChecksReferencingCheck(this.getId()); } } public CheckState getState() { try (BergamotDB db = BergamotDB.connect()) { return db.getCheckState(this.getId()); } } public Set<Contact> getAllContacts() { Set<Contact> ret = new HashSet<Contact>(); ret.addAll(this.getContacts()); for (Team team : this.getTeams()) { ret.addAll(team.getAllContacts()); } return ret; } public List<UUID> getContactIds() { return contactIds; } public void setContactIds(List<UUID> contactIds) { this.contactIds = contactIds; } public List<Contact> getContacts() { List<Contact> r = new LinkedList<Contact>(); if (this.getContactIds() != null) { try (BergamotDB db = BergamotDB.connect()) { for (UUID id : this.getContactIds()) { r.add(db.getContact(id)); } } } return r; } public void addContact(Contact contact) { try (BergamotDB db = BergamotDB.connect()) { db.addContactToCheck(this, contact); } } public void removeContact(Contact contact) { try (BergamotDB db = BergamotDB.connect()) { db.removeContactFromCheck(this, contact); } } public List<UUID> getTeamIds() { return teamIds; } public void setTeamIds(List<UUID> teamIds) { this.teamIds = teamIds; } public List<Team> getTeams() { List<Team> r = new LinkedList<Team>(); if (this.getTeamIds() != null) { try (BergamotDB db = BergamotDB.connect()) { for (UUID id : this.getTeamIds()) { r.add(db.getTeam(id)); } } } return r; } public void addTeam(Team team) { try (BergamotDB db = BergamotDB.connect()) { db.addTeamToCheck(this, team); } } public void removeTeam(Team team) { try (BergamotDB db = BergamotDB.connect()) { db.removeTeamFromCheck(this, team); } } public Notifications getNotifications() { try (BergamotDB db = BergamotDB.connect()) { return db.getNotifications(this.getId()); } } public void setNotifications(Notifications notifications) { try (BergamotDB db = BergamotDB.connect()) { notifications.setId(this.getId()); db.setNotifications(notifications); } } public List<UUID> getGroupIds() { return groupIds; } public void setGroupIds(List<UUID> groupIds) { this.groupIds = groupIds; } public List<Group> getGroups() { List<Group> r = new LinkedList<Group>(); if (this.getGroupIds() != null) { try (BergamotDB db = BergamotDB.connect()) { for (UUID id : this.getGroupIds()) { r.add(db.getGroup(id)); } } } return r; } public void removeGroup(Group group) { try (BergamotDB db = BergamotDB.connect()) { db.removeCheckFromGroup(group, this); } } public void addGroup(Group group) { try (BergamotDB db = BergamotDB.connect()) { db.addCheckToGroup(group, this); } } /** * Get the pool to which this check has been assigned * @return */ public int getPool() { return pool; } public void setPool(int pool) { this.pool = pool; } /** * Get the processing pool for this check */ public int computePool() { return this.getSite().computeProcessingPool(this.getId()); } /** * Get the current downtimes for this check */ public List<Downtime> getDowntime() { try (BergamotDB db = BergamotDB.connect()) { return db.getDowntimesForCheck(this.getId()); } } /** * Check if this check is in downtime at the given time */ public boolean isInDowntime(Calendar now) { for (Downtime downtime : this.getDowntime()) { if (downtime.isInTimeRange(now)) return true; } return false; } /** * Check if this check is currently in downtime */ public boolean isInDowntime() { return this.isInDowntime(Calendar.getInstance()); } /** * Is this check suppressed or in downtime at the given time */ public boolean isSuppressedOrInDowntime(Calendar now) { return this.isSuppressed() || this.isInDowntime(now); } /** * Is this check suppressed or currently in downtime */ public boolean isSuppressedOrInDowntime() { return this.isSuppressed() || this.isInDowntime(); } /** * Get comments against this check * @param limit the maximum number of comments to get */ @Override public List<Comment> getComments(int limit) { try (BergamotDB db = BergamotDB.connect()) { return db.getCommentsForObject(this.getId(), 0, limit); } } /** * Get comments against this check */ @Override public List<Comment> getComments() { return this.getComments(5); } public String getExternalRef() { return externalRef; } public void setExternalRef(String externalRef) { this.externalRef = externalRef; } // some basic actions /** * Suppress this check */ public void suppress() { try (BergamotDB db = BergamotDB.connect()) { this.setSuppressed(true); db.setCheck(this); db.suppressCheck(this.getId(), true); } } /** * Unsuppress this check */ public void unsuppress() { try (BergamotDB db = BergamotDB.connect()) { this.setSuppressed(false); db.setCheck(this); db.suppressCheck(this.getId(), false); } } /** * Enable this check */ public void enable() { try (BergamotDB db = BergamotDB.connect()) { this.setEnabled(true); db.setCheck(this); } } /** * Disable this check */ public void disable() { try (BergamotDB db = BergamotDB.connect()) { this.setEnabled(false); db.setCheck(this); } } /** * Compute the list of contacts who should be notified * @return a list of contact message objects */ public List<ContactMO> getContactsToNotify(NotificationType type, Status status, Calendar time) { final Notifications checkNotifications = this.getNotifications(); // compute the engines available final Set<String> enabledEngines = checkNotifications.getEnginesEnabledAt(type, status, time); // compute the contacts to notify return this.getAllContacts().stream() .filter((c) -> c != null && c.getNotifications() != null) .filter((contact) -> contact.getNotifications().isEnabledAt(type, status, time)) .map((contact) -> { ContactMO cmo = contact.toMOUnsafe(); cmo.setEngines( contact.getNotifications().getEnginesEnabledAt(type, status, time).stream() .filter((engine) -> checkNotifications.isAllEnginesEnabled() || enabledEngines.contains(engine)) .collect(Collectors.toSet()) ); return cmo; }).collect(Collectors.toList()); } public List<ContactMO> getContactsToNotify(NotificationType type) { return this.getContactsToNotify(type, this.getState().getStatus(), Calendar.getInstance()); } // protected void toMO(CheckMO mo, Contact contact, EnumSet<MOFlag> options) { super.toMO(mo, contact, options); mo.setEnabled(this.isEnabled()); mo.setState(this.getState().toMO(contact)); mo.setSuppressed(this.isSuppressed()); mo.setInDowntime(this.isInDowntime()); mo.setPool(this.getPool()); if (options.contains(MOFlag.GROUPS)) mo.setGroups(this.getGroups().stream().filter((x) -> contact == null || contact.hasPermission("read", x)).map((x) -> x.toStubMO(contact)).collect(Collectors.toList())); if (options.contains(MOFlag.CONTACTS)) mo.setContacts(this.getContacts().stream().filter((x) -> contact == null || contact.hasPermission("read", x)).map((x) -> x.toStubMO(contact)).collect(Collectors.toList())); if (options.contains(MOFlag.TEAMS)) mo.setTeams(this.getTeams().stream().filter((x) -> contact == null || contact.hasPermission("read", x)).map((x) -> x.toStubMO(contact)).collect(Collectors.toList())); if (options.contains(MOFlag.REFERENCED_BY)) mo.setReferencedBy(this.getReferencedBy().stream().filter((x) -> contact == null || contact.hasPermission("read", x)).map((v) -> {return (VirtualCheckMO) v.toStubMO(contact);}).collect(Collectors.toList())); if (options.contains(MOFlag.NOTIFICATIONS)) mo.setNotifications(this.getNotifications().toMO(contact)); if (options.contains(MOFlag.DOWNTIME)) mo.setDowntime(this.getDowntime().stream().map((x) -> x.toStubMO(contact)).collect(Collectors.toList())); if (options.contains(MOFlag.COMMENTS)) mo.setComments(this.getComments().stream().map((x) -> x.toStubMO(contact)).collect(Collectors.toList())); } @Override public void configure(C configuration, C resolvedConfiguration) { super.configure(configuration, resolvedConfiguration); // configure basic check state this.enabled = resolvedConfiguration.getEnabledBooleanValue(this.enabled); this.suppressed = resolvedConfiguration.getSuppressedBooleanValue(this.suppressed); this.externalRef = resolvedConfiguration.getExternalRef(); } }