Support for Consul Configuration Center to dynamically adjust parameters (#1007)

* Support for Consul Configuration Center to dynamically adjust parameters

* Optimize(Support for Consul Configuration Center to dynamically adjust parameters )

* Second optimization(Support for Consul Configuration Center to dynamically adjust parameters )

* delete empty rows
pull/1011/head
Lijx 3 years ago committed by GitHub
parent bc38a19cb8
commit 89dbafe5c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,45 @@
<?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>cn.hippo4j</groupId>
<artifactId>hippo4j-example</artifactId>
<version>${revision}</version>
</parent>
<artifactId>hippo4j-config-consul-spring-boot-starter-example</artifactId>
<properties>
<maven.deploy.skip>true</maven.deploy.skip>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-example-core</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.hippo4j</groupId>
<artifactId>hippo4j-config-spring-boot-starter</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-config</artifactId>
<version>${consul.version}</version>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
</project>

@ -0,0 +1,31 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.example.config.consul;
import cn.hippo4j.core.enable.EnableDynamicThreadPool;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@EnableDynamicThreadPool
@SpringBootApplication(scanBasePackages = "cn.hippo4j.example")
public class ConfigConsulExampleApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigConsulExampleApplication.class, args);
}
}

@ -0,0 +1,18 @@
server:
port: 8091
spring:
application:
name: hippo4j-config-consul-spring-boot-starter-example
profiles:
active: dev
cloud:
consul:
host: 127.0.0.1
port: 8500
config:
enabled: true
format: yaml
data-key: hippo4j-consul
default-context: application
prefix: config

@ -21,6 +21,7 @@
<module>hippo4j-config-nacos-spring-boot-starter-example</module> <module>hippo4j-config-nacos-spring-boot-starter-example</module>
<module>hippo4j-config-apollo-spring-boot-starter-example</module> <module>hippo4j-config-apollo-spring-boot-starter-example</module>
<module>hippo4j-config-zookeeper-spring-boot-starter-example</module> <module>hippo4j-config-zookeeper-spring-boot-starter-example</module>
<module>hippo4j-config-consul-spring-boot-starter-example</module>
<module>hippo4j-spring-boot-starter-adapter-rabbitmq-example</module> <module>hippo4j-spring-boot-starter-adapter-rabbitmq-example</module>
<module>hippo4j-spring-boot-starter-adapter-spring-cloud-stream-rabbitmq-example</module> <module>hippo4j-spring-boot-starter-adapter-spring-cloud-stream-rabbitmq-example</module>
<module>hippo4j-spring-boot-starter-adapter-spring-cloud-stream-rocketmq-example</module> <module>hippo4j-spring-boot-starter-adapter-spring-cloud-stream-rocketmq-example</module>

@ -47,6 +47,13 @@
<version>${apollo.version}</version> <version>${apollo.version}</version>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-config</artifactId>
<version>${consul.version}</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency> <dependency>
<groupId>org.apache.curator</groupId> <groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId> <artifactId>curator-framework</artifactId>

@ -30,6 +30,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.consul.config.ConsulConfigProperties;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -45,6 +46,8 @@ public class ConfigHandlerConfiguration {
private static final String APOLLO_NAMESPACE_KEY = "apollo.namespace"; private static final String APOLLO_NAMESPACE_KEY = "apollo.namespace";
private static final String CONSUL_DATA_KEY = "consul.data-key";
private static final String ZOOKEEPER_CONNECT_STR_KEY = "zookeeper.zk-connect-str"; private static final String ZOOKEEPER_CONNECT_STR_KEY = "zookeeper.zk-connect-str";
private static final String ETCD = "etcd.endpoints"; private static final String ETCD = "etcd.endpoints";
@ -89,6 +92,16 @@ public class ConfigHandlerConfiguration {
} }
} }
@ConditionalOnClass(ConsulConfigProperties.class)
@ConditionalOnProperty(prefix = BootstrapConfigProperties.PREFIX, name = CONSUL_DATA_KEY)
static class EmbeddedConsul {
@Bean
public ConsulRefresherHandler consulRefresher() {
return new ConsulRefresherHandler();
}
}
@ConditionalOnClass(CuratorFramework.class) @ConditionalOnClass(CuratorFramework.class)
@ConditionalOnProperty(prefix = BootstrapConfigProperties.PREFIX, name = ZOOKEEPER_CONNECT_STR_KEY) @ConditionalOnProperty(prefix = BootstrapConfigProperties.PREFIX, name = ZOOKEEPER_CONNECT_STR_KEY)
static class EmbeddedZookeeper { static class EmbeddedZookeeper {

@ -0,0 +1,86 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.config.springboot.starter.refresher;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.boot.env.OriginTrackedMapPropertySource;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.cloud.bootstrap.config.BootstrapPropertySource;
import org.springframework.cloud.consul.config.ConsulPropertySource;
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
import org.springframework.context.event.EventListener;
import org.springframework.core.env.AbstractEnvironment;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* Consul refresher handler.
*/
@Slf4j
public class ConsulRefresherHandler extends AbstractConfigThreadPoolDynamicRefresh {
@EventListener(EnvironmentChangeEvent.class)
public void refreshed(EnvironmentChangeEvent event) {
Map<String, Object> configInfo = extractLatestConfigInfo(event);
dynamicRefresh(StringUtils.EMPTY, configInfo);
}
private Map<String, Object> extractLatestConfigInfo(EnvironmentChangeEvent event) {
AbstractEnvironment environment = (AbstractEnvironment) ((AnnotationConfigServletWebServerApplicationContext) event.getSource()).getEnvironment();
String activeProfile = Optional.ofNullable(environment.getActiveProfiles().length > 0 ? environment.getActiveProfiles()[0] : null)
.orElseGet(() -> String.valueOf(getApplicationConfigDefaultContext(environment)));
List<BootstrapPropertySource<?>> bootstrapPropertySourceList = environment.getPropertySources().stream()
.filter(propertySource -> propertySource instanceof BootstrapPropertySource)
.map(propertySource -> (BootstrapPropertySource<?>) propertySource).collect(Collectors.toList());
Optional<BootstrapPropertySource<?>> bootstrapPropertySource = bootstrapPropertySourceList.stream()
.filter(source -> source.getName().contains(activeProfile) && source.getPropertyNames().length != 0).findFirst();
Map<String, Object> configInfo = new HashMap<>(64);
if (bootstrapPropertySource.isPresent()) {
ConsulPropertySource consulPropertySource = (ConsulPropertySource) bootstrapPropertySource.get().getDelegate();
String[] propertyNames = consulPropertySource.getPropertyNames();
for (String propertyName : propertyNames) {
configInfo.put(propertyName, consulPropertySource.getProperty(propertyName));
}
}
return configInfo;
}
private CharSequence getApplicationConfigDefaultContext(AbstractEnvironment environment) {
return environment.getPropertySources().stream()
.filter(propertySource -> propertySource instanceof OriginTrackedMapPropertySource)
.map(propertySource -> ((Map<String, CharSequence>) propertySource.getSource()).get("spring.cloud.consul.config.default-context"))
.findFirst().orElse(StringUtils.EMPTY);
}
/**
* TODO consul
* @return
*/
@Override
public String getProperties() {
return null;
}
@Override
public void afterPropertiesSet() {}
}

@ -61,6 +61,7 @@
<mybatis-plus.version>3.4.2</mybatis-plus.version> <mybatis-plus.version>3.4.2</mybatis-plus.version>
<spring-boot.version>2.3.2.RELEASE</spring-boot.version> <spring-boot.version>2.3.2.RELEASE</spring-boot.version>
<apollo.version>1.9.1</apollo.version> <apollo.version>1.9.1</apollo.version>
<consul.version>2.2.4.RELEASE</consul.version>
<jetcd.version>0.7.3</jetcd.version> <jetcd.version>0.7.3</jetcd.version>
<polaris.version>1.7.2</polaris.version> <polaris.version>1.7.2</polaris.version>
<rocketmq.version>2.2.2</rocketmq.version> <rocketmq.version>2.2.2</rocketmq.version>

Loading…
Cancel
Save