From 96016f0c104e980e06e3b1e53b0e8343df03a210 Mon Sep 17 00:00:00 2001 From: Rubbernecker <62733397+Rubbernecker@users.noreply.github.com> Date: Fri, 25 Dec 2020 12:50:45 +0800 Subject: [PATCH] feature:Support to obtain multiple configurations through a single dataid in Nacos (#3303) --- changes/1.5.0.md | 2 + changes/en-us/1.5.0.md | 2 + .../config/nacos/NacosConfiguration.java | 130 +++++++++++++++--- script/client/conf/registry.conf | 1 + script/server/config/registry.conf | 1 + script/server/config/registry.properties | 1 + script/server/config/registry.yml | 9 +- .../config/ConfigNacosProperties.java | 10 ++ server/src/main/resources/registry.conf | 1 + 9 files changed, 137 insertions(+), 20 deletions(-) diff --git a/changes/1.5.0.md b/changes/1.5.0.md index 45a2301aa..69f9d75a5 100644 --- a/changes/1.5.0.md +++ b/changes/1.5.0.md @@ -42,6 +42,7 @@ Seata 鏄竴娆惧紑婧愮殑鍒嗗竷寮忎簨鍔¤В鍐虫柟妗堬紝鎻愪緵楂樻€ц兘鍜岀畝鍗� - [[#3365](https://github.com/seata/seata/pull/3365)] 淇ParameterParserTest娴嬭瘯鐢ㄤ緥 - [[#3359](https://github.com/seata/seata/pull/3359)] 鍒犻櫎鏈娇鐢ㄧ殑娴嬭瘯鐢ㄤ緥 - [[#3397](https://github.com/seata/seata/pull/3397)] 娣诲姞鏇存敼璁板綍鏂囦欢澶� + - [[#3303](https://github.com/seata/seata/pull/3303)] 鏀寔浠巒acos鍗曚竴dataId涓鍙栨墍鏈夐厤缃� @@ -61,6 +62,7 @@ Seata 鏄竴娆惧紑婧愮殑鍒嗗竷寮忎簨鍔¤В鍐虫柟妗堬紝鎻愪緵楂樻€ц兘鍜岀畝鍗� - [a364176773](https://github.com/a364176773) - [anselleeyy](https://github.com/anselleeyy) - [Ifdevil](https://github.com/Ifdevil) + - [Rubbernecker](https://github.com/Rubbernecker) 鍚屾椂锛屾垜浠敹鍒颁簡绀惧尯鍙嶉鐨勫緢澶氭湁浠峰€肩殑issue鍜屽缓璁紝闈炲父鎰熻阿澶у銆� diff --git a/changes/en-us/1.5.0.md b/changes/en-us/1.5.0.md index 2c4e1a559..fb4364e98 100644 --- a/changes/en-us/1.5.0.md +++ b/changes/en-us/1.5.0.md @@ -41,6 +41,7 @@ - [[#3365](https://github.com/seata/seata/pull/3365)] optimize ParameterParserTest test case failed - [[#3359](https://github.com/seata/seata/pull/3359)] remove unused test case - [[#3397](https://github.com/seata/seata/pull/3397)] add the change records folder + - [[#3303](https://github.com/seata/seata/pull/3303)] supports reading all configurations from a single Nacos dataId ### test @@ -57,6 +58,7 @@ - [a364176773](https://github.com/a364176773) - [anselleeyy](https://github.com/anselleeyy) - [Ifdevil](https://github.com/Ifdevil) + - [Rubbernecker](https://github.com/Rubbernecker) Also, we receive many valuable issues, questions and advices from our community. Thanks for you all. diff --git a/config/seata-config-nacos/src/main/java/io/seata/config/nacos/NacosConfiguration.java b/config/seata-config-nacos/src/main/java/io/seata/config/nacos/NacosConfiguration.java index bdf45b9ee..c544810f2 100644 --- a/config/seata-config-nacos/src/main/java/io/seata/config/nacos/NacosConfiguration.java +++ b/config/seata-config-nacos/src/main/java/io/seata/config/nacos/NacosConfiguration.java @@ -15,6 +15,12 @@ */ package io.seata.config.nacos; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.charset.StandardCharsets; +import java.util.Enumeration; import java.util.Map; import java.util.Objects; import java.util.Properties; @@ -50,8 +56,10 @@ public class NacosConfiguration extends AbstractConfiguration { private static final Logger LOGGER = LoggerFactory.getLogger(NacosConfiguration.class); private static final String DEFAULT_GROUP = "SEATA_GROUP"; + private static final String DEFAULT_DATA_ID = "seata.properties"; private static final String GROUP_KEY = "group"; private static final String PRO_SERVER_ADDR_KEY = "serverAddr"; + private static final String NACOS_DATA_ID_KEY = "dataId"; private static final String ENDPOINT_KEY = "endpoint"; private static final String CONFIG_TYPE = "nacos"; private static final String DEFAULT_NAMESPACE = ""; @@ -63,8 +71,9 @@ public class NacosConfiguration extends AbstractConfiguration { private static final Configuration FILE_CONFIG = ConfigurationFactory.CURRENT_FILE_INSTANCE; private static volatile ConfigService configService; private static final int MAP_INITIAL_CAPACITY = 8; - private ConcurrentMap<String, ConcurrentMap<ConfigurationChangeListener, NacosListener>> configListenersMap - = new ConcurrentHashMap<>(MAP_INITIAL_CAPACITY); + private static final ConcurrentMap<String, ConcurrentMap<ConfigurationChangeListener, NacosListener>> CONFIG_LISTENERS_MAP + = new ConcurrentHashMap<>(MAP_INITIAL_CAPACITY); + private static volatile Properties seataConfig = new Properties(); /** * Get instance of NacosConfiguration @@ -89,6 +98,7 @@ public class NacosConfiguration extends AbstractConfiguration { if (configService == null) { try { configService = NacosFactory.createConfigService(getConfigProperties()); + initSeataConfig(); } catch (NacosException e) { throw new RuntimeException(e); } @@ -101,11 +111,17 @@ public class NacosConfiguration extends AbstractConfiguration { if (value != null) { return value; } - try { - value = configService.getConfig(dataId, getNacosGroup(), timeoutMills); - } catch (NacosException exx) { - LOGGER.error(exx.getErrMsg()); + + value = seataConfig.getProperty(dataId); + + if (null == value) { + try { + value = configService.getConfig(dataId, getNacosGroup(), timeoutMills); + } catch (NacosException exx) { + LOGGER.error(exx.getErrMsg()); + } } + return value == null ? defaultValue : value; } @@ -113,7 +129,12 @@ public class NacosConfiguration extends AbstractConfiguration { public boolean putConfig(String dataId, String content, long timeoutMills) { boolean result = false; try { - result = configService.publishConfig(dataId, getNacosGroup(), content); + if (!seataConfig.isEmpty()) { + seataConfig.setProperty(dataId, content); + result = configService.publishConfig(getNacosDataId(), getNacosGroup(), getSeataConfigStr()); + } else { + result = configService.publishConfig(dataId, getNacosGroup(), content); + } } catch (NacosException exx) { LOGGER.error(exx.getErrMsg()); } @@ -129,7 +150,12 @@ public class NacosConfiguration extends AbstractConfiguration { public boolean removeConfig(String dataId, long timeoutMills) { boolean result = false; try { - result = configService.removeConfig(dataId, getNacosGroup()); + if (!seataConfig.isEmpty()) { + seataConfig.remove(dataId); + result = configService.publishConfig(getNacosDataId(), getNacosGroup(), getSeataConfigStr()); + } else { + result = configService.removeConfig(dataId, getNacosGroup()); + } } catch (NacosException exx) { LOGGER.error(exx.getErrMsg()); } @@ -143,7 +169,7 @@ public class NacosConfiguration extends AbstractConfiguration { } try { NacosListener nacosListener = new NacosListener(dataId, listener); - configListenersMap.computeIfAbsent(dataId, key -> new ConcurrentHashMap<>()) + CONFIG_LISTENERS_MAP.computeIfAbsent(dataId, key -> new ConcurrentHashMap<>()) .put(listener, nacosListener); configService.addListener(dataId, getNacosGroup(), nacosListener); } catch (Exception exx) { @@ -161,7 +187,7 @@ public class NacosConfiguration extends AbstractConfiguration { for (ConfigurationChangeListener entry : configChangeListeners) { if (listener.equals(entry)) { NacosListener nacosListener = null; - Map<ConfigurationChangeListener, NacosListener> configListeners = configListenersMap.get(dataId); + Map<ConfigurationChangeListener, NacosListener> configListeners = CONFIG_LISTENERS_MAP.get(dataId); if (configListeners != null) { nacosListener = configListeners.get(listener); configListeners.remove(entry); @@ -177,7 +203,7 @@ public class NacosConfiguration extends AbstractConfiguration { @Override public Set<ConfigurationChangeListener> getConfigListeners(String dataId) { - Map<ConfigurationChangeListener, NacosListener> configListeners = configListenersMap.get(dataId); + Map<ConfigurationChangeListener, NacosListener> configListeners = CONFIG_LISTENERS_MAP.get(dataId); if (CollectionUtils.isNotEmpty(configListeners)) { return configListeners.keySet(); } else { @@ -210,10 +236,10 @@ public class NacosConfiguration extends AbstractConfiguration { properties.setProperty(PRO_NAMESPACE_KEY, namespace); } String userName = StringUtils.isNotBlank(System.getProperty(USER_NAME)) ? System.getProperty(USER_NAME) - : FILE_CONFIG.getConfig(getNacosUserName()); + : FILE_CONFIG.getConfig(getNacosUserName()); if (StringUtils.isNotBlank(userName)) { String password = StringUtils.isNotBlank(System.getProperty(PASSWORD)) ? System.getProperty(PASSWORD) - : FILE_CONFIG.getConfig(getNacosPassword()); + : FILE_CONFIG.getConfig(getNacosPassword()); if (StringUtils.isNotBlank(password)) { properties.setProperty(USER_NAME, userName); properties.setProperty(PASSWORD, password); @@ -234,20 +260,57 @@ public class NacosConfiguration extends AbstractConfiguration { return String.join(ConfigurationKeys.FILE_CONFIG_SPLIT_CHAR, ConfigurationKeys.FILE_ROOT_CONFIG, CONFIG_TYPE, GROUP_KEY); } + private static String getNacosDataIdKey() { + return String.join(ConfigurationKeys.FILE_CONFIG_SPLIT_CHAR, ConfigurationKeys.FILE_ROOT_CONFIG, CONFIG_TYPE, NACOS_DATA_ID_KEY); + } + private static String getNacosUserName() { return String.join(ConfigurationKeys.FILE_CONFIG_SPLIT_CHAR, ConfigurationKeys.FILE_ROOT_CONFIG, CONFIG_TYPE, - USER_NAME); + USER_NAME); } private static String getNacosPassword() { return String.join(ConfigurationKeys.FILE_CONFIG_SPLIT_CHAR, ConfigurationKeys.FILE_ROOT_CONFIG, CONFIG_TYPE, - PASSWORD); + PASSWORD); } private static String getNacosGroup() { return FILE_CONFIG.getConfig(getNacosGroupKey(), DEFAULT_GROUP); } + private static String getNacosDataId() { + return FILE_CONFIG.getConfig(getNacosDataIdKey(), DEFAULT_DATA_ID); + } + + private static String getSeataConfigStr() { + StringBuilder sb = new StringBuilder(); + + Enumeration<?> enumeration = seataConfig.propertyNames(); + while (enumeration.hasMoreElements()) { + String key = (String) enumeration.nextElement(); + String property = seataConfig.getProperty(key); + sb.append(key).append("=").append(property).append("\n"); + } + + return sb.toString(); + } + + private static void initSeataConfig() { + try { + String nacosDataId = getNacosDataId(); + String config = configService.getConfig(nacosDataId, getNacosGroup(), DEFAULT_CONFIG_TIMEOUT); + if (StringUtils.isNotBlank(config)) { + try (Reader reader = new InputStreamReader(new ByteArrayInputStream(config.getBytes()), StandardCharsets.UTF_8)) { + seataConfig.load(reader); + } + NacosListener nacosListener = new NacosListener(nacosDataId, null); + configService.addListener(nacosDataId, getNacosGroup(), nacosListener); + } + } catch (NacosException | IOException e) { + LOGGER.error("init config properties error", e); + } + } + @Override public String getTypeName() { return CONFIG_TYPE; @@ -282,8 +345,43 @@ public class NacosConfiguration extends AbstractConfiguration { @Override public void innerReceive(String dataId, String group, String configInfo) { + //The new configuration method to puts all configurations into a dateId + if (getNacosDataId().equals(dataId)) { + Properties seataConfigNew = new Properties(); + if (StringUtils.isNotBlank(configInfo)) { + try (Reader reader = new InputStreamReader(new ByteArrayInputStream(configInfo.getBytes()), StandardCharsets.UTF_8)) { + seataConfigNew.load(reader); + } catch (IOException e) { + LOGGER.error("load config properties error", e); + return; + } + } + + //Get all the monitored dataids and judge whether it has been modified + for (Map.Entry<String, ConcurrentMap<ConfigurationChangeListener, NacosListener>> entry : CONFIG_LISTENERS_MAP.entrySet()) { + String listenedDataId = entry.getKey(); + String propertyOld = seataConfig.getProperty(listenedDataId, ""); + String propertyNew = seataConfigNew.getProperty(listenedDataId, ""); + if (!propertyOld.equals(propertyNew)) { + ConfigurationChangeEvent event = new ConfigurationChangeEvent() + .setDataId(listenedDataId) + .setNewValue(propertyNew) + .setNamespace(group); + + ConcurrentMap<ConfigurationChangeListener, NacosListener> configListeners = entry.getValue(); + for (ConfigurationChangeListener configListener : configListeners.keySet()) { + configListener.onProcessEvent(event); + } + } + } + + seataConfig = seataConfigNew; + return; + } + + //Compatible with old writing ConfigurationChangeEvent event = new ConfigurationChangeEvent().setDataId(dataId).setNewValue(configInfo) - .setNamespace(group); + .setNamespace(group); listener.onProcessEvent(event); } } diff --git a/script/client/conf/registry.conf b/script/client/conf/registry.conf index b984696dc..fc04bb37f 100644 --- a/script/client/conf/registry.conf +++ b/script/client/conf/registry.conf @@ -60,6 +60,7 @@ config { group = "SEATA_GROUP" username = "" password = "" + dataId = "seata.properties" } consul { serverAddr = "127.0.0.1:8500" diff --git a/script/server/config/registry.conf b/script/server/config/registry.conf index cd85ac735..fefd59e61 100644 --- a/script/server/config/registry.conf +++ b/script/server/config/registry.conf @@ -65,6 +65,7 @@ config { group = "SEATA_GROUP" username = "" password = "" + dataId = "seataServer.properties" } consul { serverAddr = "127.0.0.1:8500" diff --git a/script/server/config/registry.properties b/script/server/config/registry.properties index 9c859befe..b478f5061 100644 --- a/script/server/config/registry.properties +++ b/script/server/config/registry.properties @@ -40,6 +40,7 @@ config.nacos.namespace= config.nacos.group=SEATA_GROUP config.nacos.username= config.nacos.password= +config.nacos.dataId=seataServer.properties config.consul.serverAddr=127.0.0.1:8500 config.apollo.appId=seata-server config.apollo.apolloMeta=http://192.168.1.204:8801 diff --git a/script/server/config/registry.yml b/script/server/config/registry.yml index 13d0d9cae..45ca471a2 100644 --- a/script/server/config/registry.yml +++ b/script/server/config/registry.yml @@ -11,8 +11,8 @@ registry: namespace: cluster: default username: - password: - + password: + eureka: serviceUrl: http://localhost:8761/eureka application: default @@ -64,11 +64,12 @@ config: namespace: group: SEATA_GROUP username: - password: + password: + dataId: seataServer.properties consul: serverAddr: 127.0.0.1:8500 - + apollo: appId: seata-server apolloMeta: http://192.168.1.204:8801 diff --git a/seata-spring-boot-starter/src/main/java/io/seata/spring/boot/autoconfigure/properties/config/ConfigNacosProperties.java b/seata-spring-boot-starter/src/main/java/io/seata/spring/boot/autoconfigure/properties/config/ConfigNacosProperties.java index 798c9e73d..2d75286cf 100644 --- a/seata-spring-boot-starter/src/main/java/io/seata/spring/boot/autoconfigure/properties/config/ConfigNacosProperties.java +++ b/seata-spring-boot-starter/src/main/java/io/seata/spring/boot/autoconfigure/properties/config/ConfigNacosProperties.java @@ -31,6 +31,7 @@ public class ConfigNacosProperties { private String group = "SEATA_GROUP"; private String username = ""; private String password = ""; + private String dataId = "seata.properties"; public String getServerAddr() { return serverAddr; @@ -76,4 +77,13 @@ public class ConfigNacosProperties { this.password = password; return this; } + + public String getDataId() { + return dataId; + } + + public ConfigNacosProperties setDataId(String dataId) { + this.dataId = dataId; + return this; + } } diff --git a/server/src/main/resources/registry.conf b/server/src/main/resources/registry.conf index 97f8d0b78..7f0210050 100644 --- a/server/src/main/resources/registry.conf +++ b/server/src/main/resources/registry.conf @@ -65,6 +65,7 @@ config { group = "SEATA_GROUP" username = "" password = "" + dataId = "seataServer.properties" } consul { serverAddr = "127.0.0.1:8500" -- GitLab