package com.intrbiz.bergamot.model; import java.io.Serializable; import java.sql.Timestamp; import java.time.Clock; import java.time.LocalDateTime; import java.util.Calendar; import java.util.EnumSet; import java.util.List; import java.util.UUID; import java.util.stream.Collectors; import com.intrbiz.bergamot.data.BergamotDB; import com.intrbiz.bergamot.model.message.DowntimeMO; import com.intrbiz.bergamot.model.timeperiod.TimeRange; 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; /** * Operational Downtime against a check, which is transiently added for * operational purposes. * * During downtime a check is suppressed, it will execute, the status will update * however notifications will not be sent and the state will not affect any * dependencies. */ @SQLTable(schema = BergamotDB.class, name = "downtime", since = @SQLVersion({ 1, 0, 0 })) public class Downtime extends BergamotObject<DowntimeMO> implements Serializable, TimeRange, Commented { private static final long serialVersionUID = 1L; /** * The unique ID for this downtime */ @SQLColumn(index = 1, name = "id", since = @SQLVersion({ 1, 0, 0 })) @SQLPrimaryKey() private UUID id; /** * The site id */ @SQLColumn(index = 2, name = "site_id", notNull = true, since = @SQLVersion({ 1, 0, 0 })) @SQLForeignKey(references = Site.class, on = "id", onDelete = Action.CASCADE, onUpdate = Action.RESTRICT, since = @SQLVersion({ 1, 0, 0 })) private UUID siteId; /** * The check to which this downtime applies */ @SQLColumn(index = 3, name = "check_id", since = @SQLVersion({ 1, 0, 0 })) private UUID checkId; /** * The summary of this downtime */ @SQLColumn(index = 4, name = "summary", notNull = true, since = @SQLVersion({ 1, 0, 0 })) protected String summary; /** * The description of this downtime */ @SQLColumn(index = 5, name = "description", since = @SQLVersion({ 1, 0, 0 })) protected String description; /** * When this downtime was added */ @SQLColumn(index = 6, name = "created", since = @SQLVersion({ 1, 0, 0 })) protected Timestamp created = new Timestamp(System.currentTimeMillis()); /** * When this downtime was last modified */ @SQLColumn(index = 7, name = "updated", since = @SQLVersion({ 1, 0, 0 })) protected Timestamp updated = new Timestamp(System.currentTimeMillis()); /** * Whom created this downtime */ @SQLColumn(index = 8, name = "created_by_id", since = @SQLVersion({ 1, 0, 0 })) @SQLForeignKey(references = Contact.class, on = "id", onDelete = Action.SET_NULL, onUpdate = Action.SET_NULL, since = @SQLVersion({ 1, 0, 0 })) protected UUID createdById; /** * When does this downtime start (in UTC) */ @SQLColumn(index = 9, name = "starts", since = @SQLVersion({ 1, 0, 0 })) protected Timestamp starts; /** * When does this downtime end (in UTC) */ @SQLColumn(index = 10, name = "ends", since = @SQLVersion({ 1, 0, 0 })) protected Timestamp ends; public Downtime() { super(); } public UUID getSiteId() { return siteId; } public void setSiteId(UUID siteId) { this.siteId = siteId; } public UUID getId() { return id; } public void setId(UUID id) { this.id = id; } public UUID getCheckId() { return checkId; } public void setCheckId(UUID checkId) { this.checkId = checkId; } public String getSummary() { return summary; } public void setSummary(String summary) { this.summary = summary; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public Timestamp getCreated() { return created; } public void setCreated(Timestamp created) { this.created = created; } public Timestamp getUpdated() { return updated; } public void setUpdated(Timestamp updated) { this.updated = updated; } public UUID getCreatedById() { return createdById; } public void setCreatedById(UUID createdById) { this.createdById = createdById; } public Timestamp getStarts() { return starts; } public void setStarts(Timestamp starts) { this.starts = starts; } public Timestamp getEnds() { return ends; } public void setEnds(Timestamp ends) { this.ends = ends; } @Override public boolean isInTimeRange(Calendar calendar) { return calendar.getTimeInMillis() >= this.getStarts().getTime() && calendar.getTimeInMillis() <= this.getEnds().getTime(); } @Override public LocalDateTime computeNextStartTime(Clock clock) { return null; } /** * Get comments against this downtime * @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 downtime */ @Override public List<Comment> getComments() { return this.getComments(5); } public Check<?,?> getCheck() { try (BergamotDB db = BergamotDB.connect()) { return db.getCheck(this.getCheckId()); } } public Contact getCreatedBy() { try (BergamotDB db = BergamotDB.connect()) { return db.getContact(this.getCreatedById()); } } public String toString() { return "Downtime { check => " + this.getCheckId() + ", starts => " + this.getStarts() + ", ends => " + this.getEnds() + ", summary => " + this.getSummary() + " }"; } @Override public DowntimeMO toMO(Contact contact, EnumSet<MOFlag> options) { DowntimeMO mo = new DowntimeMO(); mo.setCheck(this.getCheck().toStubMO(contact)); mo.setComments(this.getComments().stream().map((x) -> x.toMO(contact)).collect(Collectors.toList())); mo.setCreated(this.getCreated().getTime()); Contact createdBy = this.getCreatedBy(); if (createdBy != null) { if (contact == null || contact.hasPermission("read", createdBy)) mo.setCreatedBy(createdBy.toStubMO(contact)); } mo.setDescription(this.getDescription()); mo.setEnds(this.getEnds().getTime()); mo.setId(this.getId()); mo.setStarts(this.getStarts().getTime()); mo.setSummary(this.getSummary()); mo.setUpdated(this.getUpdated() == null ? -1 : this.getUpdated().getTime()); return mo; } // helpers public Downtime on(Check<?,?> check) { this.setCheckId(check.getId()); this.setSiteId(check.getSiteId()); this.setId(Site.randomId(this.getSiteId())); this.setCreated(new Timestamp(System.currentTimeMillis())); this.setUpdated(this.getCreated()); return this; } public Downtime createdBy(Contact createdBy) { this.setCreatedById(createdBy.getId()); return this; } public Downtime between(Timestamp starts, Timestamp ends) { this.setStarts(starts); this.setEnds(ends); return this; } public Downtime summary(String summary) { this.setSummary(summary); return this; } public Downtime description(String description) { this.setDescription(description); return this; } }