Monday, July 21, 2014

Disable Spring Boot Production Ready Services

For the past two months I've had the pleasure of working with The Lampo Group developing Hypermedia-Driven REST services using Spring Boot. Spring Boot makes it super simple to get started writing REST services. One of its biggest advantages is by default it embeds tomcat as the servlet container, allowing the developer to focus on other important things. Another great thing about Spring Boot is it includes the ability to easily enable what they call Production-Ready or Production-Grade Services. These services allow you to monitor and manage your application when its pushed to production and it's as easy as adding a dependency to your project. Unfortunately, it wasn't well documented on how to disable some of these services. But before I show you how to disable them, let me first show you how to enable them.

Enabling Spring Boot's Production-Ready Services
One of the reasons we wanted to enable some of the production-ready services was our target production environment was Amazon Web Services (AWS). As a part of that they support Elastic Load Balancing which allows one to configure a health check endpoint. It's basically an endpoint you configure in AWS that gets pinged to make sure the EC2 instance is up and running. As luck would have it, one of the services included in Spring Boot's production-ready services was a health endpoint.

To enable the production-ready services all you have to do is add a dependency to your project. If you are using maven all you have to do is add the following to your pom.xml.

<dependency>
    <groupid>org.springframework.boot</groupid>
    <artifactid>spring-boot-starter-actuator</artifactid>
    <version>1.1.4.RELEASE</version>
</dependency>


After you make the change to your pom.xml, just rebuild your project and you should be able to access http://localhost:8080/health and see something like this:



Not only does it add a health endpoint, but it also adds: autoconfig, beans, configprops, dump, env, info, metrics, mappings, shutdown (not enabled by default over HTTP), and trace. Like us, you might not want to expose all these endpoints in a production environment. In fact, all we wanted to enable was the health and info endpoints. The following will show you how to disable each service individually and how to re-enable them dynamically at runtime.

Disabling Spring Boot's Production-Ready Services
When you include the spring-boot-starter-actuator dependency in your project, it automatically exposes 11 different endpoints in your project. What I wanted to be able to do was disable all endpoints except health and info, but also have the ability to enable the other services at runtime via environment variables.

To disable some of the production-ready services add the following to your /src/main/resources file. These will be your default settings for your project.

endpoints.autoconfig.enabled=false
endpoints.beans.enabled=false
endpoints.configprops.enabled=false
endpoints.dump.enabled=false
endpoints.env.enabled=false
endpoints.health.enabled=true
endpoints.info.enabled=true
endpoints.metrics.enabled=false
endpoints.mappings.enabled=false
endpoints.shutdown.enabled=false
endpoints.trace.enabled=false


To enable/disable endpoints externally at runtime you can follow any one of these steps. Since our project is following the 12-factor app rules we needed the ability to enable/disable endpoints by setting environment variables. So for example, if I wanted to enable the metrics endpoint at runtime, I would set the following environment variable.

export ENDPOINTS_METRICS_ENABLED=true


After restarting Sprint Boot you can access the metrics endpoint at http://localhost:8080/metrics. Note, that as of version 1.0.1.RELEASE, you are unable to disable the mappings endpoint, but this was quickly fixed in 1.1.3.RELEASE.

In summary, I've been very impressed with how easy it is to work with Spring Boot and the production-ready services. In another article I'll cover how to use maven filtering, along with the git-commit-id-plugin, to display project information in the info endpoint.