重构代码,抽象出通用接口,把TSF定制化的代码移到SCTT里

pull/1095/head
yangjuanying 2 years ago
parent 35db409c0d
commit 0e29d9edf4

@ -21,6 +21,10 @@ import org.springframework.core.env.Environment;
* @author juanyinyang * @author juanyinyang
*/ */
public interface PolarisConfigCustomExtensionLayer { public interface PolarisConfigCustomExtensionLayer {
void execute(String namespace, Environment environment, CompositePropertySource compositePropertySource, PolarisPropertySourceManager polarisPropertySourceManager, ConfigFileService configFileService); void initRegisterConfig(PolarisConfigPropertyAutoRefresher polarisConfigPropertyAutoRefresher);
void initConfigFiles(String namespace, Environment environment, CompositePropertySource compositePropertySource, PolarisPropertySourceManager polarisPropertySourceManager, ConfigFileService configFileService);
void executeAfterLocateConfigReturning(CompositePropertySource compositePropertySource);
boolean executeRegisterPublishChangeListener(PolarisPropertySource polarisPropertySource);
} }

@ -20,17 +20,13 @@ package com.tencent.cloud.polaris.config.adapter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.ServiceLoader;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import com.tencent.cloud.polaris.config.config.ConfigFileGroup; import com.tencent.cloud.polaris.config.config.ConfigFileGroup;
import com.tencent.cloud.polaris.config.config.PolarisConfigProperties; import com.tencent.cloud.polaris.config.config.PolarisConfigProperties;
import com.tencent.cloud.polaris.config.config.cache.PolarisPropertyCache;
import com.tencent.cloud.polaris.config.enums.ConfigFileFormat; import com.tencent.cloud.polaris.config.enums.ConfigFileFormat;
import com.tencent.cloud.polaris.context.config.PolarisContextProperties; import com.tencent.cloud.polaris.context.config.PolarisContextProperties;
import com.tencent.polaris.configuration.api.core.ConfigFileMetadata; import com.tencent.polaris.configuration.api.core.ConfigFileMetadata;
@ -73,17 +69,7 @@ public class PolarisConfigFileLocator implements PropertySourceLocator {
private final Environment environment; private final Environment environment;
// 此类给一些客户定制化逻辑做一些特殊业务分组文件的配置处理 // 此类给一些客户定制化逻辑做一些特殊业务分组文件的配置处理
private PolarisConfigCustomExtensionLayer polarisConfigCustomExtensionLayer; private final PolarisConfigCustomExtensionLayer polarisConfigCustomExtensionLayer = PolarisServiceLoaderUtil.getPolarisConfigCustomExtensionLayer();
{
ServiceLoader<PolarisConfigCustomExtensionLayer> polarisConfigCustomExtensionLayerLoader = ServiceLoader.load(PolarisConfigCustomExtensionLayer.class);
Iterator<PolarisConfigCustomExtensionLayer> polarisConfigCustomExtensionLayerIterator = polarisConfigCustomExtensionLayerLoader.iterator();
// 一般就一个实现类,如果有多个,那么加载的是最后一个
while (polarisConfigCustomExtensionLayerIterator.hasNext()) {
polarisConfigCustomExtensionLayer = polarisConfigCustomExtensionLayerIterator.next();
LOGGER.info("[SCT Config] PolarisConfigFileLocator init polarisConfigCustomExtensionLayer:{}", polarisConfigCustomExtensionLayer);
}
}
public PolarisConfigFileLocator(PolarisConfigProperties polarisConfigProperties, PolarisContextProperties polarisContextProperties, ConfigFileService configFileService, PolarisPropertySourceManager polarisPropertySourceManager, Environment environment) { public PolarisConfigFileLocator(PolarisConfigProperties polarisConfigProperties, PolarisContextProperties polarisContextProperties, ConfigFileService configFileService, PolarisPropertySourceManager polarisPropertySourceManager, Environment environment) {
this.polarisConfigProperties = polarisConfigProperties; this.polarisConfigProperties = polarisConfigProperties;
@ -110,20 +96,25 @@ public class PolarisConfigFileLocator implements PropertySourceLocator {
return compositePropertySource; return compositePropertySource;
} }
finally { finally {
PolarisPropertyCache.getInstance().clear(); afterLocatePolarisConfigExtension(compositePropertySource);
PolarisPropertyCache.getInstance().getCache()
.addAll(new HashSet<>(Arrays.asList(compositePropertySource.getPropertyNames())));
} }
} }
private void initCustomPolarisConfigExtensionFiles(CompositePropertySource compositePropertySource) { private void initCustomPolarisConfigExtensionFiles(CompositePropertySource compositePropertySource) {
if (polarisConfigCustomExtensionLayer == null) { if (polarisConfigCustomExtensionLayer == null) {
LOGGER.info("[SCT Config] PolarisAdaptorTsfConfigExtensionLayer is not init, ignore the following execution steps"); LOGGER.debug("[SCT Config] PolarisAdaptorTsfConfigExtensionLayer is not init, ignore the following execution steps");
return; return;
} }
String namespace = polarisContextProperties.getNamespace(); String namespace = polarisContextProperties.getNamespace();
polarisConfigCustomExtensionLayer.execute(namespace, environment, compositePropertySource, polarisPropertySourceManager, configFileService); polarisConfigCustomExtensionLayer.initConfigFiles(namespace, environment, compositePropertySource, polarisPropertySourceManager, configFileService);
LOGGER.info("[SCT Config] InitCustomPolarisConfigExtensionFiles finished, namespace:{}", namespace); }
private void afterLocatePolarisConfigExtension(CompositePropertySource compositePropertySource) {
if (polarisConfigCustomExtensionLayer == null) {
LOGGER.debug("[SCT Config] PolarisAdaptorTsfConfigExtensionLayer is not init, ignore the following execution steps");
return;
}
polarisConfigCustomExtensionLayer.executeAfterLocateConfigReturning(compositePropertySource);
} }
private void initInternalConfigFiles(CompositePropertySource compositePropertySource) { private void initInternalConfigFiles(CompositePropertySource compositePropertySource) {

@ -34,7 +34,6 @@ import org.springframework.context.ApplicationListener;
import org.springframework.lang.NonNull; import org.springframework.lang.NonNull;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
/** /**
* 1. Listen to the Polaris server configuration publishing event 2. Write the changed * 1. Listen to the Polaris server configuration publishing event 2. Write the changed
* configuration content to propertySource 3. Refresh the context through contextRefresher * configuration content to propertySource 3. Refresh the context through contextRefresher
@ -51,6 +50,9 @@ public abstract class PolarisConfigPropertyAutoRefresher implements ApplicationL
private final AtomicBoolean registered = new AtomicBoolean(false); private final AtomicBoolean registered = new AtomicBoolean(false);
// 此类给一些客户定制化逻辑做一些特殊业务分组文件的配置处理
private final PolarisConfigCustomExtensionLayer polarisConfigCustomExtensionLayer = PolarisServiceLoaderUtil.getPolarisConfigCustomExtensionLayer();
public PolarisConfigPropertyAutoRefresher(PolarisConfigProperties polarisConfigProperties, PolarisPropertySourceManager polarisPropertySourceManager) { public PolarisConfigPropertyAutoRefresher(PolarisConfigProperties polarisConfigProperties, PolarisPropertySourceManager polarisPropertySourceManager) {
this.polarisConfigProperties = polarisConfigProperties; this.polarisConfigProperties = polarisConfigProperties;
this.polarisPropertySourceManager = polarisPropertySourceManager; this.polarisPropertySourceManager = polarisPropertySourceManager;
@ -75,76 +77,71 @@ public abstract class PolarisConfigPropertyAutoRefresher implements ApplicationL
return; return;
} }
// custom register polaris config
customInitRegisterPolarisConfig(this);
// register polaris config publish event // register polaris config publish event
registerPolarisConfigPublishChangeListener(polarisPropertySources); for (PolarisPropertySource polarisPropertySource : polarisPropertySources) {
registerPolarisConfigPublishChangeListener(polarisPropertySource);
// 增加接收刷新事件接收到事件以后就进行全量配置刷新重新加载PolarisConfigFileLocator同时添加Listener事件 customRegisterPolarisConfigPublishChangeListener(polarisPropertySource);
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) { private void customInitRegisterPolarisConfig(PolarisConfigPropertyAutoRefresher polarisConfigPropertyAutoRefresher) {
for (PolarisPropertySource polarisPropertySource : polarisPropertySources) { if (polarisConfigCustomExtensionLayer == null) {
ConfigKVFileChangeListener configKVFileChangeListener = configKVFileChangeEvent -> { LOGGER.debug("[SCT Config] PolarisAdaptorTsfConfigExtensionLayer is not init, ignore the following execution steps");
return;
}
polarisConfigCustomExtensionLayer.initRegisterConfig(polarisConfigPropertyAutoRefresher);
}
public void registerPolarisConfigPublishChangeListener(PolarisPropertySource polarisPropertySource) {
polarisPropertySource.getConfigKVFile()
.addChangeListener((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(); Map<String, Object> source = polarisPropertySource.getSource();
for (String changedKey : configKVFileChangeEvent.changedKeys()) { for (String changedKey : configKVFileChangeEvent.changedKeys()) {
ConfigPropertyChangeInfo configPropertyChangeInfo = configKVFileChangeEvent.getChangeInfo(changedKey); ConfigPropertyChangeInfo configPropertyChangeInfo = configKVFileChangeEvent.getChangeInfo(changedKey);
LOGGER.info("[SCT Config] changed property = {}", configPropertyChangeInfo); LOGGER.info("[SCT Config] changed property = {}", configPropertyChangeInfo);
// 新增动态改变日志级别的能力 // 新增动态改变日志级别的能力
try { try {
if (changedKey.startsWith("logging.level") && changedKey.length() >= 14) { if (changedKey.startsWith("logging.level") && changedKey.length() >= 14) {
String loggerName = changedKey.substring(14); String loggerName = changedKey.substring(14);
String newValue = (String) configPropertyChangeInfo.getNewValue().toString(); String newValue = (String) configPropertyChangeInfo.getNewValue();
LOGGER.info("[SCT Config] set logging.level loggerName:{}, newValue:{}", loggerName, newValue); LOGGER.info("[SCT Config] set logging.level loggerName:{}, newValue:{}", loggerName, newValue);
PolarisConfigLoggerContext.setLevel(loggerName, newValue); PolarisConfigLoggerContext.setLevel(loggerName, newValue);
}
} }
catch (Exception e) {
LOGGER.error("[SCT Config] set logging.level exception,", e);
}
switch (configPropertyChangeInfo.getChangeType()) {
case MODIFIED:
case ADDED:
source.put(changedKey, configPropertyChangeInfo.getNewValue());
break;
case DELETED:
source.remove(changedKey);
break;
}
// update the attribute with @Value annotation
refreshSpringValue(changedKey);
} }
catch (Exception e) { // update @ConfigurationProperties beans
LOGGER.error("[SCT Config] set logging.level exception,", e); refreshConfigurationProperties(configKVFileChangeEvent.changedKeys());
} });
switch (configPropertyChangeInfo.getChangeType()) { }
case MODIFIED:
case ADDED: private void customRegisterPolarisConfigPublishChangeListener(PolarisPropertySource polarisPropertySource) {
source.put(changedKey, configPropertyChangeInfo.getNewValue()); if (polarisConfigCustomExtensionLayer == null) {
break; LOGGER.debug("[SCT Config] PolarisAdaptorTsfConfigExtensionLayer is not init, ignore the following execution steps");
case DELETED: return;
source.remove(changedKey);
break;
}
// update the attribute with @Value annotation
refreshSpringValue(changedKey);
}
// update @ConfigurationProperties beans
refreshConfigurationProperties(configKVFileChangeEvent.changedKeys());
};
polarisPropertySource.getConfigKVFile().addChangeListener(configKVFileChangeListener);
// 保存最近添加的ChangeListener
PolarisContextRefreshUtil.getLastPolarisPropertyConfigKVFileMap()
.put(polarisPropertySource, configKVFileChangeListener);
} }
polarisConfigCustomExtensionLayer.executeRegisterPublishChangeListener(polarisPropertySource);
} }
} }

@ -1,47 +0,0 @@
/*
* 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,13 +19,11 @@
package com.tencent.cloud.polaris.config.adapter; package com.tencent.cloud.polaris.config.adapter;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import com.tencent.polaris.configuration.api.core.ConfigKVFile; import com.tencent.polaris.configuration.api.core.ConfigKVFile;
import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.MapPropertySource;
/** /**
* a polaris config file will be wrapped as polaris property source. * a polaris config file will be wrapped as polaris property source.
* *
@ -70,29 +68,6 @@ public class PolarisPropertySource extends MapPropertySource {
return configKVFile; 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 @Override
public String toString() { public String toString() {
return "PolarisPropertySource{" + "namespace='" + namespace + '\'' + ", group='" + group + '\'' + ", fileName='" + fileName + '\'' + '}'; return "PolarisPropertySource{" + "namespace='" + namespace + '\'' + ", group='" + group + '\'' + ", fileName='" + fileName + '\'' + '}';

@ -0,0 +1,41 @@
/*
* 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.Iterator;
import java.util.ServiceLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author juanyinyang
* @Date 2023810 4:11:05
*/
public final class PolarisServiceLoaderUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(PolarisServiceLoaderUtil.class);
private PolarisServiceLoaderUtil() {
}
// 此类给一些客户定制化逻辑做一些特殊业务分组文件的配置处理
private static PolarisConfigCustomExtensionLayer polarisConfigCustomExtensionLayer;
static {
ServiceLoader<PolarisConfigCustomExtensionLayer> polarisConfigCustomExtensionLayerLoader = ServiceLoader.load(PolarisConfigCustomExtensionLayer.class);
Iterator<PolarisConfigCustomExtensionLayer> polarisConfigCustomExtensionLayerIterator = polarisConfigCustomExtensionLayerLoader.iterator();
// 一般就一个实现类,如果有多个,那么加载的是最后一个
while (polarisConfigCustomExtensionLayerIterator.hasNext()) {
polarisConfigCustomExtensionLayer = polarisConfigCustomExtensionLayerIterator.next();
LOGGER.info("[SCT Config] PolarisConfigFileLocator init polarisConfigCustomExtensionLayer:{}", polarisConfigCustomExtensionLayer);
}
}
public static PolarisConfigCustomExtensionLayer getPolarisConfigCustomExtensionLayer() {
return polarisConfigCustomExtensionLayer;
}
}

@ -1,40 +0,0 @@
/*
* 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.config.cache;
import java.util.HashSet;
import java.util.Set;
/**
* @author juanyinyang
* @Date 202388 4:56:18
*/
public final class PolarisPropertyCache {
private static final PolarisPropertyCache instance = new PolarisPropertyCache();
private final Set<String> cache = new HashSet<>();
private PolarisPropertyCache() {
}
public static PolarisPropertyCache getInstance() {
return instance;
}
public Set<String> getCache() {
return cache;
}
public void clear() {
cache.clear();
}
}
Loading…
Cancel
Save