We have already seen how dropwizard is so effective in developing self-contained REST APIs and even REST client services as well. Dropwizard contains almost all the needed packages to build APIs in a very easy way without making things complex. One of the easily implemented features of dropwizard is the health check service which can be used for monitoring the status of the application/components that you are creating – in runtime.
1. Implementing Dropwizard Health Check
DropWizard health check is implemented by extending the HealthCheck
class and returning Result.healthy()
if everything is alright and Result.unhealthy()
if something is not working – as expected.
1.1. Extend HealthCheck class
import com.codahale.metrics.health.HealthCheck;
public class ApplicationHealthCheck extends HealthCheck {
@Override
protected Result check() throws Exception {
boolean status = true;
//Check application health and set the status accordingly
if(status == false)
return Result.unhealthy("message");
return Result.healthy();
}
}
1.2. Register with Environment
To register this AppHealthCheck
class with dropwizard application, use Environment.healthChecks()
registry.
public class App extends Application<ApplicationConfiguration> {
@Override
public void initialize(Bootstrap<ApplicationConfiguration> b) {
}
@Override
public void run(ApplicationConfiguration c, Environment e) throws Exception {
...
LOGGER.info("Registering Application Health Check");
e.healthChecks().register("application", new ApplicationHealthCheck());
...
}
public static void main(String[] args) throws Exception {
new App().run(args);
}
}
2. Validating Application Health
Dropwizard will an HTTP resource endpoint on /healthcheck
on the admin port (default 8081). Dropwizard also includes a check for deadlocks by default along with any custom health checks.
HTTP GET http://localhost:8081/healthcheck
Above health check URL will return some results as below:
{
"APIHealthCheck": {
"healthy": true
},
"deadlocks": {
"healthy": true
}
}
3. Custom REST Resource to Run Health Checks
If you do not want to use the admin port then you can also create a custom REST resource that will run health checks for you, and return the result in your desired response format.
To run all health checks and get all their results, you will call registry.runHealthChecks()
inside REST resource.
import com.codahale.metrics.health.HealthCheck.Result;
import com.codahale.metrics.health.HealthCheckRegistry;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import java.util.Map.Entry;
import java.util.Set;
@Produces(MediaType.APPLICATION_JSON)
@Path("/status")
public class HealthCheckController {
private HealthCheckRegistry registry;
public HealthCheckController(HealthCheckRegistry registry) {
this.registry = registry;
}
@GET
public Set<Entry<String, Result>> getStatus() {
return registry.runHealthChecks().entrySet();
}
}
Now when we call this REST API using http://localhost:8080/health-check
, we get responses like below:
[
{
"APIHealthCheck": {
"healthy": true,
"message": null,
"error": null
}
},
{
"deadlocks": {
"healthy": true,
"message": null,
"error": null
}
}
]
You can customize the messages as per your need.
4. Demo
To demonstrate the above functionalities, I have modified the code given in dropwizard hello world application.
public class ApplicationHealthCheck extends HealthCheck {
private final Client client;
public ApplicationHealthCheck(Client client) {
super();
this.client = client;
}
@Override
protected Result check() throws Exception {
WebTarget webTarget = client.target("http://localhost:8080/employees");
Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_JSON);
Response response = invocationBuilder.get();
ArrayList<Employee> employees = response.readEntity(ArrayList.class);
if (employees != null && !employees.isEmpty()) {
return Result.healthy();
}
return Result.unhealthy("API Failed");
}
}
App.java
@Override
public void run(ApplicationConfiguration c, Environment e) throws Exception {
LOGGER.info("Registering Jersey Client");
final Client client = new JerseyClientBuilder(e)
.using(c.getJerseyClientConfiguration())
.build(getName());
e.jersey().register(new APIController(client));
LOGGER.info("Registering Application Health Check");
e.healthChecks().register("application", new ApplicationHealthCheck(client));
}
Now validate the default and custom health check URLs:
4.1. Default URL
HTTP GET http://localhost:8081/healthcheck

4.2. Custom Health Check URL
http://localhost:8080/status

Let me know of your questions in the comments section.
Happy Learning !!