diff --git a/bootstrap/bootstrap-api/src/main/java/com/alipay/sofa/rpc/bootstrap/DefaultConsumerBootstrap.java b/bootstrap/bootstrap-api/src/main/java/com/alipay/sofa/rpc/bootstrap/DefaultConsumerBootstrap.java index 9c4923243..2b661be9a 100644 --- a/bootstrap/bootstrap-api/src/main/java/com/alipay/sofa/rpc/bootstrap/DefaultConsumerBootstrap.java +++ b/bootstrap/bootstrap-api/src/main/java/com/alipay/sofa/rpc/bootstrap/DefaultConsumerBootstrap.java @@ -45,7 +45,12 @@ import com.alipay.sofa.rpc.registry.Registry; import com.alipay.sofa.rpc.registry.RegistryFactory; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.CountDownLatch; @@ -167,7 +172,7 @@ public T refer() { } //接口级别动态配置参数 - final String dynamicUrl = getOrDefault(DynamicConfigKeys.DYNAMIC_URL); + final String dynamicUrl = getOrDefault(DynamicConfigKeys.CENTER_ADDRESS); if ( StringUtils.isNotBlank(dynamicUrl)) { //启用接口级别动态配置 final DynamicConfigManager dynamicManager = DynamicConfigManagerFactory.getDynamicManagerWithUrl( @@ -453,38 +458,40 @@ private class ConsumerAttributeListener implements ConfigListener { private Map newValueMap = new HashMap<>(); // 动态配置项 - private List dynamicConfigKeys = Arrays.asList(RpcConstants.CONFIG_KEY_TIMEOUT, - RpcConstants.CONFIG_KEY_RETRIES, RpcConstants.CONFIG_KEY_LOADBALANCER); + private final Set dynamicConfigKeys = new HashSet<>(); ConsumerAttributeListener() { - + dynamicConfigKeys.add(RpcConstants.CONFIG_KEY_TIMEOUT); + dynamicConfigKeys.add(RpcConstants.CONFIG_KEY_RETRIES); + dynamicConfigKeys.add(RpcConstants.CONFIG_KEY_LOADBALANCER); } @Override public void process(ConfigChangedEvent event) { - for (String key : newValueMap.keySet()) { - newValueMap.put(key, ""); - } + // 清除上次的赋值,并保留赋值过的key + newValueMap.replaceAll((k, v) -> ""); if (!event.getChangeType().equals(ConfigChangeType.DELETED)) { // ADDED or MODIFIED - String[] lines = event.getContent().split("\n"); - for (String line : lines) { - String[] keyValue = line.split("=", 2); - if (keyValue.length == 2) { - String key = keyValue[0].trim(); - String value = keyValue[1].trim(); - for (String dynamicConfigKey : dynamicConfigKeys) { - if (key.equals(dynamicConfigKey) || key.endsWith("." + dynamicConfigKey)) { - newValueMap.put(key, value); - break; - } - } - } else { - LOGGER.warn("Malformed configuration line: {}", line); + parseConfigurationLines(event.getContent()); + } + attrUpdated(newValueMap); + } + + private void parseConfigurationLines(String content) { + String[] lines = content.split("\n"); + for (String line : lines) { + String[] keyValue = line.split("=", 2); + if (keyValue.length == 2) { + String key = keyValue[0].trim(); + String value = keyValue[1].trim(); + String tempKey = key.lastIndexOf(".") == -1 ? key : key.substring(key.lastIndexOf(".") + 1); + if (dynamicConfigKeys.contains(tempKey)) { + newValueMap.put(key, value); } + } else { + LOGGER.warn("Malformed configuration line: {}", line); } } - attrUpdated(newValueMap); } @Override diff --git a/config/config-apollo/src/main/java/com/alipay/sofa/rpc/dynamic/apollo/ApolloDynamicConfigManager.java b/config/config-apollo/src/main/java/com/alipay/sofa/rpc/dynamic/apollo/ApolloDynamicConfigManager.java index f36a23d1c..c1553a3cf 100644 --- a/config/config-apollo/src/main/java/com/alipay/sofa/rpc/dynamic/apollo/ApolloDynamicConfigManager.java +++ b/config/config-apollo/src/main/java/com/alipay/sofa/rpc/dynamic/apollo/ApolloDynamicConfigManager.java @@ -29,6 +29,7 @@ import com.ctrip.framework.apollo.model.ConfigChange; import java.util.Collections; +import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -71,16 +72,10 @@ protected ApolloDynamicConfigManager(String appName, String remainUrl) { super(appName, remainUrl); System.setProperty(APOLLO_APPID_KEY, appName); System.setProperty(APOLLO_ADDR_KEY, APOLLO_PROTOCOL_PREFIX + getAddress()); - String params[] = getParams(); - if (params!= null && params.length > 0){ - for (String param : params) { - String[] keyValue = param.split("="); - if (keyValue.length == 2) { - if ("cluster".equals(keyValue[0])) { - System.setProperty(APOLLO_CLUSTER_KEY, keyValue[1]); - } - } - } + Map params = getParams(); + if (params != null && params.containsKey("cluster")) { + String clusterValue = (String)params.get("cluster"); + System.setProperty(APOLLO_CLUSTER_KEY, clusterValue); } config = ConfigService.getAppConfig(); } @@ -158,6 +153,9 @@ private ConfigChangeType getChangeType(ConfigChange change) { if (change.getChangeType() == PropertyChangeType.DELETED) { return ConfigChangeType.DELETED; } + if (change.getChangeType() == PropertyChangeType.ADDED) { + return ConfigChangeType.ADDED; + } return ConfigChangeType.MODIFIED; } diff --git a/config/config-nacos/src/main/java/com/alipay/sofa/rpc/dynamic/nacos/NacosDynamicConfigManager.java b/config/config-nacos/src/main/java/com/alipay/sofa/rpc/dynamic/nacos/NacosDynamicConfigManager.java index fc6e92ca8..afb81188c 100644 --- a/config/config-nacos/src/main/java/com/alipay/sofa/rpc/dynamic/nacos/NacosDynamicConfigManager.java +++ b/config/config-nacos/src/main/java/com/alipay/sofa/rpc/dynamic/nacos/NacosDynamicConfigManager.java @@ -73,17 +73,15 @@ protected NacosDynamicConfigManager(String appName, String remainUrl) { super(appName, remainUrl); group = appName; nacosConfig.put(PropertyKeyConst.SERVER_ADDR, getAddress()); - String params[] = getParams(); - if (params != null && params.length > 0) { - for (String param : params) { - String[] keyValue = param.split("="); - if (keyValue.length == 2) { - if ("username".equals(keyValue[0])) { - nacosConfig.put(PropertyKeyConst.USERNAME, keyValue[1]); - } else if ("password".equals(keyValue[0])) { - nacosConfig.put(PropertyKeyConst.PASSWORD, keyValue[1]); - } - } + Map params = getParams(); + if (params != null) { + if( params.containsKey("username")) { + String username = (String)params.get("username"); + nacosConfig.put(PropertyKeyConst.USERNAME, username); + } + if( params.containsKey("password")) { + String password = (String) params.get("password"); + nacosConfig.put(PropertyKeyConst.PASSWORD, password); } } try { diff --git a/core/api/src/main/java/com/alipay/sofa/rpc/dynamic/DynamicConfigKeys.java b/core/api/src/main/java/com/alipay/sofa/rpc/dynamic/DynamicConfigKeys.java index 581c7c55e..754afe468 100644 --- a/core/api/src/main/java/com/alipay/sofa/rpc/dynamic/DynamicConfigKeys.java +++ b/core/api/src/main/java/com/alipay/sofa/rpc/dynamic/DynamicConfigKeys.java @@ -29,13 +29,13 @@ public class DynamicConfigKeys { public static final String DEFAULT_NAMESPACE = "sofa-rpc"; - public static ConfigKey DYNAMIC_URL = ConfigKey + public static ConfigKey CENTER_ADDRESS = ConfigKey .build( - "dynamicUrl", + "sofa.rpc.config.center.address", " ", false, "The url of the dynamic configuration.", - new String[] { "dynamicUrl" }); + new String[] { "sofa_rpc_config_center_address" }); public static ConfigKey ZK_ADDRESS = ConfigKey .build( @@ -43,7 +43,7 @@ public class DynamicConfigKeys { "127.0.0.1:2181", false, "The address of Zookeeper configuration center.", - new String[] { "zookeeper_address" }); + new String[] { "sofa_rpc_config_center_zookeeper_address" }); public static ConfigKey NACOS_ADDRESS = ConfigKey .build( @@ -51,13 +51,13 @@ public class DynamicConfigKeys { "127.0.0.1:8848", false, "The address of Nacos configuration center.", - new String[] { "nacos_address" }); + new String[] { "sofa_rpc_config_center_nacos_address" }); public static ConfigKey APOLLO_ADDRESS = ConfigKey .build( "sofa.rpc.config.center.apollo.address", "127.0.0.1:8080", false, "The address of Apollo configuration center.", - new String[] { "apollo_address" }); + new String[] { "sofa_rpc_config_center_apollo_address" }); } \ No newline at end of file diff --git a/core/api/src/main/java/com/alipay/sofa/rpc/dynamic/DynamicConfigManager.java b/core/api/src/main/java/com/alipay/sofa/rpc/dynamic/DynamicConfigManager.java index 7fda9f36d..49099d09e 100644 --- a/core/api/src/main/java/com/alipay/sofa/rpc/dynamic/DynamicConfigManager.java +++ b/core/api/src/main/java/com/alipay/sofa/rpc/dynamic/DynamicConfigManager.java @@ -20,6 +20,9 @@ import com.alipay.sofa.rpc.ext.Extensible; import com.alipay.sofa.rpc.listener.ConfigListener; +import java.util.HashMap; +import java.util.Map; + /** * * @author bystander @@ -32,15 +35,25 @@ public abstract class DynamicConfigManager { private String address; - private String params[]; + private Map params = new HashMap<>(); protected DynamicConfigManager(String appName, String remainUrl) { this.appName = appName; + parseRemainUrl(remainUrl); + } + + protected void parseRemainUrl(String remainUrl) { int queryIndex = remainUrl.indexOf("?"); this.address = (queryIndex > -1) ? remainUrl.substring(0, queryIndex) : remainUrl; if (queryIndex > -1 && queryIndex < remainUrl.length() - 1) { String query = remainUrl.substring(queryIndex + 1); - this.params = query.split("&"); + String[] paramPairs = query.split("&"); + for (String paramPair : paramPairs) { + String[] keyValue = paramPair.split("="); + if (keyValue.length == 2) { + this.params.put(keyValue[0], keyValue[1]); + } + } } } @@ -52,7 +65,7 @@ protected String getAddress() { return address; } - protected String[] getParams() { + protected Map getParams() { return params; } diff --git a/test/test-integration/pom.xml b/test/test-integration/pom.xml index 32adfe74b..6e3d254a3 100644 --- a/test/test-integration/pom.xml +++ b/test/test-integration/pom.xml @@ -264,13 +264,13 @@ com.alipay.sofa sofa-rpc-config-apollo - 5.13.1-SNAPSHOT + ${project.parent.version} test com.alipay.sofa sofa-rpc-config-zk - 5.13.1-SNAPSHOT + ${project.parent.version} test diff --git a/test/test-integration/src/test/java/com/alipay/sofa/rpc/test/config/ApolloDynamicConfigTest.java b/test/test-integration/src/test/java/com/alipay/sofa/rpc/test/config/ApolloDynamicConfigTest.java index f72a5c362..e09241130 100644 --- a/test/test-integration/src/test/java/com/alipay/sofa/rpc/test/config/ApolloDynamicConfigTest.java +++ b/test/test-integration/src/test/java/com/alipay/sofa/rpc/test/config/ApolloDynamicConfigTest.java @@ -41,7 +41,7 @@ public class ApolloDynamicConfigTest { @Test public void testApolloDynamicConfig() throws Exception { - System.setProperty(DynamicConfigKeys.DYNAMIC_URL.getKey(), "apollo://127.0.0.1:8080"); + System.setProperty(DynamicConfigKeys.CENTER_ADDRESS.getKey(), "apollo://127.0.0.1:8080?cluster=default"); ApplicationConfig clientApplication = new ApplicationConfig(); clientApplication.setAppName("demo"); @@ -56,7 +56,7 @@ public void testApolloDynamicConfig() throws Exception { // 获取接口对应的动态配置监听器 DynamicConfigManager dynamicConfigManager = DynamicConfigManagerFactory.getDynamicManagerWithUrl - (clientApplication.getAppName(), System.getProperty(DynamicConfigKeys.DYNAMIC_URL.getKey())); + (clientApplication.getAppName(), System.getProperty(DynamicConfigKeys.CENTER_ADDRESS.getKey())); Field field = ApolloDynamicConfigManager.class.getDeclaredField("watchListenerMap"); field.setAccessible(true); Map watchListenerMap = (Map) field @@ -64,13 +64,33 @@ public void testApolloDynamicConfig() throws Exception { ApolloDynamicConfigManager.ApolloListener apolloConfigListener = watchListenerMap.get(consumerConfig .getInterfaceId()); - // 测试配置更新 - String configValue = "timeout=5000\n.sayHello.timeout=6000"; + // 测试配置新增 + String configValue = "timeout=5000\n"; ConfigChange configChange = new ConfigChange("application", consumerConfig.getInterfaceId(), null, configValue, PropertyChangeType.ADDED); Map changes= new HashMap<>(); changes.put(configChange.getPropertyName(), configChange); ConfigChangeEvent event = new ConfigChangeEvent("application",changes); apolloConfigListener.onChange(event); + Assert.assertEquals(5000, consumerConfig.getMethodTimeout("sayHello")); + + // 测试配置修改 + String oldValue = configValue; + configValue = "timeout=5000\n.sayHello.timeout=6000"; + configChange = new ConfigChange("application", consumerConfig.getInterfaceId(), oldValue, configValue, PropertyChangeType.MODIFIED); + changes= new HashMap<>(); + changes.put(configChange.getPropertyName(), configChange); + event = new ConfigChangeEvent("application",changes); + apolloConfigListener.onChange(event); Assert.assertEquals(6000, consumerConfig.getMethodTimeout("sayHello")); + + // 测试配置删除 + configChange = new ConfigChange("application", consumerConfig.getInterfaceId(), configValue, null, PropertyChangeType.DELETED); + changes= new HashMap<>(); + changes.put(configChange.getPropertyName(), configChange); + event = new ConfigChangeEvent("application",changes); + apolloConfigListener.onChange(event); + Assert.assertEquals(-1, consumerConfig.getMethodTimeout("sayHello")); + + System.clearProperty(DynamicConfigKeys.CENTER_ADDRESS.getKey()); } } diff --git a/test/test-integration/src/test/java/com/alipay/sofa/rpc/test/config/NacosDynamicConfigTest.java b/test/test-integration/src/test/java/com/alipay/sofa/rpc/test/config/NacosDynamicConfigTest.java index a95ee2a39..bc6e5b0bb 100644 --- a/test/test-integration/src/test/java/com/alipay/sofa/rpc/test/config/NacosDynamicConfigTest.java +++ b/test/test-integration/src/test/java/com/alipay/sofa/rpc/test/config/NacosDynamicConfigTest.java @@ -38,7 +38,8 @@ public class NacosDynamicConfigTest { @Test public void testNacosDynamicConfig() throws Exception { - System.setProperty(DynamicConfigKeys.DYNAMIC_URL.getKey(), "nacos://127.0.0.1:8848"); + System.setProperty(DynamicConfigKeys.CENTER_ADDRESS.getKey(), + "nacos://127.0.0.1:8848?username=nacos&password=nacos"); ApplicationConfig clientApplication = new ApplicationConfig(); clientApplication.setAppName("demo"); @@ -53,7 +54,7 @@ public void testNacosDynamicConfig() throws Exception { // 获取接口对应的动态配置监听器 DynamicConfigManager dynamicConfigManager = DynamicConfigManagerFactory.getDynamicManagerWithUrl - (clientApplication.getAppName(), System.getProperty(DynamicConfigKeys.DYNAMIC_URL.getKey())); + (clientApplication.getAppName(), System.getProperty(DynamicConfigKeys.CENTER_ADDRESS.getKey())); Field field = NacosDynamicConfigManager.class.getDeclaredField("watchListenerMap"); field.setAccessible(true); Map watchListenerMap = (Map) field @@ -61,12 +62,19 @@ public void testNacosDynamicConfig() throws Exception { NacosDynamicConfigManager.NacosConfigListener nacosConfigListener = watchListenerMap.get(consumerConfig .getInterfaceId()); - // 测试配置更新 + // 测试配置新增 String configValue = "timeout=5000"; nacosConfigListener.innerReceive(consumerConfig.getInterfaceId(), consumerConfig.getAppName(), configValue); Assert.assertEquals(5000, consumerConfig.getMethodTimeout("sayHello")); + // 测试配置修改 configValue = "timeout=5000\n.sayHello.timeout=6000"; nacosConfigListener.innerReceive(consumerConfig.getInterfaceId(), consumerConfig.getAppName(), configValue); Assert.assertEquals(6000, consumerConfig.getMethodTimeout("sayHello")); + // 测试配置删除 + configValue = ""; + nacosConfigListener.innerReceive(consumerConfig.getInterfaceId(), consumerConfig.getAppName(), configValue); + Assert.assertEquals(-1, consumerConfig.getMethodTimeout("sayHello")); + + System.clearProperty(DynamicConfigKeys.CENTER_ADDRESS.getKey()); } } diff --git a/test/test-integration/src/test/java/com/alipay/sofa/rpc/test/config/ZookeeperDynamicConfigTest.java b/test/test-integration/src/test/java/com/alipay/sofa/rpc/test/config/ZookeeperDynamicConfigTest.java index 224b1489f..1ce3973c7 100644 --- a/test/test-integration/src/test/java/com/alipay/sofa/rpc/test/config/ZookeeperDynamicConfigTest.java +++ b/test/test-integration/src/test/java/com/alipay/sofa/rpc/test/config/ZookeeperDynamicConfigTest.java @@ -22,6 +22,8 @@ import com.alipay.sofa.rpc.dynamic.DynamicConfigManager; import com.alipay.sofa.rpc.dynamic.DynamicConfigManagerFactory; import com.alipay.sofa.rpc.dynamic.zk.ZookeeperDynamicConfigManager; +import com.alipay.sofa.rpc.log.Logger; +import com.alipay.sofa.rpc.log.LoggerFactory; import com.alipay.sofa.rpc.test.HelloService; import com.alipay.sofa.rpc.test.config.base.BaseZkTest; import org.apache.curator.framework.CuratorFramework; @@ -37,9 +39,11 @@ */ public class ZookeeperDynamicConfigTest extends BaseZkTest { + Logger logger = LoggerFactory.getLogger(ZookeeperDynamicConfigTest.class); + @Test public void testZookeeperDynamicConfig() throws Exception { - System.setProperty(DynamicConfigKeys.DYNAMIC_URL.getKey(), "zookeeper://127.0.0.1:2181"); + System.setProperty(DynamicConfigKeys.CENTER_ADDRESS.getKey(), "zookeeper://127.0.0.1:2181"); ApplicationConfig clientApplication = new ApplicationConfig(); clientApplication.setAppName("demo"); @@ -53,28 +57,40 @@ public void testZookeeperDynamicConfig() throws Exception { consumerConfig.refer(); DynamicConfigManager dynamicConfigManager = DynamicConfigManagerFactory.getDynamicManagerWithUrl - (clientApplication.getAppName(), System.getProperty(DynamicConfigKeys.DYNAMIC_URL.getKey())); + (clientApplication.getAppName(), System.getProperty(DynamicConfigKeys.CENTER_ADDRESS.getKey())); Field field = ZookeeperDynamicConfigManager.class.getDeclaredField("zkClient"); field.setAccessible(true); CuratorFramework zkClient = (CuratorFramework) field.get(dynamicConfigManager); - // 创建或更新配置节点 + + // 新增或修改配置节点 if (zkClient.checkExists().forPath("/config/demo/com.alipay.sofa.rpc.test.HelloService") == null) { zkClient.create() .creatingParentsIfNeeded() .withMode(CreateMode.PERSISTENT) .forPath("/config/demo/com.alipay.sofa.rpc.test.HelloService", "timeout=5000".getBytes()); } else { - zkClient.setData().forPath("/sofa-rpc/config/demo/com.alipay.sofa.rpc.test.HelloService", + zkClient.setData().forPath("/config/demo/com.alipay.sofa.rpc.test.HelloService", "timeout=5000".getBytes()); } - try { Thread.sleep(3000); } catch (InterruptedException e) { - e.printStackTrace(); + logger.error(e.getMessage(), e); } // 验证配置是否更新 Assert.assertEquals(5000, consumerConfig.getMethodTimeout("sayHello")); + //删除配置节点 + zkClient.delete().forPath("/config/demo/com.alipay.sofa.rpc.test.HelloService"); + try { + Thread.sleep(3000); + } catch (InterruptedException e) { + logger.error(e.getMessage(), e); + } + // 验证配置是否删除 + Assert.assertEquals(-1, consumerConfig.getMethodTimeout("sayHello")); + + System.clearProperty(DynamicConfigKeys.CENTER_ADDRESS.getKey()); + } }