package com.intrbiz.bergamot.model; import java.util.EnumSet; import java.util.LinkedList; import java.util.List; import java.util.UUID; import java.util.stream.Collectors; import com.intrbiz.Util; import com.intrbiz.bergamot.config.model.RealCheckCfg; import com.intrbiz.bergamot.data.BergamotDB; import com.intrbiz.bergamot.model.message.CheckMO; import com.intrbiz.bergamot.model.message.RealCheckMO; import com.intrbiz.bergamot.model.state.CheckState; import com.intrbiz.bergamot.model.state.CheckStats; import com.intrbiz.data.db.compiler.meta.SQLColumn; import com.intrbiz.data.db.compiler.meta.SQLVersion; /** * A 'real' check has to know about hard vs soft states */ public abstract class RealCheck<T extends RealCheckMO, C extends RealCheckCfg<C>> extends Check<T, C> { private static final long serialVersionUID = 1L; /** * How many check attempts to trigger a hard alert */ @SQLColumn(index = 1, name = "alert_attempt_threshold", since = @SQLVersion({ 1, 0, 0 })) protected int alertAttemptThreshold = 3; /** * How many check attempts to trigger a hard recovery */ @SQLColumn(index = 2, name = "recovery_attempt_threshold", since = @SQLVersion({ 1, 0, 0 })) protected int recoveryAttemptThreshold = 3; /** * Checks which this check depends upon for reachability */ @SQLColumn(index = 10, name = "depends", type = "UUID[]", since = @SQLVersion({ 3, 21, 0 })) protected List<UUID> dependsIds = new LinkedList<UUID>(); public RealCheck() { super(); } public int getAlertAttemptThreshold() { return alertAttemptThreshold; } public void setAlertAttemptThreshold(int alertAttemptThreshold) { this.alertAttemptThreshold = alertAttemptThreshold; } public int getRecoveryAttemptThreshold() { return recoveryAttemptThreshold; } public void setRecoveryAttemptThreshold(int recoveryAttemptThreshold) { this.recoveryAttemptThreshold = recoveryAttemptThreshold; } public int getCurrentAttemptThreshold() { return this.computeCurrentAttemptThreshold(this.getState()); } public int computeCurrentAttemptThreshold(CheckState currentState) { return currentState.isOk() ? this.getRecoveryAttemptThreshold() : this.getAlertAttemptThreshold(); } public List<UUID> getDependsIds() { return dependsIds; } public void setDependsIds(List<UUID> dependsIds) { this.dependsIds = dependsIds; } public boolean hasDependencies() { return ! (this.dependsIds == null || this.dependsIds.isEmpty()); } public List<Check<?,?>> getDepends() { List<Check<?,?>> depends = new LinkedList<Check<?,?>>(); if (this.getDependsIds() != null && (! this.getDependsIds().isEmpty())) { try (BergamotDB db = BergamotDB.connect()) { this.dependsIds.stream().map((id) -> db.getCheck(id)).filter((c) -> c != null).forEach(depends::add); } } return depends; } public CheckCommand getCheckCommand() { try (BergamotDB db = BergamotDB.connect()) { return db.getCheckCommand(this.getId()); } } public CheckStats getStats() { try (BergamotDB db = BergamotDB.connect()) { return db.getCheckStats(this.getId()); } } protected void toMO(RealCheckMO mo, Contact contact, EnumSet<MOFlag> options) { super.toMO(mo, contact, options); mo.setAlertAttemptThreshold(this.getAlertAttemptThreshold()); mo.setRecoveryAttemptThreshold(this.getRecoveryAttemptThreshold()); mo.setCurrentAttemptThreshold(this.getCurrentAttemptThreshold()); if (options.contains(MOFlag.STATS)) mo.setStats(this.getStats().toMO(contact)); if (options.contains(MOFlag.COMMAND)) mo.setCheckCommand(Util.nullable(this.getCheckCommand(), (x) -> x.toStubMO(contact))); if (options.contains(MOFlag.DEPENDS)) mo.setDepends(this.getDepends().stream().map((c) -> (CheckMO) c.toStubMO(contact)).collect(Collectors.toList())); } @Override public void configure(C configuration, C resolvedConfiguration) { super.configure(configuration, resolvedConfiguration); // configure state thresholds if (resolvedConfiguration.getState() != null) { this.alertAttemptThreshold = resolvedConfiguration.getState().getFailedAfter(); this.recoveryAttemptThreshold = resolvedConfiguration.getState().getRecoversAfter(); } } }