Merge pull request #3 from yangjuanying/hoxton

Hoxton
pull/1095/head
melodyl 2 years ago committed by GitHub
commit 7acfa1c6cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -35,15 +35,13 @@ import org.springframework.lang.NonNull;
import org.springframework.util.CollectionUtils;
/**
* 1. Listen to the Polaris server configuration publishing event 2. Write the changed
* configuration content to propertySource 3. Refresh the context through contextRefresher
*
* @author lepdou 2022-03-28
*/
public abstract class PolarisConfigPropertyAutoRefresher
implements ApplicationListener<ApplicationReadyEvent>, PolarisConfigPropertyRefresher {
public abstract class PolarisConfigPropertyAutoRefresher implements ApplicationListener<ApplicationReadyEvent>, PolarisConfigPropertyRefresher {
private static final Logger LOGGER = LoggerFactory.getLogger(PolarisConfigPropertyAutoRefresher.class);
@ -53,9 +51,7 @@ public abstract class PolarisConfigPropertyAutoRefresher
private final AtomicBoolean registered = new AtomicBoolean(false);
public PolarisConfigPropertyAutoRefresher(
PolarisConfigProperties polarisConfigProperties,
PolarisPropertySourceManager polarisPropertySourceManager) {
public PolarisConfigPropertyAutoRefresher(PolarisConfigProperties polarisConfigProperties, PolarisPropertySourceManager polarisPropertySourceManager) {
this.polarisConfigProperties = polarisConfigProperties;
this.polarisPropertySourceManager = polarisPropertySourceManager;
}
@ -80,22 +76,40 @@ public abstract class PolarisConfigPropertyAutoRefresher
}
// register polaris config publish event
registerPolarisConfigPublishChangeListener(polarisPropertySources);
// 增加接收刷新事件接收到事件以后就进行全量配置刷新重新加载PolarisConfigFileLocator同时添加Listener事件
new Thread(new Runnable() {
@Override
public void run() {
for (; ; ) {
try {
List<PolarisPropertySource> polarisPropertySourcesList = PolarisContextRefreshUtil.getRegisterPolarisPropertySourceQueue()
.take();
LOGGER.info("[SCT Config] receive from register queue And start refresh All Config, polarisPropertySourcesList size:{}", polarisPropertySourcesList.size());
refreshConfigurationProperties(null);
LOGGER.info("[SCT Config] start to register configFile polarisPropertySourcesList:{}", polarisPropertySourcesList);
registerPolarisConfigPublishChangeListener(polarisPropertySourcesList);
}
catch (Exception e) {
LOGGER.error("[SCT Config] receive from register queue exception:", e);
}
}
}
}).start();
}
private void registerPolarisConfigPublishChangeListener(List<PolarisPropertySource> polarisPropertySources) {
for (PolarisPropertySource polarisPropertySource : polarisPropertySources) {
polarisPropertySource.getConfigKVFile()
.addChangeListener((ConfigKVFileChangeListener) configKVFileChangeEvent -> {
ConfigKVFileChangeListener configKVFileChangeListener = configKVFileChangeEvent -> {
LOGGER.info(
"[SCT Config] received polaris config change event and will refresh spring context."
+ " namespace = {}, group = {}, fileName = {}",
polarisPropertySource.getNamespace(),
polarisPropertySource.getGroup(),
polarisPropertySource.getFileName());
LOGGER.info("[SCT Config] received polaris config change event and will refresh spring context." + " namespace = {}, group = {}, fileName = {}", polarisPropertySource.getNamespace(), polarisPropertySource.getGroup(), polarisPropertySource.getFileName());
Map<String, Object> source = polarisPropertySource.getSource();
for (String changedKey : configKVFileChangeEvent.changedKeys()) {
ConfigPropertyChangeInfo configPropertyChangeInfo = configKVFileChangeEvent
.getChangeInfo(changedKey);
ConfigPropertyChangeInfo configPropertyChangeInfo = configKVFileChangeEvent.getChangeInfo(changedKey);
LOGGER.info("[SCT Config] changed property = {}", configPropertyChangeInfo);
@ -103,7 +117,7 @@ public abstract class PolarisConfigPropertyAutoRefresher
try {
if (changedKey.startsWith("logging.level") && changedKey.length() >= 14) {
String loggerName = changedKey.substring(14);
String newValue = configPropertyChangeInfo.getNewValue();
String newValue = (String) configPropertyChangeInfo.getNewValue();
LOGGER.info("[SCT Config] set logging.level loggerName:{}, newValue:{}", loggerName, newValue);
PolarisConfigLoggerContext.setLevel(loggerName, newValue);
}
@ -125,7 +139,12 @@ public abstract class PolarisConfigPropertyAutoRefresher
}
// update @ConfigurationProperties beans
refreshConfigurationProperties(configKVFileChangeEvent.changedKeys());
});
};
polarisPropertySource.getConfigKVFile().addChangeListener(configKVFileChangeListener);
// 保存最近添加的ChangeListener
PolarisContextRefreshUtil.getLastPolarisPropertyConfigKVFileMap()
.put(polarisPropertySource, configKVFileChangeListener);
}
}
}

@ -0,0 +1,47 @@
/*
* Copyright (c) 2023 www.tencent.com.
* All Rights Reserved.
* This program is the confidential and proprietary information of
* www.tencent.com ("Confidential Information"). You shall not disclose such
* Confidential Information and shall use it only in accordance with
* the terms of the license agreement you entered into with www.tencent.com.
*/
package com.tencent.cloud.polaris.config.adapter;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.LinkedBlockingQueue;
import com.alibaba.nacos.common.utils.ConcurrentHashSet;
import com.tencent.polaris.configuration.api.core.ConfigKVFileChangeListener;
/**
* @author juanyinyang
*/
public final class PolarisContextRefreshUtil {
// 最近一次的全量PolarisPropertySource集合PolarisPropertySource按 namespace + fileGroup + fileName 确保唯一)
private static final Map<PolarisPropertySource, ConfigKVFileChangeListener> lastPolarisPropertyConfigKVFileMap = new LinkedHashMap<>();
// 命名空间分组namespace + fileGroup的去重Set集合如果这个分组已添加了ConfigFileGroupListener
private static final Set<String> existConfigFileGroupListenerSet = new ConcurrentHashSet<>();
// Queue里存放的是需要添加的配置列表集合这类配置需要重新注册Listener
private static final LinkedBlockingQueue<List<PolarisPropertySource>> registerPolarisPropertySourceQueue = new LinkedBlockingQueue<>(100);
private PolarisContextRefreshUtil() {
}
public static Map<PolarisPropertySource, ConfigKVFileChangeListener> getLastPolarisPropertyConfigKVFileMap() {
return lastPolarisPropertyConfigKVFileMap;
}
public static Set<String> getExistConfigFileGroupListenerSet() {
return existConfigFileGroupListenerSet;
}
public static LinkedBlockingQueue<List<PolarisPropertySource>> getRegisterPolarisPropertySourceQueue() {
return registerPolarisPropertySourceQueue;
}
}

@ -19,11 +19,13 @@
package com.tencent.cloud.polaris.config.adapter;
import java.util.Map;
import java.util.Objects;
import com.tencent.polaris.configuration.api.core.ConfigKVFile;
import org.springframework.core.env.MapPropertySource;
/**
* a polaris config file will be wrapped as polaris property source.
*
@ -39,8 +41,7 @@ public class PolarisPropertySource extends MapPropertySource {
private final ConfigKVFile configKVFile;
public PolarisPropertySource(String namespace, String group, String fileName,
ConfigKVFile configKVFile, Map<String, Object> source) {
public PolarisPropertySource(String namespace, String group, String fileName, ConfigKVFile configKVFile, Map<String, Object> source) {
super(namespace + "-" + group + "-" + fileName, source);
this.namespace = namespace;
@ -69,9 +70,31 @@ public class PolarisPropertySource extends MapPropertySource {
return configKVFile;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + Objects.hash(fileName, group, namespace);
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
PolarisPropertySource other = (PolarisPropertySource) obj;
return Objects.equals(fileName, other.fileName) && Objects.equals(group, other.group) && Objects.equals(namespace, other.namespace);
}
@Override
public String toString() {
return "PolarisPropertySource{" + "namespace='" + namespace + '\'' + ", group='"
+ group + '\'' + ", fileName='" + fileName + '\'' + '}';
return "PolarisPropertySource{" + "namespace='" + namespace + '\'' + ", group='" + group + '\'' + ", fileName='" + fileName + '\'' + '}';
}
}

@ -18,16 +18,14 @@
package com.tencent.cloud.polaris.config.listener;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.DEFINED_PORT;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import com.google.common.collect.Sets;
import com.tencent.cloud.polaris.config.annotation.PolarisConfigKVFileChangeListener;
import com.tencent.polaris.configuration.api.core.ConfigPropertyChangeInfo;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@ -38,7 +36,9 @@ import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.DEFINED_PORT;
import com.google.common.collect.Sets;
import com.tencent.cloud.polaris.config.annotation.PolarisConfigKVFileChangeListener;
import com.tencent.polaris.configuration.api.core.ConfigPropertyChangeInfo;
/**
* Integration testing for change listener.
@ -104,7 +104,7 @@ public class ConfigChangeListenerTest {
@PolarisConfigKVFileChangeListener(interestedKeys = {"timeout"})
public void configChangedListener(ConfigChangeEvent event) {
ConfigPropertyChangeInfo changeInfo = event.getChange("timeout");
timeout = Integer.parseInt(changeInfo.getNewValue());
timeout = Integer.parseInt((String)changeInfo.getNewValue());
changeCnt++;
hits.countDown();
}
@ -112,7 +112,7 @@ public class ConfigChangeListenerTest {
@PolarisConfigKVFileChangeListener(interestedKeyPrefixes = {"timeout"})
public void configChangedListener2(ConfigChangeEvent event) {
ConfigPropertyChangeInfo changeInfo = event.getChange("timeout");
timeout = Integer.parseInt(changeInfo.getNewValue());
timeout = Integer.parseInt((String)changeInfo.getNewValue());
changeCnt++;
hits.countDown();
}

Loading…
Cancel
Save