pull/623/head
weihubeats 2 years ago committed by GitHub
parent a655b1dad4
commit 2813f7260c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -56,6 +56,14 @@
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency>
<groupId>io.etcd</groupId>
<artifactId>jetcd-core</artifactId>
<version>${jetcd.version}</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId> <artifactId>spring-boot-configuration-processor</artifactId>

@ -17,14 +17,15 @@
package cn.hippo4j.core.springboot.starter.config; package cn.hippo4j.core.springboot.starter.config;
import java.util.List;
import java.util.Map;
import cn.hippo4j.core.config.BootstrapPropertiesInterface; import cn.hippo4j.core.config.BootstrapPropertiesInterface;
import cn.hippo4j.core.springboot.starter.parser.ConfigFileTypeEnum; import cn.hippo4j.core.springboot.starter.parser.ConfigFileTypeEnum;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.List; import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.Map;
/** /**
* Bootstrap core properties. * Bootstrap core properties.
@ -86,6 +87,11 @@ public class BootstrapConfigProperties implements BootstrapPropertiesInterface {
*/ */
private Map<String, String> zookeeper; private Map<String, String> zookeeper;
/**
* etcd config
*/
private Map<String, String> etcd;
/** /**
* Tomcat thread pool config. * Tomcat thread pool config.
*/ */

@ -21,8 +21,10 @@ import cn.hippo4j.core.springboot.starter.refresher.ApolloRefresherHandler;
import cn.hippo4j.core.springboot.starter.refresher.NacosCloudRefresherHandler; import cn.hippo4j.core.springboot.starter.refresher.NacosCloudRefresherHandler;
import cn.hippo4j.core.springboot.starter.refresher.NacosRefresherHandler; import cn.hippo4j.core.springboot.starter.refresher.NacosRefresherHandler;
import cn.hippo4j.core.springboot.starter.refresher.ZookeeperRefresherHandler; import cn.hippo4j.core.springboot.starter.refresher.ZookeeperRefresherHandler;
import cn.hippo4j.core.springboot.starter.refresher.EtcdRefresherHandler;
import com.alibaba.cloud.nacos.NacosConfigManager; import com.alibaba.cloud.nacos.NacosConfigManager;
import com.alibaba.nacos.api.config.ConfigService; import com.alibaba.nacos.api.config.ConfigService;
import io.etcd.jetcd.Client;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFramework;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
@ -45,6 +47,8 @@ public class ConfigHandlerConfiguration {
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 = "endpoints";
@RequiredArgsConstructor @RequiredArgsConstructor
@ConditionalOnClass(ConfigService.class) @ConditionalOnClass(ConfigService.class)
@ConditionalOnMissingClass(NACOS_CONFIG_MANAGER_KEY) @ConditionalOnMissingClass(NACOS_CONFIG_MANAGER_KEY)
@ -88,4 +92,16 @@ public class ConfigHandlerConfiguration {
return new ZookeeperRefresherHandler(); return new ZookeeperRefresherHandler();
} }
} }
@ConditionalOnClass(Client.class)
@ConditionalOnProperty(prefix = BootstrapConfigProperties.PREFIX, name = ETCD)
static class EmbeddedEtcd {
@Bean
public EtcdRefresherHandler etcdRefresher() {
return new EtcdRefresherHandler();
}
}
} }

@ -0,0 +1,105 @@
package cn.hippo4j.core.springboot.starter.refresher;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Objects;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.common.toolkit.StringUtil;
import io.etcd.jetcd.ByteSequence;
import io.etcd.jetcd.Client;
import io.etcd.jetcd.ClientBuilder;
import io.etcd.jetcd.KeyValue;
import io.etcd.jetcd.Watch;
import io.etcd.jetcd.watch.WatchEvent;
import io.etcd.jetcd.watch.WatchResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
*@author : wh
*@date : 2022/8/30 17:59
*@description:
*/
@Slf4j
public class EtcdRefresherHandler extends AbstractCoreThreadPoolDynamicRefresh implements ApplicationContextAware {
private ApplicationContext applicationContext;
private Client client;
private static final String ENDPOINTS = "endpoints";
private static final String USER = "user";
private static final String PASSWORD = "password";
private static final String CHARSET = "charset";
private static final String AUTHORITY = "authority";
private static final String KEY = "key";
@Override
public void afterPropertiesSet() throws Exception {
Map<String, String> etcd = bootstrapConfigProperties.getEtcd();
String user = etcd.get(USER);
String password = etcd.get(PASSWORD);
String endpoints = etcd.get(ENDPOINTS);
String authority = etcd.get(AUTHORITY);
String key = etcd.get(KEY);
Charset charset = StringUtil.isBlank(etcd.get(CHARSET)) ? StandardCharsets.UTF_8 : Charset.forName(etcd.get(CHARSET));
ClientBuilder clientBuilder = Client.builder().endpoints(endpoints.split(","));
client = applicationContext.getBean(Client.class);
if (Objects.isNull(client)) {
client = StringUtil.isAllNotEmpty(user, password) ? clientBuilder.user(ByteSequence.from(user, charset))
.password(ByteSequence.from(password, charset)).authority(authority)
.build() : clientBuilder.build();
}
// todo Currently only supports json
KeyValue keyValue = client.getKVClient().get(ByteSequence.from(key, charset)).get().getKvs().get(0);
if (Objects.isNull(keyValue)) {
return;
}
client.getWatchClient().watch(ByteSequence.from(key, charset), new Watch.Listener() {
@Override
public void onNext(WatchResponse response) {
WatchEvent watchEvent = response.getEvents().get(0);
WatchEvent.EventType eventType = watchEvent.getEventType();
// todo Currently only supports json
if (Objects.equals(eventType, WatchEvent.EventType.PUT)) {
KeyValue keyValue1 = watchEvent.getKeyValue();
String value = keyValue1.getValue().toString(charset);
Map map = JSONUtil.parseObject(value, Map.class);
dynamicRefresh(keyValue1.getKey().toString(charset), map);
}
}
@Override
public void onError(Throwable throwable) {
log.error("dynamic thread pool etcd config watcher exception ", throwable);
}
@Override
public void onCompleted() {
log.info("dynamic thread pool etcd config key refreshed, config key {}", key);
}
});
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}

@ -49,6 +49,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>
<jetcd.version>0.7.3</jetcd.version>
<rocketmq.version>2.2.2</rocketmq.version> <rocketmq.version>2.2.2</rocketmq.version>
<netty.version>4.1.56.Final</netty.version> <netty.version>4.1.56.Final</netty.version>
<tomcat-embed-core.version>9.0.55</tomcat-embed-core.version> <tomcat-embed-core.version>9.0.55</tomcat-embed-core.version>

Loading…
Cancel
Save