[[MicroProfile_Health_SmallRye]]
= MicroProfile Health Subsystem

ifdef::env-github[]
:tip-caption: :bulb:
:note-caption: :information_source:
:important-caption: :heavy_exclamation_mark:
:caution-caption: :fire:
:warning-caption: :warning:
endif::[]

Support for https://microprofile.io/project/eclipse/microprofile-health[MicroProfile Health] is provided by
 the _microprofile-health-smallrye_ subsystem.

[[required-extension-microprofile-health-smallrye]]
== Required Extension

This extension is included in the standalone-microprofile configurations included in the
WildFly distribution.

You can also add the extension to a configuration without it either by adding
an `<extension module="org.wildfly.extension.microprofile.health-smallrye"/>`
element to the xml or by using the following CLI operation:

[source,options="nowrap"]
----
[standalone@localhost:9990 /]/extension=org.wildfly.extension.microprofile.health-smallrye:add
----

It depends on the base health extension `org.wildfly.extension.health` that must be installed.

== Management Operations

The healthiness of the application server can be queried by calling 3 different operations:

* `check` to check both the liveness and readiness of the runtime
* `check-live` to check only the liveness of the runtime
* `check-ready` to check only the readiness of the runtime
* `check-started` to check only the startup of the runtime


[source,options="nowrap"]
----
[standalone@localhost:9990 /] /subsystem=microprofile-health-smallrye:check
{
    "outcome" => "success", <1>
    "result" => {
        "status" => "UP", <2>
        "checks" => [
            {
                "name" => "server-state",
                "status" => "UP",
                "data" => {"value" => "running"}
            },
            {
                "name" => "empty-startup-checks",
                "status" => "UP"
            },
            {
                "name" => "empty-readiness-checks",
                "status" => "UP"
            },
            {
                "name" => "boot-errors",
                "status" => "UP"
            },
            {
                "name" => "empty-liveness-checks",
                "status" => "UP"
            },
            {
                "name" => "deployments-status",
                "status" => "UP"
            }
        ]
    }
}
----
<1> this `outcome` means that the management operation is successful
<2> this `status` corresponds to the health check, `UP` if the application server is healthy, `DOWN` else.

== HTTP Endpoints

The MicroProfile Health Check specifications defines three HTTP endpoints:

* `/health` to test both the liveness and readiness of the application server.
* `/health/live` to test the liveness of the application server
* `/health/ready` to test the readiness of the application server.
* `/health/started` to test the startup of the application server.

The Health HTTP endpoints are accessible on WildFly HTTP management interface (e.g. http://localhost:9990/health[http://localhost:9990/health]).

If the application server is healthy, it will return a `200 OK` response:

[source,shell]
----
$ curl -v http://localhost:9990/health
< HTTP/1.1 200 OK
...
{"status":"UP","checks":[{"name":"server-state","status":"UP","data":{"value":"running"}},{"name":"empty-startup-checks","status":"UP"},{"name":"empty-readiness-checks","status":"UP"},{"name":"boot-errors","status":"UP"},{"name":"empty-liveness-checks","status":"UP"},{"name":"deployments-status","status":"UP"}]}
----

If the application server is not healthy, it returns `503 Service Unavailable`

[source,shell]
----
$ curl -v http://localhost:9990/health
< HTTP/1.1 503 Service Unavailable
...
{"outcome":"DOWN","checks":[{"name":"myFailingProbe","state":"DOWN","data":{"foo":"bar"}}]}
----

=== Secured Access to the HTTP endpoints

Secured access to the HTTP endpoint is controlled by the `security-enabled` attribute of the `/subsystem=microprofile-health-smallrye` resource.
The value of this attribute will override the `security-enabled` attribute of the `/subsystem=health` resource (documented in <<health-http-endpoint,Health subsystem configuration guide>>).
If it is set to `true`, the HTTP client must be authenticated.

If security has been enabled, the HTTP client must pass the credentials corresponding to a management user
created by the `add-user` script. For example:

[source,shell]
----
$ curl -v --digest -u myadminuser:myadminpassword http://localhost:9990/health
< HTTP/1.1 200 OK
...
{"status":"UP","checks":[{"name":"empty-liveness-checks","status":"UP"},{"name":"server-state","status":"UP","data":{"value":"running"}},{"name":"boot-errors","status":"UP"},{"name":"deployments-status","status":"UP"},{"name":"empty-readiness-checks","status":"UP"}]}
----

If the authentication fails, the  server will reply with a `401 NOT AUTHORIZED` response.

=== Default Server Procedures

WildFly provides some readiness procedures that are checked to determine if the application server is ready to serve requests:

* `boot-errors` checks that there were no errors during the server boot sequence
* `deployments-status` checks that all deployments were deployed without errors
* `server-state` checks that the server state is `running`
* `empty-readiness-checks` determines the status when there are no readiness check procedures deployed to the server. The outcome of this procedure is determined by the `empty-readiness-checks-status` attribute. If the attribute is
   `UP` (by default), the server can be ready when there are no readiness checks in the deployments. Setting the `empty-readiness-checks-status` attribute to `DOWN` will make this procedure fail when there are no readiness checks in the deployments.

If a deployment does not provide any readiness checks, WildFly will automatically add one for each deployment (named `ready-<deployment name>`) which always returns `UP`.

[NOTE]
====
This allows applications that does not provide readiness checks to still be able to inform cloud containers when they are ready to serve requests.
Setting `empty-readiness-checks-status` to `DOWN` ensures that the server will not be ready until the application is deployed. At that time, the `ready-<deployment name>`
will be added (which returns `UP`) and the `empty-readiness-checks` procedure will no longer be checked as there is now a readiness check procedure provided either by the deployment or by the server.
====

WildFly also provide a liveness procedure that is checked to determine if the application server is live:

* `empty-liveness-checks` determines the status when there are no liveness check procedures deployed to the server. The outcome of this procedure is determined by the `empty-liveness-checks-status` attribute. If the attribute is
`UP` (by default), the server can be live when there are no liveness checks in the deployments.  Setting the `empty-liveness-checks-status` attribute to `DOWN` will make this procedure fail when there are no liveness checks in the deployments.

WildFly also provides a similar procedure for what concerns startup checks:

* `empty-startup-checks` determines the status when there are no startup check procedures deployed to the server. The outcome of this procedure is determined by the `empty-startup-checks-status` attribute. If the attribute is
`UP` (by default), the server can be ready when there are no startup checks in the deployments. Setting the `empty-startup-checks-status` attribute to `DOWN` will make this procedure fail when there are no readiness checks in the deployments.

If a deployment does not provide any startup checks, WildFly will automatically add one for each deployment (named `started-<deployment name>`) which always returns `UP`.

[NOTE]
====
This allows applications that do not provide startup checks to still be able to inform cloud containers when they are started to proceed with the container start.
Setting `empty-startup-checks-status` to `DOWN` ensures that the server will not be ready until the application is deployed. At that time, the `started-<deployment name>`
will be added (which returns `UP`) and the `empty-startup-checks` procedure will no longer be checked as there is now a startup check procedure provided either by the deployment or by the server.
====

=== Disabling Default Server Procedures

It is possible to disable the default server procedures by using the MicroProfile Config property `mp.health.disable-default-procedures`.

[NOTE]
====
The MicroProfile Config property `mp.health.disable-default-procedures` is read at 2 different times:

1. __When the server starts__, to determine if the default procedures should be disabled or enabled globally.
It can be set using the system property `mp.health.disable-default-procedures` or the environment variable
`MP_HEALTH_DISABLE_DEFAULT_PROCEDURES`. Setting this property in a deployment is ignored at that time.
2. __When an application is deployed__. At this time, setting this property in a `microprofile-config.properties` file
in the deployment would be taken into account (with the usual priority rules for MicroProfile Config properties),
and with a higher priority than the global server configuration, based on the principle that microservices applications -
and specifically MicroProfile based - usually endorse a single-deployment model.

That being said, the multi-deployment use case is taken into account as well, meaning that the server will track all the
deployments: default procedures will be disabled server-wide if any of them sets the
`mp.health.disable-default-procedures` to `true` while they will be enabled if none of the current deployed
application does.
====

When the `mp.health.disable-default-procedures` is set to `true` the server will not return any of its health checks in the responses which involve also the default empty configurable checks included before the deployments are processed, namely `empty-readiness-checks`, `empty-startup-checks`, and `empty-liveness-checks`. This means that the server might prematurely respond with invalid `UP` response particularly to `startup` and `readiness` invocations before the user deployment is processed. For this reason, MicroProfile Health specification defines two MicroProfile Config properties that specify the response returned while the server is still processing deployments, i.e. it returns an empty health response:

* `mp.health.default.readiness.empty.response` (default `DOWN`) that specifies empty readiness response. This response will be switched to `UP` once the user deployment is processed even if it doesn't contain any readiness checks. Otherwise, it will be switched to the status set by the user readiness checks.

* `mp.health.default.startup.empty.response` (default `DOWN`) that specifies empty startup response. This response will be switched to `UP` once the user deployment is processed even if it doesn't contain any startup checks. Otherwise, it will be switched to the status set by the user startup checks.

== Component Reference

The MicroProfile Health implementation is provided by the SmallRye Health project.

****

* https://microprofile.io/project/eclipse/microprofile-health[MicroProfile Health]
* http://github.com/smallrye/smallrye-health/[SmallRye Health]

****
