Reconfiguring Applications with Spring Cloud Config Server
Check out this introductory article which will show you how to...well, reconfigure your applications using Spring Cloud Config Server.
Join the DZone community and get the full member experience.
Join For FreeFirst we code up a simple Spring Boot 2.0 app and a Spring Cloud Config Server for it to use, doing so quickly by using the Spring Initializr. For this you can code along or clone from GitHub for an ASCII Art Transformers version. Then we dockerize the Config Server so that we can use it in a docker-based project.
Create the Client App
We can quickly create a Spring Boot 2.0 app using the Spring Initializr:
We select these Dependencies as we need our app to be a Config Client, we’re going to have it handle web requests so we add Web and we’ll use the Actuator to refresh config.
After importing this project to our IDE we can add the following class to handle http requests (or get it here):
@RestController
@RefreshScope
public class ConfigClientController {
@Value("${message}")
private String message;
@GetMapping
public String hello(){
return message;
}
}
It just outputs a message that comes from a property called ‘message’. It’s marked as @RefreshScope
so that we can later trigger that it should pick up a change to the message property.
In the generated application.properties file we add:
management.endpoints.web.exposure.include=*
message=Hello from application properties
So the message will be ‘Hello from application properties’ and we enable management endpoints (in the Spring Boot 2.0 way; in Boot 1.x we would've set management.security.enabled=false). We need management endpoints so that we can later perform a refresh.
And in the same directory (src/main/resources) we add a bootstrap.properties to indicate where it will later find the Config Server and what our application is called (the Config Server will use the name to know which property file to provide):
spring.application.name=configclient
spring.cloud.config.uri=http://localhost:8888
Now we can start the app by going to its directory and doing ‘mvn spring-boot:run’. Go to localhost:8080 in the browser to see ‘Hello from application properties’. The message comes from the properties file as the Config Server isn't yet running.
Or in the GitHub version we have ASCII art embedded in the properties file so we instead see:
(The ASCII art in the file is generated from ascii-art-generator using images from writesup.org)
Create the Config Server
Next we need to create the Config Server. Again we can go to the Spring Initializr:
First we add the @EnableConfigServer
annotation under @SpringBootApplication
on the ConfigserverApplication class.
Then in the generated application.properties we add:
server.port=8888
spring.cloud.config.server.native.searchLocations=classpath:/
spring.profiles.active=native
This will make the Config Server available on port 8888 (which is the default anyway but it’s nice to be explicit) and tell it to host config files it finds on its own java classpath—we have to use the ‘native’ profile to do that. (For real-life scenarios we’d more likely want to host files from a git repo but we’ll come back to that later.)
Create a file in the same directory (src/main/resources) called ‘configclient.properties’ containing:
message=Hello from configserver
Start the Config Server by running ‘mvn spring-boot:run’ from its directory. Go to http://localhost:8888/configclient/default in the browser and you’ll see that the Config Server is now hosting config.
Refresh the Client App
So the configclient is running and the configserver is hosting config. But localhost:8080 still shows ‘Hello from application properties’.
We can refresh the client app (in the boot 2.0 way) with:
curl -X POST http://localhost:8080/actuator/refresh
(Note in Spring Boot 1.x the endpoint was http://localhost:8080/refresh. If you don't have curl you could do an empty POST from postman.)
Now if we go to localhost:8080 again or refresh that page in the browser we see 'Hello from configserver'. So we can see that the app now after the refresh has used the bootstrap.properties to find the Config Server and used the config from the server in preference to the values in the application.properties.
In the GitHub version we have different ASCII Art in the configclient.properties so now we see:
Dockerizing the Config Server
Using the classpath of the Config Server helped us see everything working quickly but probably isn’t how we want to run in a live system. We’re more likely to want to use a remote git repository. So we’ll want to take out the spring.profile.active and spring.cloud.server.native.searchLocations lines from the configserver’s application.properties as they tell the server to use local files.
We could add a line to set the URI to a GitHub repo containing the configclient.properties file (by setting the spring.cloud.config.server.git.uriproperty). But if we’re planning to use Docker we can use relaxed binding so that instead we pass in the environment variable SPRING_CLOUD_CONFIG_SERVER_GIT_URI.
Then we just need to add a Dockerfile to build the image. We can use this:
# requires Docker version 17.05.0-ce-rc1, build 2878a85
FROM maven:3.5-jdk-8 as BUILDCONFIGSERVER
COPY src /usr/src/myapp/src
COPY pom.xml /usr/src/myapp
RUN mvn -f /usr/src/myapp/pom.xml clean package -DskipTests
FROM openjdk:alpine
COPY --from=BUILDCONFIGSERVER /usr/src/myapp/target/*.jar /maven/
CMD java $JAVA_OPTS -jar maven/*.jar
Or just fork this project from GitHub which includes the Dockerfile. We can check this works by doing:
docker build . -t configserver
docker run -it -p 8888:8888 -e SPRING_CLOUD_CONFIG_SERVER_GIT_URI=https://github.com/spring-cloud-samples/config-repo configserver
And going to http://localhost:8888/bar/default in the browser. (Here https://github.com/spring-cloud-samples/config-repo is the URI of a sample repo from Spring Cloud containing a bar.properties)
Now that we have an image, we can push the image to a docker registry or create an automated build on dockerhub. Or if you don’t want to maintain an image there are others out there who have created images that are available to use (e.g. https://hub.docker.com/r/hyness/spring-cloud-config-server/ ). But if you need to customise the Config Server (say, adding Spring Security) then you’ll want to build the image yourself.
There are much more sophisticated ways of setting up the chain of refreshing the server and refreshing the client’s properties but that’s beyond the scope of this introductory article. To see what more you can do it’s best to read a more in-depth article on using the config server. Or if this has all moved a bit fast then consider a more slow-paced introduction.
Opinions expressed by DZone contributors are their own.
Comments