Company information
Fill up the form and we will contact you shortly.
ServoCode Sp. z o.o.
Jasionka 954E, 36-002 Jasionka, Poland
NIP: 8133719852
REGON: 364182909
KRS: 0000611643
Every application needs a configuration. We can pass variables directly on the command line, read from a file (we usually do that), and sometimes (sometimes quite often but shhh!) - hard-coded in the code, which generates additional time costs (time.equals(money)) at the support stage. It can be very convenient to keep all configuration data in one place so that your infrastructure applications receive data from there.
It might seem that the configuration file is a great solution. Haha, wrong answer!
Example time! One of our clients wants to be able to dynamically change some values in configs. The application is written using Spring Boot and uses the application.properties (with a bunch of profiles) as the configuration file. Normally, you need to restart the server and make some changes in the configuration. However, there are cases when due to a typo or a minimal change, it is necessary to re-compile, build and deploy the application, which can be very time-consuming. Or even inadmissible. The situation is impaired in the case of distributed systems. Here the Consul will help us!
Take a look at the work of the Consul on the example of the simplest Spring Boot application mentioned before.
pom.xml
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>consul</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>consul</name>
<description>Demo project for Spring Boot with Consul</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
In the configuration file, create a variable which has a value that is going to be returned (I hope your application does more meaningful things).
application.yml
foo: bar
com.example.consul.ConsulApplication.java
package com.example.consul;import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class ConsulApplication {
@Value("${foo}")
private String foo;
public static void main(String[] args) {
SpringApplication.run(ConsulApplication.class, args);
}
@GetMapping("/foo")
public String getFoo() {
return foo;
}
}
Run the application:
mvn spring-boot:run
and open the following endpoint in your favourite browser
In the answer, you should get "bar" (at least I hope for it ).
So, what if your client (or you) is fed up (changed requirements etc.) with the return value? Or the value often changes, but it is impossible to constantly compile and run the application or reluctantly? There is one golden solution. You add the Consul in advance!
Add support for the Consul in thr application.
pom.xml
<dependency><groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-all</artifactId>
<version>1.3.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-config</artifactId>
<version>1.3.0.RELEASE</version>
</dependency>
Next to application.yml, create bootstrap.yml, which is loaded before the previous one.spring:
application:
name: ConsulDemo
cloud:
consul:
host: localhost
port: 8500
config:
enabled: true
Restart the app:
mvn spring-boot:run
It is time to start the Consul. To do this, use the ready docker image. Yes, you need to have a Docker installed. Here is the link if you haven't done it yet: https://www.consul.io/downloads.html.
docker run -d --rm --name consul -p 8500:8500 consul
By default, Consul runs on port 8500, but in the products, most likely, you want to change both the address and the port. While opening in the browser http://localhost:8500 we will see a fairly simple and nice interface, as well as our connected application.
Consul looks for the value of the variables in "/config/${appName}". In our case, you need to create the "/config/ConsulDemo/foo" key with some new value, for example, "New value".
Then restart the application once again and open http://localhost:8080/foo in the browser and we will see the new value.
Now you can change the key value at any time and it will be automatically applied the next time it is called. But for this to work, you need to add an @RefreshScope annotation to our controller. After that, changing the values of variables works without restarting the application and SMS.
Project structure
Of course, not all values can be applied without reloading (for example, the port on which the application will be launched), but you will agree: it is very pleasant to test various settings of the application or to lose the need to satisfy such whims of your clients without spending time compiling, assembling and deploying the application!
You can download the whole code here https://github.com/ServoCodeBlog/consul
Have an idea ? Let’s talk
Fill up the form and we will contact you shortly.
ServoCode Sp. z o.o.
Jasionka 954E, 36-002 Jasionka, Poland
NIP: 8133719852
REGON: 364182909
KRS: 0000611643
Your message has been sent!
Your message has been sent!