|This repository contains the guide documentation source. To view the guide in published form, view it on the Open Liberty website.|
Learn how to provide external configuration to microservices using MicroProfile Config.
What you’ll learn
You will learn how to externalize and inject both static and dynamic configuration properties for microservices using MicroProfile Config.
You will learn to aggregate multiple configuration sources, assign prioritization values to these sources, merge configuration values, and create custom configuration sources.
The application that you will be working with is an
inventory service which stores the information about various JVMs running on different hosts.
Whenever a request is made to the
inventory service to retrieve the JVM
system properties of a particular host, the
inventory service will communicate with the
service on that host to get these system properties. You will add configuration properties to simulate if a service is down for maintenance.
Try what you’ll build
finish directory in the root of this guide contains the finished inventory application. Feel
free to give it a try before you proceed.
To try out the application, first navigate to the
finish directory and then run the following
Maven goals to build the application and run it inside Open Liberty:
mvn install liberty:start-server
After starting the application, you can access the following two microservices to test their availability:
In addition, you can access a third microservice, which retrieves and aggregates all of the configuration properties and sources that have been added throughout this guide. This is available at:
Once you are done checking out the application, stop the Open Liberty server:
Ordering multiple configuration sources
Now, navigate to the
start directory to begin.
MicroProfile Config combines configuration properties from multiple sources, each known as a ConfigSource. Each ConfigSource has a specified priority, defined by its config_ordinal value.
A higher ordinal value means that the values taken from this ConfigSource will override values from ConfigSources with a lower ordinal value.
There are three default configuration sources as following:
System properties has a default ordinal of 400. (e.g.
Environment variables has a default ordinal of 300. (e.g.
META-INF/microprofile-config.propertiesconfiguration property file on the classpath has a default ordinal of 100.
src/main/resources/META-INF/microprofile-config.properties local configuration file. This configuration file is the default configuration source for an application that uses MicroProfile Config.
Injecting static configuration
The MicroProfile Config API was added as a dependency to your
pom.xml file. Look for the dependency with the
mpConfig artifact ID.
This feature allows you to use the MicroProfile Config API to externalize configurations for your microservices.
mpConfig feature is also enabled in the
Now navigate to the
src/main/resources/META-INF/microprofile-config.properties local configuration file to check some static configuration.
This configuration file is the default configuration source for an application that uses MicroProfile Config.
io_openliberty_guides_port_number property that has already been defined in this file, determines the port number of the REST service.
To use this configuration property, create a
io_openliberty_guides_port_number property, and add the
getPortNumber() class method to the
@Inject annotation injects the port number directly, the injection value is static and fixed on application starting.
getPortNumber() method directly returns the value of
portNumber because it has been injected.
Injecting dynamic configuration
Note that three default config sources mentioned above are static and fixed on application starting, so the properties within them cannot be modified while the server is running. However, you can externalize configuration data out of the application package, through the creation of custom configuration sources, so that the service updates configuration changes dynamically.
Creating custom configuration sources
Custom configuration sources can be created by implementing the
org.eclipse.microprofile.config.spi.ConfigSource interface and using the
CustomConfigSource.json JSON file has already been created in the
resources directory. This JSON file simulates a remote configuration resource in real life.
This file contains 4 custom config properties and has an ordinal of
To use these properties in the application, the data object needs to be transformed from this JSON file to the configuration for your application.
To link this JSON file to your application, create a
CustomConfigSource class in the
src/main/java/io/openliberty/guides/config/CustomConfigSource.java file. Add the following content to implement the
getProperties() method reads the key value pairs from the
resources/CustomConfigSource.json JSON file and writes the information into a map.
Last but important, register the custom configuration source. Create a
src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource file. Add the following fully qualified class name of the configuration source into it:
Enabling dynamic configuration injection
Now that the custom configuration source has successfully been set up, you can enable dynamic configuration injection of the properties being set in this ConfigSource.
To enable this dynamic injection, first access the partially implemented Java class in the
io_openliberty_guides_inventory_inMaintenance property, and add the
isInMaintenance() class method. Simply copy all the following code and replace the contents of the file:
@ConfigProperty annotations inject the
io_openliberty_guides_inventory_inMaintenance configuration property from the
Provider<> interface used, forces the service to retrieve the inMaintenance value just in time. This retrieval of the value just in time makes the config injection dynamic and able to change without having to restart the application.
Every time that you invoke the
inMaintenance.get() method, the
Provider<> interface picks up the
latest value of the
io_openliberty_guides_inventory_inMaintenance property from configuration sources.
Creating custom converters
Configuration values are purely Strings. MicroProfile Config API has built-in converters that automatically converts configured Strings into target types such as
Therefore, in the previous section, it is type-safe to directly set the variable type to
To convert configured Strings to an arbitrary class type, such as the
To use this
The Type parameter of the interface is the target type the String is converted to.
src/main/java/io/openliberty/guides/config/CustomEmailConverter.java file, and add the following content to implement the
To register your implementation, create a
src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.Converter file. Add the following fully qualified class name of the custom converter into it:
To use the custom
src/main/java/io/openliberty/guides/inventory/InventoryConfig.java file, inject the
io_openliberty_guides_email property, and add the
getEmail() method. Simply copy all the following code and replace the contents of the file:
Adding configuration to the microservice
To use externalized configuration in the
inventory service, open the
Simply copy all the following code and replace the contents of the file:
To add configuration to the
inventory service, the
InventoryConfig object is injected to the existing class.
The port number from the configuration is retrieved by the
inventoryConfig.getPortNumber() method and passed to the
manager.get() method as a parameter.
To determine whether the inventory service is in maintenance or not (according to the configuration value),
inventoryConfig.isInMaintenance() class method is used.
If you set the
io_openliberty_guides_inventory_inMaintenance property to
true in the configuration, the inventory service returns the message,
ERROR: Service is currently in maintenance, along with the contact email.
The email configuration value can be get by calling
Once the server is running, the following two microservices should be available to access:
You can find the service that retrieves configuration information that is specific to this guide at the following location:
config_ordinal value of the custom configuration source is set to
150. It overrides configuration values of the default
microprofile-config.properties source, which has a
config_ordinal value of
Play with this application by changing configuration values for each property in the
Your changes are added dynamically, and you do not need to restart the server. Refresh
http://localhost:9080/config to see the dynamic changes.
For example, change
true, then try to access
The following message displays:
ERROR: Service is currently in maintenance.
Testing the application
src/test/java/it/io/openliberty/guides/config/ConfigurationTest.java file and add the following code:
testInitialServiceStatus() test case reads the value of the
io_openliberty_guides_inventory_inMaintenance configuration property in the file
META-INF/microprofile-config.properties and checks the HTTP response of the inventory service.
If the configuration value is
false, the service returns a valid response. Otherwise, the service returns the following message:
ERROR: Service is currently in maintenance.
io_openliberty_guides_inventory_inMaintenance configuration property is set to
false by default, the
testPutServiceInMaintenance() test case first checks that the inventory service is not in maintenance in the beginning.
Next, this test switches the value of the
io_openliberty_guides_inventory_inMaintenance configuration property to
In the end, the inventory service returns the following message:
ERROR: Service is currently in maintenance.
testChangeEmail() test case first puts the
inventory service in maintenance, then it changes the email address in the configuration file. In the end, the
inventory service should display the error message with the latest email address.
In addition, a few endpoint tests have been provided for you to test the basic functionality of the
system services. If a test failure occurs, then you must have introduced a bug into the code.
Reminder that you must register the custom configuration source and custom converter in the
src/main/resources/META-INF/services/ directory, if you miss to complete these steps, the tests will fail.
------------------------------------------------------- T E S T S ------------------------------------------------------- Running it.io.openliberty.guides.config.ConfigurationTest Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 4.729 sec - in it.io.openliberty.guides.config.ConfigurationTest Running it.io.openliberty.guides.inventory.InventoryEndpointTest Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.477 sec - in it.io.openliberty.guides.inventory.InventoryEndpointTest Running it.io.openliberty.guides.system.SystemEndpointTest Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.013 sec - in it.io.openliberty.guides.system.SystemEndpointTest Results : Tests run: 3, Failures: 0, Errors: 0, Skipped: 0
To see whether the tests detect a failure, remove the configuration resetting line in the
setup() method of the
Then manually change some configuration values in the
Re-run the Maven build. You will see a test failure occur.
Great work! You’re done!
You just built and tested a MicroProfile application with MicroProfile Config and Open Liberty.
Feel free to try one of the related guides. They demonstrate new technologies that you can learn and expand on top what you built in this guide.