Hybrid Deployments

Scaling Your Java MicroProfile-Based Microservices App (1 of 3)

Share this post:

Scaling your microservices: How to externalize the configuration for flexibility and easier deployment

As explained in IBM Cloud Method’s microservices architecture, the notable benefits of this approach include simplified deployment and more efficient development teams, thanks to the separation of a traditional “monolith” application into discrete, network-connected services that can be updated independently. This independence also simplifies application scalability because resources like CPU and memory can be allocated to individual services independently, consistent with their criticality to the overall app and anticipated throughput demands.

In the next three entries of this blog series, we’ll cover how to handle the factors below when handling scalability for Liberty’s MicroProfile-based microservices:

  • Externalizing configuration
  • Security
  • Fault tolerance

Thankfully, these considerations are part of the base MicroProfile, so the developer burden is minimal.

NB: For those who may have joined late, this blog series is based on my team’s experience migrating our simple storefront application from a Spring Boot-based microservices to MicroProfile, an optimized microservices programming model for enterprise Java. It was originally coded using Spring Boot (source code) and migrated to MicroProfile (source code). Both the projects are hosted on GitHub with source code and full documentation.

Why externalization of your microservices app’s configuration is important

Cloud-native designs often depend on several microservices apps to deliver their results. These microservices apps may run on multiple environments. Of course, when they run on different environments, they need different configurations. For example, they may need deployment-specific external URLs or credentials that change regularly. If the developer hardcodes these configuration values within the service, it would have to be redeployed for every configuration change.

MicroProfile

To avoid the hassle of redeploying microservices app code for different environments, the solution is clear—externalize the configurations! This is cited in the twelve-factor app methodology. The good news is that the MicroProfile Config Feature defines an API for Java Enterprise, including IBM WebSphere Liberty (see IBM Doubles Down on Enterprise Java with WebSphere Liberty on ADTmag.com for more details).

In our last blog post, we showed you how MicroProfile Rest Client and JSON-B makes our work easier while building microservices using REST. In today’s blog post, I’ll explain how to externalize the configurations in order to run them on different execution environments without any source code changes.

Externalized configuration for Spring Boot apps

Spring Boot Config allows the externalization of the configurations in various environments without changing any application code. To enable this, properties can be defined as environment variables, command line arguments, properties files, and YAML files. Configurations in our reference application are defined using YAML files and the properties are bound using the @ConfigurationProperties annotation. The properties can also be configured using the @Value annotation.

Externalized configuration for MicroProfile apps

MicroProfile Config allows one to externalize configuration properties and retrieve their values from the target environment without changing any application code. You can easily obtain configuration from different sources like system properties, system environment variables, and properties files. These configuration values can be overridden in properties files and overridden programmatically at runtime. Using this feature enables the application to pick up configured values immediately after they are updated.

The config values are sorted according to their ordinal value. We can override the lower importance values by passing them externally during application installation, assembly, or at runtime. Below is the order of importance for the config sources:

  1. System.getProperties()
  2. System.getenv()
  3. all META-INF/microprofile-config.properties files on the classpath.

Contrasting MicroProfile and Spring Boot support of externalized configuration

Externalizing the configuration from the code is important. Without this separation, you would need to recompile the application whenever the configuration values change. If you have many instances of the same service running, updating the configurations for all of them will be difficult and time-consuming.

In both the MicroProfile and Spring Boot implementations, we externalized the properties to a config file. In the Spring Boot implementation of our sample application, we used application.yml as our config file and those were retrieved using the @ConfigurationProperties annotation. Whereas in MicroProfile implementation, we obtained the configuration programatically. This can be done by obtaining the config object. The config object contains all the required properties and each property can be obtained via the getValue() method. Below are sample snippets of each approach from our sample application:

Spring Boot MicroProfile
application.yml

elasticsearch:
  url: http://localhost:9200
  user:
  password:
  index: micro
  doc_type: items
microprofile-config.properties

elasticsearch_url=http://localhost:9200
elasticsearch_index=micro
elasticsearch_doc_type=items
# optional
elasticsearch_user=<user name>
elasticsearch_password=<password>
Code excerpt

@Component("ElasticConfig")
@ConfigurationProperties(prefix  = "elasticsearch")
public class ElasticsearchConfig {

  private  String url;

  public String getUrl()  {
    return url;
  }

  public void setUrl(String url)  {
    this.url= url;
  }
}

@Service
public class ItemService {

  @Autowired
  private ElasticsearchConfig config;
  private String url= config.getUrl();
}
Code excerpt

public class ElasticSearch {
    Config config = ConfigProvider.getConfig();
    private String url =
        config.getValue
        ("elasticsearch_url", String.class);
}

The above are examples for one approach—you can do it in multiple ways. For more, check out BlueCompute – MicroProfile implementation on GitHub.

Hurray! That’s it, and all the configuration values for our sample application are externalized. Personally, I felt like the MicroProfile Config approach is easy to use and more straightforward than the Spring Boot Config. For more details on how the Catalog Service is built, see the source code on GitHub. To run the whole application together, see the project README.

What’s next

Modern development shops run their microservices apps in different environments, like dev, test, and production. Each requires specific values that must be changed based on the deployment environment. Updating them individually would be a pain! Externalizing the configuration values as described earlier supports a reliable, predictable DevOps-driven process. The MicroProfile Config Feature allows you to conveniently change these values without modifying your application code. It is as simple as defining a properties file and choosing the underlying methods (annotations, programmatically, or a combination of both) to use the configurations in your application.

When I worked on externalizing the configurations for our simple storefront application, the Open Liberty guides are extremely helpful and made my work easier. I used Configuring microservices as my reference.

MicroProfile Config is just one among the several awesome specifications that come with Eclipse MicroProfile. The next blog post will cover Security and MicroProfile JWT Propagation. In the meantime, take a look at our microservices reference implementation available on GitHub. Each microservice in our simple storefront application can be run individually using Maven as well, so you can import them and run as-is locally, or can run them on IBM Cloud and IBM Cloud Private.

Cloud Solution Architect

More Hybrid Deployments stories
November 7, 2018

Open Liberty Loves Spring

We think Open Liberty and Spring go well together. Liberty loves Spring and we want to make it easy for Spring Boot developers to love Liberty. With the new boost-maven-plugin plugin, it's handled automatically as part of your maven build.

Continue reading

November 2, 2018

Scaling Your Java MicroProfile-Based Microservices App (2 of 3)

In this blog series, we cover how to handle scalability for Liberty’s MicroProfile-based microservices, focusing on externalizing configuration, security, and fault tolerance. In this second entry in the series, you'll learn how to secure the REST APIs using MicroProfile JWT Propagation.

Continue reading

October 17, 2018

Certified Kubernetes Deployments Made Easy with WebSphere Liberty Cloud Pak

You want to have confidence in your cloud-based deployment of WebSphere Liberty on Kubernetes. Developers want an environment that's ready to go, administrators want an infrastructure that's trusted. Who wants to be in the business of stitching together component layers and then verifying they're compatible with each other? With IBM Cloud Paks, rely on a trusted and tested release with key components verified as a set.

Continue reading