Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
227 changes: 227 additions & 0 deletions docs/src/main/asciidoc/health-guide.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
include::./attributes.adoc[]
= {project-name} - MicroProfile Health

This guide demonstrates how your {project-name} application can utilize the MicroProfile
Health specification through the SmallRye Health extension.

MicroProfile Health allows applications to provide information about their state
to external viewers which is typically useful in cloud environments where automated
processes must be able to determine whether the application should be discarded
or restarted.

== Prerequisites

To complete this guide, you need:

* less than 15 minutes
* an IDE
* JDK 1.8+ installed with `JAVA_HOME` configured appropriately
* Apache Maven 3.5.3+

== Architecture

In this guide, we build a simple REST application that exposes MicroProfile Health functionalities at
the `/health` endpoint according to the specification. It will also provide several other REST
endpoints to allow us to dynamically change the healthness of our {project-name} application.

== Solution

We recommend that you follow the instructions in the next sections and create the application step by step.
However, you can go right to the completed example.

Clone the Git repository: `git clone {quickstarts-clone-url}`, or download an {quickstarts-archive-url}[archive].

The solution is located in the `microprofile-health` {quickstarts-tree-url}/microprofile-health[directory].

== Creating the Maven Project

First, we need a new project. Create a new project with the following command:

[source, subs=attributes+]
----
mvn io.quarkus:quarkus-maven-plugin:0.11.0:create \
-DprojectGroupId=org.acme \
-DprojectArtifactId=microprofile-health \
-Dextensions="smallrye-health"
----

This command generates a Maven project, importing the `smallrye-health` extension
which is an implementation of the MicroProfile Health specification used in {project-name}.

== Running the health check

Importing the `smallrye-health` extension directly exposes a single REST endpoint at
the `/health` endpoint that can be used to run the health check procedures:

* start your {project-name} application with `mvn compile quarkus:dev`
* access the `http://localhost:8080/health` endpoint using your browser or
`curl http://localhost:8080/health`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
`curl http://localhost:8080/health`
`curl http://localhost:8080/health`.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gsmet both bullets should be same so I will skip this comment


The health REST enpoint returns a simple JSON object with two fields:

* `outcome` -- the overall result of all the health check procedures
* `checks` -- an array of individual checks

The general `outcome` of the health check is computed as a logical AND of all the declared
health check procedures. The `checks` array is empty as we have not specified any health
check procedure yet so let's define some.

== Creating your first health check

In this section we create our first simple health check procedure.

Create the `org.acme.health.SimpleHealthCheck` class:

[source,java]
----
package org.acme.health;

import org.eclipse.microprofile.health.Health;
import org.eclipse.microprofile.health.HealthCheck;
import org.eclipse.microprofile.health.HealthCheckResponse;

import javax.enterprise.context.ApplicationScoped;

@Health
@ApplicationScoped
public class SimpleHealthCheck implements HealthCheck {

@Override
public HealthCheckResponse call() {
return HealthCheckResponse.named("Simple health check").up().build();
}
}
----

As you can see health check procedures are defined as implementations of the `HealthCheck`
interface which are defined as CDI beans with the `@Health` qualifier. `HealthCheck` is
a functional interface whose single method `call` returns a `HealthCheckResponse` object
which can be easily constructed by the fluent builder API shown in the example.

As we have started our {project-name} application in dev mode simply repeat the request
to `http://localhost:8080/health` by refreshing your browser window or by using `curl http://localhost:8080/health`.
The new health check procedure is now present in the `checks` array.

Congratulations! You've created your first {project-name} health check procedure. Let's
continue by exploring what else can be done with the MicroProfile Health specification.

== Adding user specific data to the health check response

In previous section we saw how to create a simple health check with only the minimal
attributes, namely, the health check name and its state (UP or DOWN). However, the
MicroProfile specification also provides a way for the applications to supply
arbitrary data in the form of key value pairs sent to the consuming end. This can be done by using the
`withData(key, value)` method of the health check response builder API.

Let's create our second health check procedure `org.acme.health.DataHealthCheck`:

[source,java]
----
package org.acme.health;

import org.eclipse.microprofile.health.Health;
import org.eclipse.microprofile.health.HealthCheck;
import org.eclipse.microprofile.health.HealthCheckResponse;

import javax.enterprise.context.ApplicationScoped;

@Health
@ApplicationScoped
public class DataHealthCheck implements HealthCheck {

@Override
public HealthCheckResponse call() {
return HealthCheckResponse.named("Health check with data")
.up()
.withData("foo", "fooValue")
.withData("bar", "barValue")
.build();
}
}
----

If you rerun the health check procedure again by accessing the `/health` endpoint you can
see that the new health check `Health check with data` is present in the `checks` array.
This check contains a new attribute called `data` which is a JSON object consisting of
the properties we have defined in our health check procedure.

== Negative health check procedure

In this section we create another health check procedure which simulates a connection to
an external service provider such as a database. For simplicity reasons, we only determine
whether the database is accessible or not by a configuration property.

Create `org.acme.health.DatabaseConnectionHealthCheck` class:

[source,java]
----
package org.acme.health;

import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.eclipse.microprofile.health.Health;
import org.eclipse.microprofile.health.HealthCheck;
import org.eclipse.microprofile.health.HealthCheckResponse;
import org.eclipse.microprofile.health.HealthCheckResponseBuilder;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;

@Health
@ApplicationScoped
public class DatabaseConnectionHealthCheck implements HealthCheck {

@Inject
@ConfigProperty(name = "database.up", defaultValue = "false")
private boolean databaseUp;

@Override
public HealthCheckResponse call() {

HealthCheckResponseBuilder responseBuilder = HealthCheckResponse.named("Database connection health check");

try {
simulateDatabaseConnectionVerification();
responseBuilder.up();
} catch (IllegalStateException e) {
// cannot access the database
responseBuilder.down()
.withData("error", e.getMessage());
}

return responseBuilder.build();
}

private void simulateDatabaseConnectionVerification() {
if (!databaseUp) {
throw new IllegalStateException("Cannot contact database");
}
}
}
----

If you now rerun the health check the overall `outcome` should be DOWN and you should
see in the `checks` array the newly added `Database connection health check` which is
down and the error message explaining why it failed.

As we shouldn't leave this application with a health check in DOWN state and because we
are running {project-name} dev mode you can add `database.up=true` in
`src/main/resources/application.properties` and rerun the health check again --
it should be up again.

== Conclusion

MicroProfile Health provides a way for your application to distribute information
about its healthness state to state whether or not it is able to function properly.

All that is needed to enable the MicroProfile Health features in {project-name} is:

* adding the `smallrye-health` {project-name} extension to your project using the `quarkus-maven-plugin`:

mvn quarkus:add-extension -Dextensions="smallrye-health"

* or simply adding the following Maven dependency:

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-health</artifactId>
</dependency>
1 change: 1 addition & 0 deletions docs/src/main/asciidoc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ include::quarkus-intro.adoc[tag=intro]
* link:infinispan-client-guide.html[Using Infinispan Client]
* link:spring-di-guide.html[Using our Spring Dependency Injection compatibility layer]
* link:kotlin.html[Using Kotlin]
* link:health-guide.html[Using MicroProfile Health]
* link:fault-tolerance-guide.html[Using Fault Tolerance]
* link:extension-authors-guide.html[Write Your Own Extension] _(advanced)_
* link:performance-measure.html[Measuring Performance] _(advanced)_
Expand Down