Spring Cloud Config Server with Git Integration

Microservices approach now has become an industry standard for any new API development, and almost all the organizations are promoting it. Spring cloud provides excellent tools to build these microservice on top of the Spring boot framework.

In this spring cloud configuration tutorial, we will discuss a specific Microservice feature called Config Server. Config server is where all configurable parameters of all microservices are stored and maintained.

It is more like externalizing properties/resource file out of project codebase to an external service altogether so that any changes to any given property does not necessitate the re-deployment of service which is using that property. All such property changes will be reflected without redeploying the microservice.

Table of Contents

1. Why to Use Config Server
2. Tech Stack
3. Config Server Configuration
4. Config Client Configuration
5. Demo
6. Things to check if facing any error

1. Why to Use Spring Cloud Config Server

The idea of config server has come from the 12-factor app manifesto related to the best practices guidelines of developing modern cloud-native applications. It suggests to externalize properties or resource files out of server where the values of those resources vary during runtime – usually different configurations that will differ in each environment.

As an example, let’s say one service is dependent on another service (invoked for specific business scenarios) and if that dependent service URL got changed to something else. Then usually we need to build and deploy our service with the updated URL. Now, if we go by the 12-factor app approach and if we read those config properties from external service, then we just need to update URL in the config server and refresh that client service configuration to use the updated URL.

So, the idea is obvious and effective. Let’s now see how to create spring cloud config server.

2. Tech Stack

We will be using spring-boot based spring-cloud API that is readily available and very popular. It is called Config Server in spring framework nomenclature. Also, we will use the git configuration to host the properties file.

So finally, our technology stack for this demo will be:

  1. Java 1.8
  2. Eclipse IDE
  3. Spring cloud
  4. Spring boot
  5. Spring Rest
  6. GitHub as resource repository
  7. Maven
  8. REST client

To start with, we will develop two microservices using spring boot.

  1. one is the config server service, providing the configuration in runtime
  2. one is the config client service, using the configuration exposed as config server.

3. Config Server Configuration

Let’s first build the config server part with given steps:

  1. Generate the project structure

    Start with spring boot initializer portal which is a great starting point for creating any spring boot based application. Here we will choose only Config server starter pom. The screen shot is something like this. With this configuration, once we generate the project, one zip file will be downloaded, which we will import in eclipse after unzipping.

    Generate Server Project with Config Server Starter POM
    Generate Server Project with Config Server Starter POM
  2. Import the project in Eclipse

    Once you have the zip file from the spring initializer portal, we need to unzip it to a directory we choose to and import it to eclipse as maven project.

    <properties>
    	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    	<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    	<java.version>1.8</java.version>
    	<spring-cloud.version>Hoxton.RELEASE</spring-cloud.version>
    </properties>
    
    <dependencyManagement>
    	<dependencies>
    		<dependency>
    			<groupId>org.springframework.cloud</groupId>
    			<artifactId>spring-cloud-dependencies</artifactId>
    			<version>${spring-cloud.version}</version>
    			<type>pom</type>
    			<scope>import</scope>
    		</dependency>
    	</dependencies>
    </dependencyManagement>
    
    <dependencies>
    	<dependency>
    		<groupId>org.springframework.cloud</groupId>
    		<artifactId>spring-cloud-config-server</artifactId>
    	</dependency>
    	<dependency>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-actuator</artifactId>
    	</dependency>
    	<dependency>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-test</artifactId>
    		<scope>test</scope>
    	</dependency>
    </dependencies>
    
  3. Build in eclipse

    Next step will be to run mvn clean install from either command prompt or from eclipse whatever you are comfortable with. In this step, all necessary dependencies will be downloaded from the maven repo. Make sure you are trying it from any network where no download restriction is present. Successful build in this step is very much required to proceed to the next steps.

  4. Add @EnableConfigServer annotation

    Now open the Spring Application class that spring already has provided and add the @EnableConfigServer annotation before the class and build the project once again. With this annotation, this artifact will act like a spring config server.

    After adding this annotation, the class will look like below – the class name can be different depending on the Project name you gave while generating. Also you can manually change the class name to a name you like it.

    package com.howtodoinjava.example.springconfigserver;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.config.server.EnableConfigServer;
    
    @EnableConfigServer
    @SpringBootApplication
    public class SpringConfigServerApplication 
    {
    	public static void main(String[] args) 
    	{
    		SpringApplication.run(SpringConfigServerApplication.class, args);
    	}
    }
    
    
  5. Client properties in git repository

    The next essential step is to create a local git repository. It can easily be converted to a remote repository later by configuring its URL in the properties file. We will place the external property file [configuration], which will be used by the Config server microservice to provide the external configuration of properties. We need to follow the below steps to create a local git repository and check-in sample properties files.

    1. Make sure you have git shell installed in your machine and you can run git bash from command prompt. To verify it open command prompt and type git, if it recognize the command then you probably have the git prompt installed, if not please follow git website, download and install as per the instruction.
    2. Now Create a directory config-server-repo in your Desktop.
    3. Then create a file config-server-client.properties file in the config-server-repo directory and add the message there msg = Hello world - this is from config server.
    4. Then create another file config-server-client-development.properties file in the config-server-repo directory and add the message there msg = Hello world - this is from config server – Development environment.
    5. Then create another file config-server-client-production.properties file in the config-server-repo directory and add the message there msg = Hello world - this is from config server – Production environment.
    6. Here we are maintaining same property name for different environment, as we generally maintain properties for different environments like urls, credentials, database details etc. Here the most important point is that we need to append hyphen (-) with the environment name in each property so that config server understands it. Also, we need to name the properties file with the config client service name that we will create after this.
    7. Now open command prompt from config-server-repo directory and run command git init to make that directory as git repository.
    8. Now run git add . to add everything to this repo.
    9. Then finally we need to commit the properties file by running command git commit –m "initial checkin". This should check in all the files in the git repository. Here is the command prompt screen shot for the same.
      Property Check-in in Git
      Property Check-in in Git
      msg = Hello world - this is from config server - default profile
      
      msg = Hello world - this is from config server - Development Environment
      
      msg = Hello world - this is from config server - Prodcution Environment
      
      $ git init
      
      $ git add .
      
      $ git commit -m "initial commit"
      
  6. Point the Git repo from Config Server

    Create one file called bootstrap.properties in the src\main\resources directory of spring-config-sever project and add below lines.

    #Server port
    server.port = 8888
    
    #Git repo location
    spring.cloud.config.server.git.uri=E:\\devsetup\\gitworkspace\\spring-cloud\\config-git-repo
    
    #Verify any repository issue in service startup
    spring.cloud.config.server.git.cloneOnStart=true
    
    #Disable security of the Management endpoint
    management.security.enabled=false
    

    Now let’s understand those properties.

    • server.port defines the port on which the embedded server will start.
    • spring.cloud.config.server.git.uri will bind the git location to look for the configuration. Here we are using local git repo but can be switched to remote got location by just changing this location.
    • management.security.enabled=false will disable the spring security on the management enpoints like /env, /refresh etc. This is for development settings, in production security should be enabled.

    So, this step will point to a git location and server port.

    All above steps are very much we need to do in the config server-side, now do a final mvn clean install command on this project so that everything gets compiled properly and also packaged in the target folder as well as in local maven repository. We will start the config server service once we have the client part ready and we will finally test the feature.

  7. Verify Configuration

    The command to run the service in embedded mode is java -jar target\spring-config-server-0.0.1-SNAPSHOT.jar however we will revisit this in the testing part.

    To check if the Config-server can recognize the properties, first run the config server microservice from command prompt by using the given command from command prompt of the project code base location.

    java -jar target\spring-config-server-0.0.1-SNAPSHOT.jar

    Now open browser and check below URLs, it will return the JSON output and in propertySources section we can see all the properties we have added in the properties. This ensures that the config-server is running successfully, it has recognized the git location, and it is serving configuration for different environments.

    • http://localhost:8888/client-config/development
    • http://localhost:8888/client-config/production

    Also to check if any change in the property file is reflected by the server without restart – do a change in the value of any environment’s property and check-in property file. Then run that specific environment’s endpoint, and verify that changed property value should be reflected immediately without restarting the server.

    To do the git check in, after doing the change and save the file by any text editor, run the command git add . and git commit -m "test"

4. Config Client Configuration

Now we will proceed to the client-side implementation where we will use those properties from a separate microservice, which is our final goal – to externalize the configuration to different services.

  1. Create Maven Project

    Go to https://start.spring.io/ web portal and generate client project with the below selected artifacts:

    1. Actuator
    2. Config Client
    3. Web
    4. Rest Repositories

    The screen will look like below before generation; once we click on generate, we will get the .zip file download option. Like Spring-Config-Server, unzip the file in some directory and import it in eclipse.

    <properties>
    	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    	<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    	<java.version>1.8</java.version>
    	<spring-cloud.version>Hoxton.RELEASE</spring-cloud.version>
    </properties>
    
    <dependencyManagement>
    	<dependencies>
    		<dependency>
    			<groupId>org.springframework.cloud</groupId>
    			<artifactId>spring-cloud-dependencies</artifactId>
    			<version>${spring-cloud.version}</version>
    			<type>pom</type>
    			<scope>import</scope>
    		</dependency>
    	</dependencies>
    </dependencyManagement>
    
    <dependencies>
    	<dependency>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-actuator</artifactId>
    	</dependency>
    	<dependency>
    		<groupId>org.springframework.cloud</groupId>
    		<artifactId>spring-cloud-starter-config</artifactId>
    	</dependency>
    	<dependency>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-data-rest</artifactId>
    	</dependency>
    	<dependency>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-web</artifactId>
    	</dependency>
    
    	<dependency>
    		<groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-test</artifactId>
    		<scope>test</scope>
    	</dependency>
    </dependencies>
    

    Generate Client Project with Listed Dependencies
    Generate Client Project with Listed Dependencies
  2. Create REST Resource

    Add one RestController to view the Server side property values in the response. To do that open the @SpringBootApplication class file that has been generated, and add the below small class in the end of that file. This is very simple and straight forward, we are just exposing one method at /message URL where we will just return the property value of msg that will be supplied by the config server microservice, which is configured to a local git repository (which will be migrated to a remote git repository in production!).

    package com.howtodoinjava.example.springconfigclient;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.context.config.annotation.RefreshScope;
    import org.springframework.core.env.Environment;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @SpringBootApplication
    public class SpringConfigClientApplication {
    
    	public static void main(String[] args) {
    		SpringApplication.run(SpringConfigClientApplication.class, args);
    	}
    	
    	@Autowired
    	public void setEnv(Environment e)
    	{
    		System.out.println(e.getProperty("msg"));
    	}
    }
    
    @RefreshScope
    @RestController
    class MessageRestController {
    
    	@Value("${msg:Config Server is not working. Please check...}")
    	private String msg;
    
    	@GetMapping("/msg")
    	public String getMsg() {
    		return this.msg;
    	}
    }
    
  3. Bind with the Config Server

    Create one file called bootstrap.properties in the src\main\resources directory and add the below properties to connect with the config server along with some required configuration.

    spring.application.name=client-config
    
    #Active Profile - will relate to development properties file in the server. 
    #If this property is absent then,default profile will be activated which is 
    #the property file without any environment name at the end. 
    spring.profiles.active=development
    
    # N.B. this is the default:
    spring.cloud.config.uri=http://localhost:8888
    
    management.security.enabled=false
    

    Let’s understand the properties now.

    • spring.application.name is just the application name of the microservice that would be deployed.
    • spring.cloud.config.uri is the property to mention the config server url. Point to note that our config server is running on port 8888; verify it by opening the application.properties file of the spring config server code base and check the server.port=8888.
    • management.security.enabled=false will disable the spring security on the management endpoints like /env, /refresh etc. This is for development settings, in production security should be enabled.
  4. Verify Client Config

    This is very much we need to do in the config client side, not do a final mvn clean install command on this project so that everything gets compiled properly and packaged also in the target folder as well as in local maven repository. We will start the config client service along with the server side and we will finally test the feature.

5. Demo

Let’s test the config server application.

  • Build and Run Config Server Project

    Open command prompt from spring-config-server folder and run mvn clean install command. Once build is completed run the application from that command prompt itself by java -jar command like java -jar target\spring-config-server-0.0.1-SNAPSHOT.jar.

    This will start the config server service in 8888 port in the localhost.

  • Build and Run Config Client Project

    Similarly, Open command prompt from spring-config-client folder and run mvn clean install command. Once build is completed run the application from that command prompt itself by java -jar command like java -jar target\spring-config-client-0.0.1-SNAPSHOT.jar.

    This will start the Config Client service in 8080 port of localhost.

  • Test REST Endpoint

    Now in the browser open the /msg rest endpoint by browsing the url http://localhost:8080/msg. It should return Hello world - this is from config server which is mentioned in the config-server-client-development.properties file.

    Test REST End Point
    Test REST End Point
  • Test Property Change

    Now we will do a property change and test if this can be reflected in the config client service without restarting any of the Microservices.
    Do some change, in the value of the msg property in the config-server-client-development.properties and check-in in the local git, then hit the http://localhost:8080/msg again in the browser, You will the old value only.

    To reflect the new value, we need to refresh the configuration by hitting http://localhost:8080/refresh endpoint using POST method from any of the REST client.

    Once you have successfully refreshed the config client service, the new value should be reflected in the service response. This is because @RefreshScope annotation the Rest Controller that we have exposed.

6. Things to check if facing any error

  • Property file name and the Client module service name spring.application.name=config-server-client should be exactly same, otherwise, properties will not be detected. Actually, Config Server exposes the properties in an end point of property file name, if you browse URL http://localhost:8888/config-server-client/development it will return all the dev environment values.

    All Dev Properties View
    All Dev Properties View
  • Make sure you have checked-in the properties files in the git repo by using git init/add/commit commands as described above.
  • Make sure you have refreshed the client service environment by invoking POST method of http://localhost:8080/refresh by any REST client. Otherwise changed values will not be reflected in the client service.
  • Make sure at the time of starting the config client service, config server service is running already. Otherwise, it might take some time to register, which might create confusion while testing.

That’s all about creating a Config server for microservices. Please add comments if you have any difficulty in configuring all the points mentioned in this article, we will be happy to look into the problem.

Happy Learning !!

Was this post helpful?

Join 7000+ Fellow Programmers

Subscribe to get new post notifications, industry updates, best practices, and much more. Directly into your inbox, for free.

15 thoughts on “Spring Cloud Config Server with Git Integration”

  1. Hi
    I’m passing cipher text in git credentials to fetch properties directly from git.
    But it’s gives me unauthorised exception with encrypted credentials .
    Can You help?

  2. The endpoint is now /actuator/refresh for Spring 2 and greater

    and for refresh endpoint to work

    management.endpoints.web.exposure.include=refresh

  3. Test REST Endpoint
    Now in the browser open the /msg rest endpoint by browsing the url http://localhost:8080/msg. It should return Hello world – this is from config server which is mentioned in the config-server-client-development.properties file.

    Hey – something seems off on this. “Hello world – this is from config server ” message is from default file not from development properties. Though my application.properties file has development profile activated – property is always pulling from default file not from the development file. please help

  4. Great article.

    I have a config server working, with Git.

    What would be the best practice regarding testing (unit/integration).

    Should we start the config server before test? Seems too heavy for testing

    Another solution would be to duplicate the properties in a test/application.yml but the drawback is that we need to maintain two locations..

    Any other ideas?

    Thanks!

  5. At some point in time/version, the ‘refresh’ endpoint has changed to:

    /actuator/refresh

    and further, requires configuration of:

    management.endpoints.web.exposure.include=refresh

    in order to do its refresh thing properly.

  6. Should the spring boot cloud config client be always a Rest client?. I have a Jms spring boot config client. The properties $Values are null when it fetches from spring cloud config server. It works for Rest client. I do not have spring-web dependency for jms client.

  7. Should the spring boot cloud config client be always a Rest client?. I have a Jms spring boot config client. The properties @Values are null when it fetches from spring cloud config server. It works for Rest client.

  8. Hello
    Thanks for the valuable post.
    Could you please help me in understanding that When should we use config server for external properties?
    If I already know in advance that my configuration are not going to be changed then also should I use config server?

  9. Looks Perfect , you saved my time. thanks you so much. I Just want to know small check. How to load the changed properties without making /refresh rest call ?

Comments are closed.

HowToDoInJava

A blog about Java and its related technologies, the best practices, algorithms, interview questions, scripting languages, and Python.