-
Notifications
You must be signed in to change notification settings - Fork 3k
Add MicroProfile Health guide #1483
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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` | ||
|
||
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> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
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