Spring Cloud Config program example

Keywords: Spring RabbitMQ github git

Catalog

Spring Cloud Config server example

Spring Cloud Config client example

Spring Cloud Config user authentication

Configure information encryption

Symmetric encryption

Asymmetric encryption

Configuration refresh

Manual refresh

auto refresh

Spring Cloud Config client sends update notification

Spring Cloud Config server sends update notification

Spring Cloud Config integrates Eureka

Eureka server

Modify the Spring Cloud Config server

Modify the Spring Cloud Config client

Java version: 1.8

Spring version: 5.1.8.RELEASE

Spring Boot version: 2.1.6.RELEASE

Spring Cloud version: Greenwich.SR1

Spring Cloud Config server example

Add spring cloud config server dependency in pom file

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.6.RELEASE</version>
		<relativePath/>
	</parent>
	<groupId>com.sean</groupId>
	<artifactId>config-server</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>config-server</name>
	<description>config-server</description>

	<properties>
		<java.version>1.8</java.version>
		<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-config-server</artifactId>
		</dependency>
	</dependencies>

	<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>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

Start the Spring Cloud Config service in the startup class settings

package com.sean;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;

@EnableConfigServer
@SpringBootApplication
public class ConfigServerApplication {
	public static void main(String[] args) {
		SpringApplication.run(ConfigServerApplication.class, args);
	}
}

Log in to your github account, create a config warehouse, and create a test branch for the warehouse. Create the following files under the branch

The configuration content of the Spring Cloud configuration file application.properties is as follows

server.port=8080
spring.application.name=config-server

spring.cloud.config.server.git.uri=https://github.com/seanzou88/config
spring.cloud.config.server.git.username=******
spring.cloud.config.server.git.password=******

After the program starts, access http://localhost:8080/config-server/online/test (/ {application name} / {profile} [/ {label}], where label represents branch name and master branch is not filled in by default) you can get configuration details

In particular, the URL in this file cannot be accessed directly. It is only used as an identifier

Visit http://localhost:8080/test/config-server-online.properties ([/ {label}] / {application name} - {profile}. Properties, where label represents branch name, and master branch is not filled in by default) get specific environment configuration information

In the Spring Cloud configuration file application.properties, you can also use the fuzzy matching method to set the github library

server.port=8080
spring.application.name=config-server

#Default configuration
spring.cloud.config.server.git.uri=https://github.com/seanzou88/test
#The request path contains config, which will be used
spring.cloud.config.server.git.repos.rule1.pattern=*config*
spring.cloud.config.server.git.repos.rule1.uri=https://github.com/seanzou88/config
#By default, when the request is initiated, the git library will be checked and called
#Set the configuration change to true, and the git library configuration will be checked after the project is started
spring.cloud.config.server.git.repos.rule1.cloneOnStart=true
spring.cloud.config.server.git.username=******
spring.cloud.config.server.git.password=******

Spring Cloud Config client example

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.6.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.sean</groupId>
	<artifactId>config-client</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>config-client</name>
	<description>config-client</description>

	<properties>
		<java.version>1.8</java.version>
		<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-config</artifactId>
		</dependency>
	</dependencies>

	<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>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>
package com.sean;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ConfigClientApplication {
	public static void main(String[] args) {
		SpringApplication.run(ConfigClientApplication.class, args);
	}
}

The configuration content of the Spring Cloud configuration file application.properties is as follows

server.port=8081

Spring The configuration content of cloud boot configuration file bootstrap.properties is as follows. The configuration file specifies where to obtain configuration information (the priority of configuration content in the configuration file is higher than application.properties. If you move the following configuration content to application.properties, the configuration will not take effect. The project will use the default configuration of bootstrap.properties to find configuration information

Where http://localhost:8888 is the default address of the Spring Cloud Config server)

spring.application.name=config-server

spring.cloud.config.uri=http://localhost:8080
spring.cloud.config.profile=online
spring.cloud.config.label=test

The server configuration URL corresponding to this configuration is http://localhost:8080/test/config-server-online.properties

Create a Controller class to verify whether the Spring Cloud Config client can obtain configuration information from the server

package com.sean;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Created by sean on 2020/2/16.
 */
@RestController
public class Controller {
    @Value("${env}")
    private String env;
    @Value("${desc}")
    private String desc;

    @GetMapping("/env")
    public String getEnv(){
        return env;
    }

    @GetMapping("/desc")
    public String getDesc(){
        return desc;
    }
}

After project launch, visit http://localhost:8081/env online access http://localhost:8081/desc You can get this is main config file

Spring Cloud Config user authentication

From the previous example, we can see that we can get configuration information from the Spring Cloud Config server by sending http requests, which is undoubtedly very dangerous. If the server address is leaked, it will cause very serious consequences. We can avoid this situation by adding user authentication

Update Spring Cloud Config server code

Modify pom file and add spring boot starter security dependency (form authentication is enabled by default at this time)

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-security</artifactId>
</dependency>

Modify the Spring Cloud configuration file application.properties and add the following

#If you do not specify a user name and password, the default user name, user, is used and a random password is generated at system startup
spring.security.user.name=sean
spring.security.user.password=123

Now we visit http://localhost:8080/test/config-server-online.properties , you need to enter the user name and password before you can jump to the target URL

Update Spring Cloud Config client code

Modify the Spring Cloud boot configuration file bootstrap.properties and add the following

spring.cloud.config.username=sean
spring.cloud.config.password=123

Configure information encryption

There are some restrictions on JCE provided by JDK. We download unlimited version to replace JCE provided by JDK. Because we use JDK 1.8, the corresponding download address is: http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html

After downloading, replace the jar package in the path {JAVA_HOME}/jre/lib/security with the jar package in the compressed package

Symmetric encryption

Modify the Spring Cloud Config server code

Add the Spring Cloud boot configuration file bootstrap.properties, as follows

#Symmetric encryption key
encrypt.key=******

Then we use the / encrypt node provided by Spring Cloud Config to encrypt the plaintext

C:\Users\sean>curl http://localhost:8080/encrypt -d online
5d04f58d03844e506659e2160bf063bccea76a0c1cd0c5b77cc5625072c08d30

Let's modify the config-server-online.properties under the test branch of the config project on github, replace the previous clear text with the encrypted content, and add the {cipher} ID before encrypting the content

env={cipher}5d04f58d03844e506659e2160bf063bccea76a0c1cd0c5b77cc5625072c08d30

Visit http://localhost:8080/test/config-server-online.properties , we can find that the encrypted content will be automatically decrypted

Asymmetric encryption

Use the keytool tool provided with JDK to generate the key

C:\Users\sean>D:\Java\jdk1.8.0_121\bin\keytool -genkeypair -alias testkey -keyalg rsa -keystore server.jks

Put the generated server.jks under the Spring Cloud Config server project resource path

Modify the Spring Cloud boot configuration file bootstrap.properties as follows

#Asymmetric encryption key
encrypt.key-store.location=classpath:server.jks
encrypt.key-store.password=123456
encrypt.key-store.secret=123456
encrypt.key-store.alias=testkey

Then we use the / encrypt node provided by Spring Cloud Config to encrypt the plaintext

C:\Users\sean>curl http://localhost:8080/encrypt -d online
AQA6d52vfbCRe9D2hr2XA0Xu9OFxCc586eTp9aLjCL+/7CjBk1RpFn5m5il/p0C1DcKkz6fvwZHopuNLe1Ku33qD43oh+1zSecVu1T0X/ygPza02DfUwaKxCrz0iPuVtvPAXX+02f2+V0Yn+FXW5tGgGRJuAj3witOVwRmChqdjImq8oKCdqtQDOJrCNLziLkIBmLzhnDu14PlKkoVka+zpYqy6d0bKBugfymkuU0V8IOIQZyQacePLgCNy/0qiVI6vb7oTTS4pv4JDkcatnqYxJ9t/k8EoJM4Hp/jOXf0Zj6nD/9hMfzEc8if+02iQiZQnv659QI4t9Gts2Gm2XdFxTwLDOjb/Rc9Q+7KM/OI79G7ZAZpdiBrbWvE2q8eeHJPk=

The remaining steps are the same as symmetric encryption

Configuration refresh

Manual refresh

Modify the pom file of the Spring Cloud Config client and add the spring boot actor dependency

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

Modify the Spring Cloud configuration file application.properties and open the refresh node of the actor

management.endpoints.web.exposure.include=refresh

Add RefreshScope annotation on the controller so that we can manually refresh the configuration information obtained from the server by the Spring Cloud Config client using the refresh node provided by the actor

package com.sean;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Created by sean on 2020/2/16.
 */
@RefreshScope
@RestController
public class Controller {
    @Value("${env}")
    private String env;
    @Value("${desc}")
    private String desc;

    @GetMapping("/env")
    public String getEnv(){
        return env;
    }

    @GetMapping("/desc")
    public String getDesc(){
        return desc;
    }
}

Then we test. We modify config-server.properties under the test branch of the config project on github, and replace its content with desc=update

Visit http://localhost:8081/desc , the returned result is still this is main config file

Refresh the configuration using the refresh node provided by the actor

C:\Users\sean>curl -v -X POST "http://localhost:8081/actuator/refresh"
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8081 (#0)
> POST /actuator/refresh HTTP/1.1
> Host: localhost:8081
> User-Agent: curl/7.55.1
> Accept: */*
>
< HTTP/1.1 200
< Content-Type: application/vnd.spring-boot.actuator.v2+json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Mon, 17 Feb 2020 02:54:47 GMT
<
["config.client.version","desc"]* Connection #0 to host localhost left intact

The system log is as follows

2020-02-17 10:54:41.385  INFO 11272 --- [nio-8081-exec-4] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$1dd09c4c] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-02-17 10:54:43.011  INFO 11272 --- [nio-8081-exec-4] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at : http://localhost:8080
2020-02-17 10:54:47.309  INFO 11272 --- [nio-8081-exec-4] c.c.c.ConfigServicePropertySourceLocator : Located environment: name=config-server, profiles=[online], label=test, version=1f2955ac5f16256d1a394240c2ad34e45bb6eea6, state=null
2020-02-17 10:54:47.310  INFO 11272 --- [nio-8081-exec-4] b.c.PropertySourceBootstrapConfiguration : Located property source: CompositePropertySource {name='configService', propertySources=[MapPropertySource {name='configClient'}, MapPropertySource {name='https://github.com/seanzou88/config/config-server-online.properties'}, MapPropertySource {name='https://github.com/seanzou88/config/config-server.properties'}]}
2020-02-17 10:54:47.311  INFO 11272 --- [nio-8081-exec-4] o.s.boot.SpringApplication               : No active profile set, falling back to default profiles: default
2020-02-17 10:54:47.316  INFO 11272 --- [nio-8081-exec-4] o.s.boot.SpringApplication               : Started application in 7.571 seconds (JVM running for 616.389)

Access at this time http://localhost:8081/desc , the returned result changes to update

auto refresh

We need to use Spring Cloud Bus here. Because Spring Cloud Bus only supports RabbitMQ and Kafka, we choose RabbitMQ here

Start the local RabbitMQ service

Spring Cloud Config client sends update notification

Modify the pom file of the Spring Cloud Config client and add the spring cloud starter bus AMQP dependency

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-bus-amqp</artifactId>
	<version>2.1.2.RELEASE</version>
</dependency>

Modify the Spring Cloud boot configuration file bootstrap.properties and add the following

spring.rabbitmq.host=localhost
#RabbitMQ default port
spring.rabbitmq.port=5672
#RabbitMQ creates account by default
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest

Modify the Spring Cloud configuration file application.properties and open the bus refresh node of the actor

management.endpoints.web.exposure.include=bus-refresh

Copy the current config client project to create a new project config client1, and change the service port of config client1 to 8082

Then we test. We modify config-server.properties under the test branch of the config project on github, and replace its content with desc=client update

Visit http://localhost:8081/desc and http://localhost:8082/desc , the returned result is still update

Use the bus refresh node provided by the actor to refresh the configuration

C:\Users\sean>curl -v -X POST "http://localhost:8081/actuator/bus-refresh"
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8081 (#0)
> POST /actuator/bus-refresh HTTP/1.1
> Host: localhost:8081
> User-Agent: curl/7.55.1
> Accept: */*
>
< HTTP/1.1 204
< Date: Wed, 19 Feb 2020 14:59:19 GMT
<
* Connection #0 to host localhost left intact

Access at this time http://localhost:8081/desc and http://localhost:8082/desc , the returned results are all changed to client update

Then we can add webhook on github's config warehouse to automatically call the bus refresh node of any Spring Cloud Config client to refresh the configuration after each code submission

The overall process of the project is as follows

Spring Cloud Config server sends update notification

Modify the pom file of the Spring Cloud Config server and add the spring cloud starter bus AMQP dependency

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-bus-amqp</artifactId>
	<version>2.1.2.RELEASE</version>
</dependency>

Modify the Spring Cloud boot configuration file bootstrap.properties and add the following

spring.rabbitmq.host=localhost
#RabbitMQ default port
spring.rabbitmq.port=5672
#RabbitMQ creates account by default
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest

Modify the Spring Cloud configuration file application.properties and open the bus refresh node of the actor

management.endpoints.web.exposure.include=bus-refresh

Since we have previously enabled user authentication for the Spring Cloud Config server, and the default user authentication method is login authentication, we cannot fill in login authentication in Postman or when we use curl to call the bus refresh node provided by the actor to refresh the configuration, so we need to set Http Basic authentication to be enabled

package com.sean;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

/**
 * Created by sean on 2020/2/28.
 */
@Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //At the same time, it supports login verification or httpbasic verification
        http.authorizeRequests().anyRequest().authenticated()
                .and()
                .formLogin()
                .and()
                .httpBasic();
        //Turn off cross station request forgery, otherwise the bus refresh node will still report 403 even if the login authentication or http basic authentication passes
        http.csrf().disable();
    }
}

Then we carry out a test. We modify the config-server.properties under the test branch of the config project on github, and replace the content with desc=server update

Visit http://localhost:8081/desc , the returned result is still client update

Use the bus refresh node provided by the actor to refresh the configuration

C:\Users\sean>curl -v -X POST "http://sean:123@localhost:8080/actuator/bus-refresh"
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
* Server auth using Basic with user 'sean'
> POST /actuator/bus-refresh HTTP/1.1
> Host: localhost:8080
> Authorization: Basic c2VhbjoxMjM=
> User-Agent: curl/7.55.1
> Accept: */*
>
< HTTP/1.1 204
< Set-Cookie: JSESSIONID=75FF9E8AD7D16955F4FC5E4944FD5DFA; Path=/; HttpOnly
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Date: Thu, 05 Mar 2020 01:51:40 GMT
<
* Connection #0 to host localhost left intact

Access at this time http://localhost:8081/desc and http://localhost:8082/desc , the returned results are all changed to server update

Similarly, we can add webhook on github's config warehouse to automatically call the Spring Cloud Config server's bus refresh node to refresh the configuration after each code submission

The overall process of the project is as follows

Spring Cloud Config integrates Eureka

In the current configuration, we have specified the Spring Cloud Config server address in the Spring Cloud Config client. When the address changes, we need to modify all the Spring Cloud Config client configurations, so it is necessary to integrate Eureka

Eureka server

Please refer to Eureka of Spring Cloud service discovery Eureka Server in

Modify the Spring Cloud Config server

Add Eureka related dependency in pom

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

Modify the Spring Cloud configuration file application.properties and register it with Eureka

eureka.client.service-url.defaultZone=http://localhost:8000/eureka

#Service priority use ip to register to eureka
eureka.instance.prefer-ip-address=true
# Service renewal task (sending heartbeat) execution interval, default 30s
eureka.instance.lease-renewal-interval-in-seconds=10
# Service expiration time, default 90s
eureka.instance.lease-expiration-duration-in-seconds=20 

Modify the Spring Cloud Config client

Add Eureka related dependency in pom

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

Modify the Spring Cloud boot configuration file bootstrap.properties, remove the previous Spring Cloud Config server address, and use Eureka service discovery instead

#spring.cloud.config.uri=http://localhost:8080
spring.cloud.config.username=sean
spring.cloud.config.password=123
eureka.client.service-url.defaultZone=http://sean:123@localhost:8000/eureka
spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.service-id=config-server

Then we test. We modify config-server.properties under the test branch of the config project on github, and replace its content with desc=eureka

Visit http://localhost:8081/desc , the returned result is still server update

Call the bus refresh node of the Spring Cloud Config server to refresh the configuration, and visit again http://localhost:8081/desc , the returned result changes to eureka

 

234 original articles published, 542 praised, 3.34 million visitors+
His message board follow

Posted by ffdave77 on Wed, 04 Mar 2020 19:39:44 -0800