In this tutorial we will learn how to add Rabbit MQ capabilities to our Spring cloud config server so any changes to configurations can be pushed to all connected applications during runtime. We need such kind of behaviour when we need to refresh the properties without restarting our application. Below is the overall architecture for this complete setup.
Spring Cloud Config Server
Spring cloud config server is used to setup the distributed configuration using GIT or local file system where we can keep our configuration files and serve as them from Spring cloud config server. Client application just has to connect with config server by providing their application and profile name for specific configuration. Please refer below link where I have explained more about cloud config and how to code it.https://www.thetechnojournals.com/2019/10/spring-cloud-config.html
Install Rabbit MQ
Please refer below link on how to install rabbit-mq and virtual host verification.https://www.thetechnojournals.com/2019/11/installing-rabbit-mq.html
Note: If there is any problem running the virtual host then your Spring config server may not be able to connect to rabbitmq and you will see similar error in Spring boot console. c.r.c.impl.ForgivingExceptionHandler : An unexpected connection driver error occured (Exception message: Socket closed)
Spring Cloud Bus
When we have changes to our configuration in GIT source repository then it may notify the config server for the changes and these changes can be pushed to all connected clients so that they can refresh the properties with latest available changes. It can be achieved through the webhook which is supported by many providers like github to publish the event in which users are interested. Then config server push the event to all clients through rabbitmq and all connected clients refresh the changes at runtime. Below changes are required to enable the spring cloud bus in spring cloud config server application which we have seen in first section "Spring Cloud Config Server".Maven dependencies
We need to add below dependencies where monitor starter stream dependency is added to communicate with rabbit mq and config monitor is added to receive notifications from git repository.<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-stream-rabbit</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-monitor</artifactId> </dependency>
Configuration changes
Add below properties in your application.properties or application.yml to enable the Spring cloud bus with RabbitMQ.spring: cloud: bus: enabled: true rabbitmq: host: localhost port: 5672 virtual-host: / username: guest password: guest
Webhook configuration using Github
A webhook need to be configured using Github so it can notify our Spring cloud config server for any changes committed to the configuration repository. We configure the webhook in Github by registering our /monitor endpoint of config server application and due to this we should have public IP instead of localhost. See in next section how to refresh for localhost manually.Refer the below screenshot for webhook configuration.
Manual refresh using /monitor endpoint
In case we don't have a public IP for our host where cloud config server application is running, we can auto refresh all the connected applications by hitting only one URL manually on cloud config server application.Monitoring URL: http://localhost:8888/monitor
Please note that to access above URL you have to make a POST request with below headers and request body.
Headers:
Content-Type: application/json X-Event-Key: repo:push X-Hook-UUID: webhook-uuidRequest body:
{"push": {"changes": []}}While executing above request, you may face similar error as given below due to the default enablement of csrf in spring.
{ "timestamp": "2019-11-23T16:37:08.098+0000", "status": 403, "error": "Forbidden", "message": "Forbidden", "path": "/monitor" }To fix this issue we need to disable the csrf by creating below class.
@Configuration @EnableWebSecurity public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable(); } }
Config Test Service (Config client)
Now we will create a client application which will access the properties using cloud config server and refresh them without restarting it.Maven Dependencies
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</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-actuator</artifactId> </dependency>
bootstrap.yml
Add below properties to bootstrap properties or yml file.spring: profiles: active: DEV cloud: config: name: microservices-config uri: http://localhost:8888/ username: config_user password: config_user rabbitmq: host: localhost port: 5672 virtual-host: / username: guest password: guest
PropertiesController.java
This class uses property key "message" which we will test with refresh event. We have used RefreshScope annotation on this class so it can be refreshed with all the message properties in this class.@RefreshScope @RestController public class PropertiesController { @Value("${message}") private String message; @RequestMapping(value = "/test", method = RequestMethod.GET) public String testMessage(){ return message; } }
Testing the application
Below are the steps to test the application.- Download the code for "Cloud config server" from below GIT location and execute below command in root directory of application Git URL: https://github.com/thetechnojournals/microservices/tree/master/Cloud-config
- Download the config client from below GIT location and run using given command. Git URL: https://github.com/thetechnojournals/microservices/tree/master/ConfigClientTest
- Hit the URL (http://localhost:8080/test) in browser to test the client application and you will see below message which is configured currently in your properties file.
Run command: clean spring-boot:run
Run command: clean spring-boot:run
Welcome to Dev env...!!!
Welcome to Dev environment...!!!
Other posts you may like
Microservice development using Spring bootSpring cloud API gateway tutorial
Registry/ discovery server using Spring boot and Eureka
Comments
Post a Comment