diff --git a/api/src/main/java/com/alibaba/nacos/api/PropertyKeyConst.java b/api/src/main/java/com/alibaba/nacos/api/PropertyKeyConst.java index 984591bdf..de42befe5 100644 --- a/api/src/main/java/com/alibaba/nacos/api/PropertyKeyConst.java +++ b/api/src/main/java/com/alibaba/nacos/api/PropertyKeyConst.java @@ -52,6 +52,8 @@ public class PropertyKeyConst { public final static String MAX_RETRY = "maxRetry"; + public final static String ENABLE_REMOTE_SYNC_CONFIG = "enableRemoteSyncConfig"; + public final static String NAMING_LOAD_CACHE_AT_START = "namingLoadCacheAtStart"; public final static String NAMING_CLIENT_BEAT_THREAD_COUNT = "namingClientBeatThreadCount"; diff --git a/api/src/main/java/com/alibaba/nacos/api/config/ConfigService.java b/api/src/main/java/com/alibaba/nacos/api/config/ConfigService.java index 13a8eac25..7da577f1d 100644 --- a/api/src/main/java/com/alibaba/nacos/api/config/ConfigService.java +++ b/api/src/main/java/com/alibaba/nacos/api/config/ConfigService.java @@ -37,7 +37,7 @@ public interface ConfigService { String getConfig(String dataId, String group, long timeoutMs) throws NacosException; /** - * Get config + * Get config and register Listener * * @param dataId dataId * @param group group diff --git a/client/src/main/java/com/alibaba/nacos/client/config/NacosConfigService.java b/client/src/main/java/com/alibaba/nacos/client/config/NacosConfigService.java index 85d82c37a..a6ce0c79c 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/NacosConfigService.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/NacosConfigService.java @@ -175,11 +175,6 @@ public class NacosConfigService implements ConfigService { cr.setContent(content); - CacheData cacheData = worker.getCache(dataId, group, tenant); - if (cacheData != null) { - cacheData.setContent(content); - } - configFilterChainManager.doFilter(null, cr); content = cr.getContent(); diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java index 67cbb3fd2..aa05cac49 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/CacheData.java @@ -23,6 +23,7 @@ import com.alibaba.nacos.client.config.filter.impl.ConfigFilterChainManager; import com.alibaba.nacos.client.config.filter.impl.ConfigResponse; import com.alibaba.nacos.client.config.utils.MD5; import com.alibaba.nacos.client.utils.LogUtils; +import com.alibaba.nacos.client.utils.StringUtils; import com.alibaba.nacos.client.utils.TenantUtil; import org.slf4j.Logger; @@ -74,8 +75,7 @@ public class CacheData { if (null == listener) { throw new IllegalArgumentException("listener is null"); } - ManagerListenerWrap wrap = new ManagerListenerWrap(listener); - wrap.lastCallMd5 = md5; + ManagerListenerWrap wrap = new ManagerListenerWrap(listener, md5); if (listeners.addIfAbsent(wrap)) { LOGGER.info("[{}] [add-listener] ok, tenant={}, dataId={}, group={}, cnt={}", name, tenant, dataId, group, listeners.size()); @@ -263,6 +263,22 @@ public class CacheData { this.md5 = getMd5String(content); } + public CacheData(ConfigFilterChainManager configFilterChainManager, String name, String dataId, String group, + String tenant, String content) { + if (null == dataId || null == group) { + throw new IllegalArgumentException("dataId=" + dataId + ", group=" + group); + } + this.name = name; + this.configFilterChainManager = configFilterChainManager; + this.dataId = dataId; + this.group = group; + this.tenant = tenant; + listeners = new CopyOnWriteArrayList(); + this.isInitializing = true; + this.content = StringUtils.isEmpty(content) ? loadCacheContentFromDiskLocal(name, dataId, group, tenant) : content; + this.md5 = getMd5String(content); + } + // ================== private final String name; @@ -294,6 +310,11 @@ class ManagerListenerWrap { this.listener = listener; } + ManagerListenerWrap(Listener listener, String md5) { + this.listener = listener; + this.lastCallMd5 = md5; + } + @Override public boolean equals(Object obj) { if (null == obj || obj.getClass() != getClass()) { diff --git a/client/src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java b/client/src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java index 93022337d..221b0d2ce 100644 --- a/client/src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java +++ b/client/src/main/java/com/alibaba/nacos/client/config/impl/ClientWorker.java @@ -177,7 +177,6 @@ public class ClientWorker { return cache; } String key = GroupKey.getKeyTenant(dataId, group, tenant); - cache = new CacheData(configFilterChainManager, agent.getName(), dataId, group, tenant); synchronized (cacheMap) { CacheData cacheFromMap = getCache(dataId, group, tenant); // multiple listeners on the same dataid+group and race condition,so @@ -187,6 +186,18 @@ public class ClientWorker { cache = cacheFromMap; // reset so that server not hang this check cache.setInitializing(true); + } else { + cache = new CacheData(configFilterChainManager, agent.getName(), dataId, group, tenant); + String content; + // fix issue # 1317 + if (enableRemoteSyncConfig) { + try { + content = getServerConfig(dataId, group, tenant, 3000L); + } catch (NacosException ignore) { + content = null; + } + cache.setContent(content); + } } Map copy = new HashMap(cacheMap.get()); @@ -471,6 +482,8 @@ public class ClientWorker { Constants.CONFIG_LONG_POLL_TIMEOUT), Constants.MIN_CONFIG_LONG_POLL_TIMEOUT); taskPenaltyTime = NumberUtils.toInt(String.valueOf(properties.get(PropertyKeyConst.CONFIG_RETRY_TIME)), Constants.CONFIG_RETRY_TIME); + + enableRemoteSyncConfig = Boolean.parseBoolean(properties.getProperty(PropertyKeyConst.ENABLE_REMOTE_SYNC_CONFIG)); } class LongPollingRunnable implements Runnable { @@ -569,4 +582,5 @@ public class ClientWorker { private long timeout; private double currentLongingTaskCount = 0; private int taskPenaltyTime; + private boolean enableRemoteSyncConfig = false; } diff --git a/test/src/test/java/com/alibaba/nacos/test/config/ConfigAPI_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/config/ConfigAPI_ITCase.java index 5fc386106..837a6cce9 100644 --- a/test/src/test/java/com/alibaba/nacos/test/config/ConfigAPI_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/config/ConfigAPI_ITCase.java @@ -436,7 +436,7 @@ public class ConfigAPI_ITCase { } /** - * @TCDescription : nacos_在主动拉取配置后并注册Listener,在更新配置后才触发Listener监听事件 + * @TCDescription : nacos_在主动拉取配置后并注册Listener,在更新配置后才触发Listener监听事件(使用特定接口) * @TestStep : TODO Test steps * @ExpectResult : TODO expect results * @author xiaochun.xxc @@ -450,7 +450,7 @@ public class ConfigAPI_ITCase { boolean result = iconfig.publishConfig(dataId, group, content); Assert.assertTrue(result); - Thread.sleep(3000); + Thread.sleep(2000); Listener ml = new AbstractListener() { @Override @@ -460,6 +460,7 @@ public class ConfigAPI_ITCase { Assert.assertEquals(content, newContent); } }; + String receiveContent = iconfig.getConfigAndSignListener(dataId, group, 1000, ml); System.out.println(receiveContent); @@ -467,7 +468,58 @@ public class ConfigAPI_ITCase { Assert.assertTrue(result); Assert.assertEquals(content, receiveContent); - Thread.sleep(3000); + Thread.sleep(2000); + + Assert.assertEquals(1, count.get()); + iconfig.removeListener(dataId, group, ml); + } + + /** + * @TCDescription : nacos_在主动拉取配置后并注册Listener,在更新配置后才触发Listener监听事件(进行配置参数设置) + * @TestStep : TODO Test steps + * @ExpectResult : TODO expect results + * @author xiaochun.xxc + * @since 3.6.8 + */ + @Test + public void nacos_addListener_6() throws InterruptedException, NacosException { + + Properties properties = new Properties(); + properties.put(PropertyKeyConst.SERVER_ADDR, "127.0.0.1"+":"+port); + properties.put(PropertyKeyConst.ENABLE_REMOTE_SYNC_CONFIG, "true"); + ConfigService iconfig = NacosFactory.createConfigService(properties); + + final AtomicInteger count = new AtomicInteger(0); + final String content = "test-abc"; + final String newContent = "new-test-def"; + boolean result = iconfig.publishConfig(dataId, group, content); + Assert.assertTrue(result); + + Thread.sleep(2000); + + Listener ml = new AbstractListener() { + @Override + public void receiveConfigInfo(String configInfo) { + count.incrementAndGet(); + System.out.println("Listener receive : [" + configInfo + "]"); + Assert.assertEquals(content, newContent); + } + }; + + iconfig.addListener(dataId, group, ml); + + String receiveContent = iconfig.getConfig(dataId, group, 1000); + + System.out.println(receiveContent); + + result = iconfig.publishConfig(dataId, group, newContent); + Assert.assertTrue(result); + + Thread.sleep(2000); + + receiveContent = iconfig.getConfig(dataId, group, 1000); + + Assert.assertEquals(newContent, receiveContent); Assert.assertEquals(1, count.get()); iconfig.removeListener(dataId, group, ml); diff --git a/test/src/test/java/com/alibaba/nacos/test/config/ConfigLongPoll_ITCase.java b/test/src/test/java/com/alibaba/nacos/test/config/ConfigLongPoll_ITCase.java index c50fd92da..fb45d8830 100644 --- a/test/src/test/java/com/alibaba/nacos/test/config/ConfigLongPoll_ITCase.java +++ b/test/src/test/java/com/alibaba/nacos/test/config/ConfigLongPoll_ITCase.java @@ -82,7 +82,7 @@ public class ConfigLongPoll_ITCase { } }); - TimeUnit.SECONDS.sleep(30); + TimeUnit.SECONDS.sleep(10); }