From ff1fa8fe1b599da6554985ed5d24ca4b5902a459 Mon Sep 17 00:00:00 2001 From: jimin Date: Mon, 19 Aug 2024 00:30:40 +0800 Subject: [PATCH] optimize: optimize NacosConfiguration singleton reload (#6763) --- changes/en-us/2.x.md | 1 + changes/zh-cn/2.x.md | 2 + .../java/org/apache/seata/config/Dispose.java | 27 +++ .../config/nacos/NacosConfiguration.java | 58 ++++-- .../{nacos => extend}/NacosConfiguration.java | 21 +- .../NacosConfigurationProvider.java | 2 +- .../TestConfigFromExtendSPI.java} | 10 +- .../config/nacos/NacosConfigurationTest.java | 35 +++- .../seata/config/nacos/NacosMockTest.java | 193 ++++++++++++++++++ .../io.seata.config.ConfigurationProvider | 2 +- ....apache.seata.config.ConfigurationProvider | 17 ++ .../src/test/resources/registry-mock.conf | 85 ++++++++ .../src/test/resources/registry.conf | 2 +- 13 files changed, 405 insertions(+), 50 deletions(-) create mode 100644 config/seata-config-core/src/main/java/org/apache/seata/config/Dispose.java rename config/seata-config-nacos/src/test/java/io/seata/config/{nacos => extend}/NacosConfiguration.java (95%) rename config/seata-config-nacos/src/test/java/io/seata/config/{nacos => extend}/NacosConfigurationProvider.java (97%) rename config/seata-config-nacos/src/test/java/io/seata/config/{nacos/TestConfigCustomSPI.java => extend/TestConfigFromExtendSPI.java} (92%) create mode 100644 config/seata-config-nacos/src/test/java/org/apache/seata/config/nacos/NacosMockTest.java create mode 100644 config/seata-config-nacos/src/test/resources/META-INF/services/org.apache.seata.config.ConfigurationProvider create mode 100644 config/seata-config-nacos/src/test/resources/registry-mock.conf diff --git a/changes/en-us/2.x.md b/changes/en-us/2.x.md index fb3764e2cd1..8874bc1a827 100644 --- a/changes/en-us/2.x.md +++ b/changes/en-us/2.x.md @@ -57,6 +57,7 @@ Add changes here for all PR submitted to the 2.x branch. - [[#6748](https://github.com/apache/incubator-seata/pull/6748)] optimize ConsistentHashLoadBalance Algorithm - [[#6747](https://github.com/apache/incubator-seata/pull/6747)] optimize fastjson deserialization - [[#6755](https://github.com/apache/incubator-seata/pull/6755)] optimize namingserver code logic +- [[#6763](https://github.com/apache/incubator-seata/pull/6763)] optimize NacosConfiguration singleton reload - [[#6761](https://github.com/apache/incubator-seata/pull/6761)] optimize the namingserver code to improve readability diff --git a/changes/zh-cn/2.x.md b/changes/zh-cn/2.x.md index f53af3f5a07..bd37dcc9dca 100644 --- a/changes/zh-cn/2.x.md +++ b/changes/zh-cn/2.x.md @@ -58,8 +58,10 @@ - [[#6748](https://github.com/apache/incubator-seata/pull/6748)] 优化 ConsistentHashLoadBalance 算法 - [[#6747](https://github.com/apache/incubator-seata/pull/6747)] 优化 fastjson 反序列化 - [[#6755](https://github.com/apache/incubator-seata/pull/6755)] 优化namingserver代码逻辑 +- [[#6763](https://github.com/apache/incubator-seata/pull/6763)] 优化 NacosConfiguration 单例加载 - [[#6761](https://github.com/apache/incubator-seata/pull/6761)] 提升namingserver manager代码可读性 + ### refactor: diff --git a/config/seata-config-core/src/main/java/org/apache/seata/config/Dispose.java b/config/seata-config-core/src/main/java/org/apache/seata/config/Dispose.java new file mode 100644 index 00000000000..3de4ebe065f --- /dev/null +++ b/config/seata-config-core/src/main/java/org/apache/seata/config/Dispose.java @@ -0,0 +1,27 @@ +/* + * 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 org.apache.seata.config; + +/** + * The interface Dispose. + */ +public interface Dispose { + /** + * Dispose. + */ + void dispose(); +} diff --git a/config/seata-config-nacos/src/main/java/org/apache/seata/config/nacos/NacosConfiguration.java b/config/seata-config-nacos/src/main/java/org/apache/seata/config/nacos/NacosConfiguration.java index 1530eceb5dc..63ff3a06aed 100644 --- a/config/seata-config-nacos/src/main/java/org/apache/seata/config/nacos/NacosConfiguration.java +++ b/config/seata-config-nacos/src/main/java/org/apache/seata/config/nacos/NacosConfiguration.java @@ -38,6 +38,7 @@ import org.apache.seata.config.ConfigurationChangeListener; import org.apache.seata.config.ConfigurationFactory; import org.apache.seata.config.ConfigurationKeys; +import org.apache.seata.config.Dispose; import org.apache.seata.config.processor.ConfigProcessor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -47,7 +48,7 @@ * The type Nacos configuration. * */ -public class NacosConfiguration extends AbstractConfiguration { +public class NacosConfiguration extends AbstractConfiguration implements Dispose { private static volatile NacosConfiguration instance; private static final Logger LOGGER = LoggerFactory.getLogger(NacosConfiguration.class); @@ -66,10 +67,10 @@ public class NacosConfiguration extends AbstractConfiguration { private static final String RAM_ROLE_NAME_KEY = "ramRoleName"; private static final String USE_PARSE_RULE = "false"; private static final String CONTEXT_PATH = "contextPath"; - private static final Configuration FILE_CONFIG = ConfigurationFactory.CURRENT_FILE_INSTANCE; + private Configuration fileConfig = ConfigurationFactory.CURRENT_FILE_INSTANCE; private static volatile ConfigService configService; private static final int MAP_INITIAL_CAPACITY = 8; - private static final ConcurrentMap> CONFIG_LISTENERS_MAP + private static volatile ConcurrentMap> CONFIG_LISTENERS_MAP = new ConcurrentHashMap<>(MAP_INITIAL_CAPACITY); private static volatile Properties seataConfig = new Properties(); @@ -203,14 +204,14 @@ public Set getConfigListeners(String dataId) { } } - private static Properties getConfigProperties() { + private Properties getConfigProperties() { Properties properties = new Properties(); properties.setProperty(ConfigurationKeys.IS_USE_CLOUD_NAMESPACE_PARSING, USE_PARSE_RULE); properties.setProperty(ConfigurationKeys.IS_USE_ENDPOINT_PARSING_RULE, USE_PARSE_RULE); if (System.getProperty(PRO_SERVER_ADDR_KEY) != null) { properties.setProperty(PRO_SERVER_ADDR_KEY, System.getProperty(PRO_SERVER_ADDR_KEY)); } else { - String address = FILE_CONFIG.getConfig(getNacosAddrFileKey()); + String address = fileConfig.getConfig(getNacosAddrFileKey()); if (address != null) { properties.setProperty(PRO_SERVER_ADDR_KEY, address); } @@ -219,7 +220,7 @@ private static Properties getConfigProperties() { if (System.getProperty(PRO_NAMESPACE_KEY) != null) { properties.setProperty(PRO_NAMESPACE_KEY, System.getProperty(PRO_NAMESPACE_KEY)); } else { - String namespace = FILE_CONFIG.getConfig(getNacosNameSpaceFileKey()); + String namespace = fileConfig.getConfig(getNacosNameSpaceFileKey()); if (namespace == null) { namespace = DEFAULT_NAMESPACE; } @@ -228,7 +229,7 @@ private static Properties getConfigProperties() { if (!initNacosAuthProperties(properties)) { LOGGER.info("Nacos config auth properties empty."); } - String contextPath = StringUtils.isNotBlank(System.getProperty(CONTEXT_PATH)) ? System.getProperty(CONTEXT_PATH) : FILE_CONFIG.getConfig(getNacosContextPathKey()); + String contextPath = StringUtils.isNotBlank(System.getProperty(CONTEXT_PATH)) ? System.getProperty(CONTEXT_PATH) : fileConfig.getConfig(getNacosContextPathKey()); if (StringUtils.isNotBlank(contextPath)) { properties.setProperty(CONTEXT_PATH, contextPath); } @@ -242,10 +243,10 @@ private static Properties getConfigProperties() { * @param sourceProperties the source properties * @return auth properties */ - private static boolean initNacosAuthProperties(Properties sourceProperties) { - String userName = StringUtils.isNotBlank(System.getProperty(USER_NAME)) ? System.getProperty(USER_NAME) : FILE_CONFIG.getConfig(getNacosUserName()); + private boolean initNacosAuthProperties(Properties sourceProperties) { + String userName = StringUtils.isNotBlank(System.getProperty(USER_NAME)) ? System.getProperty(USER_NAME) : fileConfig.getConfig(getNacosUserName()); if (StringUtils.isNotBlank(userName)) { - String password = StringUtils.isNotBlank(System.getProperty(PASSWORD)) ? System.getProperty(PASSWORD) : FILE_CONFIG.getConfig(getNacosPassword()); + String password = StringUtils.isNotBlank(System.getProperty(PASSWORD)) ? System.getProperty(PASSWORD) : fileConfig.getConfig(getNacosPassword()); if (StringUtils.isNotBlank(password)) { sourceProperties.setProperty(USER_NAME, userName); sourceProperties.setProperty(PASSWORD, password); @@ -253,10 +254,10 @@ private static boolean initNacosAuthProperties(Properties sourceProperties) { return true; } } else { - String accessKey = StringUtils.isNotBlank(System.getProperty(ACCESS_KEY)) ? System.getProperty(ACCESS_KEY) : FILE_CONFIG.getConfig(getNacosAccessKey()); - String ramRoleName = StringUtils.isNotBlank(System.getProperty(RAM_ROLE_NAME_KEY)) ? System.getProperty(RAM_ROLE_NAME_KEY) : FILE_CONFIG.getConfig(getNacosRamRoleNameKey()); + String accessKey = StringUtils.isNotBlank(System.getProperty(ACCESS_KEY)) ? System.getProperty(ACCESS_KEY) : fileConfig.getConfig(getNacosAccessKey()); + String ramRoleName = StringUtils.isNotBlank(System.getProperty(RAM_ROLE_NAME_KEY)) ? System.getProperty(RAM_ROLE_NAME_KEY) : fileConfig.getConfig(getNacosRamRoleNameKey()); if (StringUtils.isNotBlank(accessKey)) { - String secretKey = StringUtils.isNotBlank(System.getProperty(SECRET_KEY)) ? System.getProperty(SECRET_KEY) : FILE_CONFIG.getConfig(getNacosSecretKey()); + String secretKey = StringUtils.isNotBlank(System.getProperty(SECRET_KEY)) ? System.getProperty(SECRET_KEY) : fileConfig.getConfig(getNacosSecretKey()); if (StringUtils.isNotBlank(secretKey)) { sourceProperties.put(ACCESS_KEY, accessKey); sourceProperties.put(SECRET_KEY, secretKey); @@ -310,15 +311,15 @@ public static String getNacosRamRoleNameKey() { return String.join(ConfigurationKeys.FILE_CONFIG_SPLIT_CHAR, ConfigurationKeys.FILE_ROOT_CONFIG, CONFIG_TYPE, RAM_ROLE_NAME_KEY); } - private static String getNacosGroup() { - return FILE_CONFIG.getConfig(getNacosGroupKey(), DEFAULT_GROUP); + private String getNacosGroup() { + return fileConfig.getConfig(getNacosGroupKey(), DEFAULT_GROUP); } - private static String getNacosDataId() { - return FILE_CONFIG.getConfig(getNacosDataIdKey(), DEFAULT_DATA_ID); + private String getNacosDataId() { + return fileConfig.getConfig(getNacosDataIdKey(), DEFAULT_DATA_ID); } - private static String getNacosDataType() { + private String getNacosDataType() { return ConfigProcessor.resolverConfigDataType(getNacosDataId()); } @@ -339,7 +340,7 @@ private static String getNacosContextPathKey() { return String.join(ConfigurationKeys.FILE_CONFIG_SPLIT_CHAR, ConfigurationKeys.FILE_ROOT_CONFIG, CONFIG_TYPE, CONTEXT_PATH); } - private static void initSeataConfig() { + private void initSeataConfig() { try { String nacosDataId = getNacosDataId(); String config = configService.getConfig(nacosDataId, getNacosGroup(), DEFAULT_CONFIG_TIMEOUT); @@ -360,10 +361,27 @@ public String getTypeName() { return CONFIG_TYPE; } + @Override + public void dispose() { + if (null != CONFIG_LISTENERS_MAP) { + CONFIG_LISTENERS_MAP.clear(); + } + if (null != seataConfig) { + seataConfig.clear(); + } + if (null != configService) { + configService = null; + } + if (null != instance) { + instance = null; + } + fileConfig = ConfigurationFactory.CURRENT_FILE_INSTANCE; + } + /** * Non-blocking subscriptions prohibit adding subscriptions in the thread pool to prevent thread termination */ - public static class NacosListener extends AbstractSharedListener { + public class NacosListener extends AbstractSharedListener { private final String dataId; private final ConfigurationChangeListener listener; diff --git a/config/seata-config-nacos/src/test/java/io/seata/config/nacos/NacosConfiguration.java b/config/seata-config-nacos/src/test/java/io/seata/config/extend/NacosConfiguration.java similarity index 95% rename from config/seata-config-nacos/src/test/java/io/seata/config/nacos/NacosConfiguration.java rename to config/seata-config-nacos/src/test/java/io/seata/config/extend/NacosConfiguration.java index 87e3c39dbff..fb978c6b93a 100644 --- a/config/seata-config-nacos/src/test/java/io/seata/config/nacos/NacosConfiguration.java +++ b/config/seata-config-nacos/src/test/java/io/seata/config/extend/NacosConfiguration.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.seata.config.nacos; +package io.seata.config.extend; import java.io.IOException; import java.util.Enumeration; @@ -23,8 +23,6 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; import com.alibaba.nacos.api.NacosFactory; import com.alibaba.nacos.api.config.ConfigService; @@ -245,7 +243,6 @@ public static String getNacosDataIdKey() { NACOS_DATA_ID_KEY); } - private static String getNacosGroup() { return FILE_CONFIG.getString(getNacosGroupKey()); } @@ -316,17 +313,17 @@ public void innerReceive(String dataId, String group, String configInfo) { } } //Get all the monitored dataids and judge whether it has been modified - for (Map.Entry> entry : CONFIG_LISTENERS_MAP.entrySet()) { + for (Map.Entry> 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); + ConfigurationChangeEvent event = new ConfigurationChangeEvent().setDataId(listenedDataId) + .setNewValue(propertyNew).setNamespace(group); - ConcurrentMap configListeners = - entry.getValue(); + ConcurrentMap configListeners + = entry.getValue(); for (ConfigurationChangeListener configListener : configListeners.keySet()) { configListener.onProcessEvent(event); } @@ -340,8 +337,8 @@ public void innerReceive(String dataId, String group, String configInfo) { LOGGER.error("innerReceive error: {}", e.getMessage(), e); } //Compatible with old writing - ConfigurationChangeEvent event = - new ConfigurationChangeEvent().setDataId(dataId).setNewValue(configInfo).setNamespace(group); + ConfigurationChangeEvent event = new ConfigurationChangeEvent().setDataId(dataId).setNewValue(configInfo) + .setNamespace(group); listener.onProcessEvent(event); } } diff --git a/config/seata-config-nacos/src/test/java/io/seata/config/nacos/NacosConfigurationProvider.java b/config/seata-config-nacos/src/test/java/io/seata/config/extend/NacosConfigurationProvider.java similarity index 97% rename from config/seata-config-nacos/src/test/java/io/seata/config/nacos/NacosConfigurationProvider.java rename to config/seata-config-nacos/src/test/java/io/seata/config/extend/NacosConfigurationProvider.java index 54bfe67b3a4..578a7a1853b 100644 --- a/config/seata-config-nacos/src/test/java/io/seata/config/nacos/NacosConfigurationProvider.java +++ b/config/seata-config-nacos/src/test/java/io/seata/config/extend/NacosConfigurationProvider.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.seata.config.nacos; +package io.seata.config.extend; import io.seata.config.Configuration; import org.apache.seata.common.loader.LoadLevel; diff --git a/config/seata-config-nacos/src/test/java/io/seata/config/nacos/TestConfigCustomSPI.java b/config/seata-config-nacos/src/test/java/io/seata/config/extend/TestConfigFromExtendSPI.java similarity index 92% rename from config/seata-config-nacos/src/test/java/io/seata/config/nacos/TestConfigCustomSPI.java rename to config/seata-config-nacos/src/test/java/io/seata/config/extend/TestConfigFromExtendSPI.java index 54e1bbd846d..80bde364814 100644 --- a/config/seata-config-nacos/src/test/java/io/seata/config/nacos/TestConfigCustomSPI.java +++ b/config/seata-config-nacos/src/test/java/io/seata/config/extend/TestConfigFromExtendSPI.java @@ -14,19 +14,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.seata.config.nacos; +package io.seata.config.extend; import java.security.SecureRandom; -import java.util.Properties; import java.util.Set; import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import com.alibaba.nacos.api.NacosFactory; import com.alibaba.nacos.api.config.ConfigService; -import com.alibaba.nacos.api.config.listener.AbstractSharedListener; import com.alibaba.nacos.api.exception.NacosException; import com.typesafe.config.Config; @@ -42,7 +38,7 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -public class TestConfigCustomSPI { +public class TestConfigFromExtendSPI { private static Config FILE_CONFIG; private static ConfigService configService; @@ -67,7 +63,7 @@ public void testGetConfigProperties() throws Exception { Assertions.assertNotNull(configService); Configuration configuration = ConfigurationFactory.getInstance(); String postfix = generateRandomString(); - String dataId = "nacos.config.custom.spi." + postfix; + String dataId = "nacos.config.extension.spi." + postfix; String group = FILE_CONFIG.getString("config.test.group"); String content = "seata"; CountDownLatch listenerCountDown = new CountDownLatch(1); diff --git a/config/seata-config-nacos/src/test/java/org/apache/seata/config/nacos/NacosConfigurationTest.java b/config/seata-config-nacos/src/test/java/org/apache/seata/config/nacos/NacosConfigurationTest.java index 78ab0ec865a..ff938c9e28e 100644 --- a/config/seata-config-nacos/src/test/java/org/apache/seata/config/nacos/NacosConfigurationTest.java +++ b/config/seata-config-nacos/src/test/java/org/apache/seata/config/nacos/NacosConfigurationTest.java @@ -19,26 +19,45 @@ import java.lang.reflect.Method; import java.util.Properties; +import com.alibaba.nacos.api.exception.NacosException; + import org.apache.seata.common.util.ReflectionUtil; -import org.assertj.core.api.Assertions; +import org.apache.seata.config.Configuration; +import org.apache.seata.config.ConfigurationFactory; +import org.apache.seata.config.Dispose; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; - /** * The type Nacos configuration test - * */ public class NacosConfigurationTest { + private static Configuration configuration; + + @BeforeAll + public static void setup() throws NacosException { + System.clearProperty("seataEnv"); + configuration = NacosConfiguration.getInstance(); + if (configuration instanceof Dispose) { + ((Dispose)configuration).dispose(); + } + ConfigurationFactory.reload(); + configuration = NacosConfiguration.getInstance(); + } + @Test public void testGetConfigProperties() throws Exception { + Assertions.assertNotNull(configuration); Method method = ReflectionUtil.getMethod(NacosConfiguration.class, "getConfigProperties"); - Properties properties = (Properties) ReflectionUtil.invokeMethod(null, method); - Assertions.assertThat(properties.getProperty("contextPath")).isEqualTo("/bar"); + //do not use `ConfigurationFactory.getInstance()`, it's a proxy object + Properties properties = (Properties)method.invoke(configuration); + Assertions.assertEquals("/bar", properties.getProperty("contextPath")); System.setProperty("contextPath", "/foo"); - properties = (Properties) ReflectionUtil.invokeMethod(null, method); - Assertions.assertThat(properties.getProperty("contextPath")).isEqualTo("/foo"); + properties = (Properties)method.invoke(configuration); + Assertions.assertEquals("/foo", properties.getProperty("contextPath")); + System.clearProperty("contextPath"); } - } diff --git a/config/seata-config-nacos/src/test/java/org/apache/seata/config/nacos/NacosMockTest.java b/config/seata-config-nacos/src/test/java/org/apache/seata/config/nacos/NacosMockTest.java new file mode 100644 index 00000000000..7a30740a89c --- /dev/null +++ b/config/seata-config-nacos/src/test/java/org/apache/seata/config/nacos/NacosMockTest.java @@ -0,0 +1,193 @@ +/* + * 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 org.apache.seata.config.nacos; + +import java.lang.reflect.UndeclaredThrowableException; +import java.time.Duration; +import java.util.Properties; +import java.util.Set; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import com.alibaba.nacos.api.NacosFactory; +import com.alibaba.nacos.api.config.ConfigService; +import com.alibaba.nacos.api.exception.NacosException; + +import org.apache.seata.config.Configuration; +import org.apache.seata.config.ConfigurationCache; +import org.apache.seata.config.ConfigurationChangeEvent; +import org.apache.seata.config.ConfigurationChangeListener; +import org.apache.seata.config.ConfigurationFactory; +import org.apache.seata.config.Dispose; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +public class NacosMockTest { + private static ConfigService configService; + private static final String NACOS_ENDPOINT = "console.nacos.io:80"; + + private static final String NACOS_GROUP = "SEATA_GROUP"; + + private static final String NACOS_DATAID = "seata-mock"; + private static final String SUB_NACOS_DATAID = "KEY"; + + private ConfigurationChangeListener listener; + + @BeforeAll + public static void setup() throws NacosException { + System.setProperty("seataEnv", "mock"); + NacosConfiguration configuration = NacosConfiguration.getInstance(); + if (configuration instanceof Dispose) { + ((Dispose)configuration).dispose(); + } + ConfigurationFactory.reload(); + Properties properties = new Properties(); + properties.setProperty("serverAddr", NACOS_ENDPOINT); + configService = NacosFactory.createConfigService(properties); + configService.removeConfig(NACOS_DATAID, NACOS_GROUP); + } + + @Test + public void getInstance() { + Assertions.assertNotNull(configService); + Assertions.assertNotNull(NacosConfiguration.getInstance()); + Assertions.assertNotNull(ConfigurationFactory.getInstance()); + } + + @Test + public void getConfig() { + Configuration configuration = ConfigurationFactory.getInstance(); + String configStrValue = configuration.getConfig(SUB_NACOS_DATAID); + Assertions.assertNull(configStrValue); + configStrValue = configuration.getConfig(SUB_NACOS_DATAID, 5000); + Assertions.assertNull(configStrValue); + configStrValue = configuration.getConfig(SUB_NACOS_DATAID, "TEST", 5000); + Assertions.assertEquals("TEST", configStrValue); + ConfigurationCache.clear(); + System.setProperty(SUB_NACOS_DATAID, "SYS-TEST"); + configStrValue = configuration.getConfig(SUB_NACOS_DATAID, "TEST", 5000); + Assertions.assertEquals("SYS-TEST", configStrValue); + ConfigurationCache.clear(); + System.clearProperty(SUB_NACOS_DATAID); + + ConfigurationCache.clear(); + int configIntValue = configuration.getInt(SUB_NACOS_DATAID); + Assertions.assertEquals(0, configIntValue); + configIntValue = configuration.getInt(SUB_NACOS_DATAID, 100); + Assertions.assertEquals(100, configIntValue); + configIntValue = configuration.getInt(SUB_NACOS_DATAID, 100, 5000); + Assertions.assertEquals(100, configIntValue); + + ConfigurationCache.clear(); + boolean configBoolValue = configuration.getBoolean(SUB_NACOS_DATAID); + Assertions.assertEquals(false, configBoolValue); + configBoolValue = configuration.getBoolean(SUB_NACOS_DATAID, true); + Assertions.assertEquals(true, configBoolValue); + configBoolValue = configuration.getBoolean(SUB_NACOS_DATAID, true, 5000); + Assertions.assertEquals(true, configBoolValue); + + ConfigurationCache.clear(); + short configShortValue = configuration.getShort(SUB_NACOS_DATAID); + Assertions.assertEquals(0, configShortValue); + configShortValue = configuration.getShort(SUB_NACOS_DATAID, (short)64); + Assertions.assertEquals(64, configShortValue); + configShortValue = configuration.getShort(SUB_NACOS_DATAID, (short)127, 5000); + Assertions.assertEquals(127, configShortValue); + + ConfigurationCache.clear(); + long configLongValue = configuration.getShort(SUB_NACOS_DATAID); + Assertions.assertEquals(0L, configLongValue); + configLongValue = configuration.getLong(SUB_NACOS_DATAID, 12345678L); + Assertions.assertEquals(12345678L, configLongValue); + configLongValue = configuration.getLong(SUB_NACOS_DATAID, 65535L, 5000); + Assertions.assertEquals(65535L, configLongValue); + + ConfigurationCache.clear(); + Duration configDurValue = configuration.getDuration(SUB_NACOS_DATAID); + Assertions.assertEquals(Duration.ZERO, configDurValue); + Duration defaultDuration = Duration.ofMillis(5000); + configDurValue = configuration.getDuration(SUB_NACOS_DATAID, defaultDuration); + Assertions.assertEquals(defaultDuration, configDurValue); + defaultDuration = Duration.ofMillis(1000); + configDurValue = configuration.getDuration(SUB_NACOS_DATAID, defaultDuration, 5000); + Assertions.assertEquals(defaultDuration, configDurValue); + + ConfigurationCache.clear(); + configStrValue = configuration.getLatestConfig(SUB_NACOS_DATAID, "DEFAULT", 5000); + Assertions.assertEquals("DEFAULT", configStrValue); + + } + + @Test + public void putConfigIfAbsent() { + Configuration configuration = ConfigurationFactory.getInstance(); + Assertions.assertThrows(UndeclaredThrowableException.class, () -> { + configuration.putConfigIfAbsent(NACOS_DATAID, "TEST"); + }); + } + + @Test + public void removeConfig() { + Configuration configuration = ConfigurationFactory.getInstance(); + boolean removed = configuration.removeConfig(SUB_NACOS_DATAID); + Assertions.assertTrue(removed); + } + + @Test + public void putConfig() { + Configuration configuration = ConfigurationFactory.getInstance(); + boolean added = configuration.putConfig(SUB_NACOS_DATAID, "TEST"); + Assertions.assertTrue(added); + boolean removed = configuration.removeConfig(SUB_NACOS_DATAID); + Assertions.assertTrue(removed); + } + + @Test + public void testConfigListener() throws NacosException, InterruptedException { + Configuration configuration = ConfigurationFactory.getInstance(); + configuration.putConfig(NACOS_DATAID, "KEY=TEST"); + //prevent the listener event from batch processing + Thread.sleep(1000); + CountDownLatch latch = new CountDownLatch(1); + listener = new ConfigurationChangeListener() { + @Override + public void onChangeEvent(ConfigurationChangeEvent event) { + Assertions.assertEquals(SUB_NACOS_DATAID, event.getDataId()); + latch.countDown(); + } + }; + configuration.addConfigListener(SUB_NACOS_DATAID, listener); + Thread.sleep(1000); + configuration.putConfig(NACOS_DATAID, "KEY=VALUE"); + latch.await(3000, TimeUnit.MILLISECONDS); + Set listeners = configuration.getConfigListeners(SUB_NACOS_DATAID); + //configcache listener + user listener + Assertions.assertEquals(2, listeners.size()); + + configuration.removeConfigListener(SUB_NACOS_DATAID, listener); + listeners = configuration.getConfigListeners(SUB_NACOS_DATAID); + Assertions.assertEquals(1, listeners.size()); + } + + @AfterEach + public void afterEach() throws NacosException { + configService.removeConfig(NACOS_DATAID, NACOS_GROUP); + ConfigurationFactory.reload(); + } +} diff --git a/config/seata-config-nacos/src/test/resources/META-INF/services/io.seata.config.ConfigurationProvider b/config/seata-config-nacos/src/test/resources/META-INF/services/io.seata.config.ConfigurationProvider index a06919a0cc9..019e95c5192 100644 --- a/config/seata-config-nacos/src/test/resources/META-INF/services/io.seata.config.ConfigurationProvider +++ b/config/seata-config-nacos/src/test/resources/META-INF/services/io.seata.config.ConfigurationProvider @@ -14,4 +14,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -io.seata.config.nacos.NacosConfigurationProvider \ No newline at end of file +io.seata.config.extend.NacosConfigurationProvider \ No newline at end of file diff --git a/config/seata-config-nacos/src/test/resources/META-INF/services/org.apache.seata.config.ConfigurationProvider b/config/seata-config-nacos/src/test/resources/META-INF/services/org.apache.seata.config.ConfigurationProvider new file mode 100644 index 00000000000..2332d872085 --- /dev/null +++ b/config/seata-config-nacos/src/test/resources/META-INF/services/org.apache.seata.config.ConfigurationProvider @@ -0,0 +1,17 @@ +# +# 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. +# +org.apache.seata.config.nacos.NacosConfigurationProvider \ No newline at end of file diff --git a/config/seata-config-nacos/src/test/resources/registry-mock.conf b/config/seata-config-nacos/src/test/resources/registry-mock.conf new file mode 100644 index 00000000000..a0bfd9890c1 --- /dev/null +++ b/config/seata-config-nacos/src/test/resources/registry-mock.conf @@ -0,0 +1,85 @@ +# +# 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. +# + +registry { + # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa、custom + type = "nacos" + + nacos { + application = "seata-server" + serverAddr = "console.nacos.io:80" + group = "SEATA_GROUP" + namespace = "" + username = "" + password = "" + contextPath = "/foo" + ##if use MSE Nacos with auth, mutex with username/password attribute + #accessKey = "" + #secretKey = "" + ##if use Nacos naming meta-data for SLB service registry, specify nacos address pattern rules here + #slbPattern = "" + } + eureka { + serviceUrl = "http://localhost:8761/eureka" + weight = "1" + } + redis { + serverAddr = "localhost:6379" + db = "0" + password = "" + timeout = "0" + } + zk { + serverAddr = "127.0.0.1:2181" + sessionTimeout = 6000 + connectTimeout = 2000 + username = "" + password = "" + } + consul { + serverAddr = "127.0.0.1:8500" + aclToken = "" + } + etcd3 { + serverAddr = "http://localhost:2379" + } + sofa { + serverAddr = "127.0.0.1:9603" + region = "DEFAULT_ZONE" + datacenter = "DefaultDataCenter" + group = "SEATA_GROUP" + addressWaitTime = "3000" + } + file { + name = "file.conf" + } + custom { + name = "" + } +} + +config { + # file、nacos 、apollo、zk、consul、etcd3、springCloudConfig、custom + type = "nacos" + + nacos { + serverAddr = "console.nacos.io:80" + namespace = "" + group = "SEATA_GROUP" + dataId = "seata-mock" + } +} diff --git a/config/seata-config-nacos/src/test/resources/registry.conf b/config/seata-config-nacos/src/test/resources/registry.conf index 1fbdb5694b1..2590023087f 100644 --- a/config/seata-config-nacos/src/test/resources/registry.conf +++ b/config/seata-config-nacos/src/test/resources/registry.conf @@ -21,7 +21,7 @@ registry { nacos { application = "seata-server" - serverAddr = "127.0.0.1:8848" + serverAddr = "console.nacos.io:80" group = "SEATA_GROUP" namespace = "" username = ""