package org.fenixedu.bennu.core.rest; import java.io.PrintWriter; import java.io.StringWriter; import com.google.gson.JsonObject; /** * An {@link Healthcheck} provides information about the health of a system depended on by the application (typically an external * system). * * This class was greatly inspired by <a href="http://metrics.codahale.com">Metrics</a>. * * @author João Carvalho (joao.pedro.carvalho@tecnico.ulisboa.pt) * */ public abstract class Healthcheck { /** * The result of a {@link Healthcheck}. It can be healthy or unhealthy (with either an error message or a thrown exception). */ public static class Result { /** * Returns a healthy {@link Result}. * * @return {@link Result} instance with "OK" message */ public static Result healthy() { return new Result(true, "OK", null); } /** * Returns a healthy {@link Result} with the given message. * * @param message the message to include in the result * @return {@link Result} instance */ public static Result healthy(String message) { return new Result(true, message, null); } /** * Returns an unhealthy {@link Result} with the given message. * * @param message the message to include in the result * @return {@link Result} instance */ public static Result unhealthy(String message) { return new Result(false, message, null); } /** * Returns an unhealthy {@link Result} with the given error. * * @param error an exception to include in the result * @return {@link Result} instance */ public static Result unhealthy(Throwable error) { return new Result(false, error.getMessage(), error); } /** * Returns an unhealthy {@link Result} with the given error and message. * * @param message the message to include in the result * @param error an exception to include in the result * * @return {@link Result} instance */ public static Result unhealthy(String message, Throwable error) { return new Result(false, message, error); } private final boolean healthy; private final String message; private final Throwable error; private Result(boolean isHealthy, String message, Throwable error) { this.healthy = isHealthy; this.message = message; this.error = error; } public JsonObject toJson() { JsonObject json = new JsonObject(); json.addProperty("healthy", healthy); json.addProperty("message", message); if (error != null) { StringWriter writer = new StringWriter(); error.printStackTrace(new PrintWriter(writer)); json.addProperty("error", writer.toString()); } return json; } } /** * Returns the presentation name of this healthcheck. * * @return the name {@link String} */ public abstract String getName(); /** * Perform a check of the application component. * * @return if the component is healthy, a healthy {@link Result}; otherwise, an unhealthy {@link Result} with a descriptive * error message or exception * @throws Exception if there is an unhandled error during the health check; this will result in a failed health check */ protected abstract Result check() throws Exception; /** * Executes the health check. Any exceptions will result in an Unhealthy Result. * * @return {@link Result} instance */ public final Result execute() { try { return check(); } catch (Exception e) { return Result.unhealthy(e); } } }