= Vert.x Health Checks

This component provides a simple way to compute health checks.
Health checks are used to express the current state of the application in very simple terms: _UP_ or _DOWN_.

== Using Vert.x Health Checks

Add the following dependency:

* Maven (in your `pom.xml`):

[source,xml,subs="+attributes"]
----
<dependency>
  <groupId>io.vertx</groupId>
  <artifactId>vertx-health-check</artifactId>
  <version>5.0.0.CR3</version>
</dependency>
----

* Gradle (in your `build.gradle` file):

[source,groovy,subs="+attributes"]
----
compile 'io.vertx:vertx-health-check:5.0.0.CR3'
----

=== Creating the health check object.

The central object is `link:../../apidocs/io/vertx/ext/healthchecks/HealthChecks.html[HealthChecks]`.
You can create a new instance using:

[source,java]
----
HealthChecks hc = HealthChecks.create(vertx);

hc.register(
  "my-procedure",
  promise -> promise.complete(Status.OK()));

// Register with a timeout. The check fails if it does not complete in time.
// The timeout is given in ms.
hc.register(
  "my-procedure",
  2000,
  promise -> promise.complete(Status.OK()));
----

Once you have created this object you can register and unregister procedures.

== Procedures

A procedure is a function checking some aspect of the system to deduce the current health.
It reports a `link:../../apidocs/io/vertx/ext/healthchecks/Status.html[Status]` indicating whether the test has passed or failed.
This function must not block and report to the given `link:../../apidocs/io/vertx/core/Promise.html[Promise]` whether it succeeded or failed.

When you register a procedure, you give a name and the function (handler) executing the check.

Rules deducing the status are the following:

* if the promise is marked as failed, the check is considered as _KO_
* if the promise is completed successfully but without a `link:../../apidocs/io/vertx/ext/healthchecks/Status.html[Status]`, the check is considered as _OK_.
* if the promise is completed successfully with a `link:../../apidocs/io/vertx/ext/healthchecks/Status.html[Status]` marked as _OK_, the check is considered as _OK_.
* if the promise is completed successfully with a `link:../../apidocs/io/vertx/ext/healthchecks/Status.html[Status]` marked as _KO_, the check is considered as _KO_.

`link:../../apidocs/io/vertx/ext/healthchecks/Status.html[Status]` can also provide additional data:

[source,java]
----
healthChecks.register("my-procedure-name", promise -> {
  // Status can provide additional data provided as JSON
  promise.complete(Status.OK(new JsonObject().put("available-memory", "2mb")));
});

healthChecks.register("my-second-procedure-name", promise -> {
  promise.complete(Status.KO(new JsonObject().put("load", 99)));
});
----

Procedures can be organised in groups.
The procedure name indicates the group (separated by `/`).
The procedures are organised as a tree.

[source,java]
----
healthChecks.register("a-group/my-procedure-name", promise -> {
  //....
});
// Groups can contain other groups
healthChecks.register("a-group/a-second-group/my-second-procedure-name", promise -> {
  //....
});
----

== Examples of procedures

This section provides example of common health checks.

=== SQL client

This check reports whether a connection to the database can be established:

[source,java]
----
healthChecks.register("database", promise ->
  pool.getConnection()
    .compose(SqlConnection::close)
    .<Status>mapEmpty()
    .onComplete(promise)
);
----

=== Event bus

This check reports whether a consumer is ready on the event bus.
The protocol, in this example, is a simple ping/pong, but it can be more sophisticated.
This check can be used to check whether a verticle is ready if it's listening on a specific event address.

[source,java]
----
healthChecks.register("receiver", promise ->
  vertx.eventBus().request("health", "ping")
    .onSuccess(msg -> {
      promise.complete(Status.OK());
    })
    .onFailure(err -> {
      promise.complete(Status.KO());
    })
);
----

== Exposing health checks on the event bus

While exposing the health checks using HTTP with the Vert.x web handler is convenient, it can be useful to expose the data differently.
This section gives an example to expose the data on the event bus:

[source,java]
----
vertx.eventBus().consumer("health", message ->
  healthChecks.checkStatus()
    .onSuccess(message::reply)
    .onFailure(err -> message.fail(0, err.getMessage()))
);
----