There is a Spring Boot add-on known as Actuator
which provides a user insight into the Spring environment for a running application. It has several endpoints, and a full discussion of this functionality can be found in the Actuator Documentation
One of the more interesting endpoints provided by Actuator is /health
. This endpoint will provide an indication of the general health of the application, and for each of the @Component
classes that implement the HealthIndicator
interface, will actually check the health of that component. By default, all standard components (such as DataSource) implement this interface. The HealthCheck provided by a DataSource is to make a connection to a database and perform a simple query, such as select 1 from dual
against an Oracle DataBase.
There will be a case where the functionality of a Component will be outside of what Spring naturally provides, and a custom health check will be required. In order to accomplish this, simply create a class that implements the HealthIndicator
interface and annotate it with @Component
to pull it into the Spring context. The following example performs a health check against a cache, a data source, and a remote (SOAP or Rest) service:
@Override
public Health health() {
// check cache is available
Cache cache = cacheManager.getCache("mycache");
if (cache == null) {
LOG.warn("Cache not available");
return Health.down().withDetail("smoke test", "cache not available").build();
}
// check db available
try (Connection connection = dataSource.getConnection()) {
} catch (SQLException e) {
LOG.warn("DB not available");
return Health.down().withDetail("smoke test", e.getMessage()).build();
}
// check some service url is reachable
try {
URL url = new URL(resUrl);
int port = url.getPort();
if (port == -1) {
port = url.getDefaultPort();
}
try (Socket socket = new Socket(url.getHost(), port)) {
} catch (IOException e) {
LOG.warn("Failed to open socket to " + resUrl);
return Health.down().withDetail("smoke test", e.getMessage()).build();
}
} catch (MalformedURLException e1) {
LOG.warn("Malformed URL: " + resUrl);
return Health.down().withDetail("smoke test", e1.getMessage()).build();
}
return Health.up().build();
}
Implementing a custom health check class is preferred to adding this code directly to a smoke test controller, as it takes full advantage of the Actuator framework.