From 240ee50aa2efd577a9dc691ca01fa5378b2d7537 Mon Sep 17 00:00:00 2001 From: chuntaojun Date: Sat, 15 Jun 2019 19:12:54 +0800 Subject: [PATCH] fix(nacos-client:config): fix issue 1317 --- .../nacos/api/config/ConfigService.java | 12 ++++++ .../client/config/NacosConfigService.java | 14 +++++++ .../nacos/client/config/impl/CacheData.java | 6 ++- .../client/config/impl/ClientWorker.java | 10 +++++ .../nacos/test/config/ConfigAPI_ITCase.java | 38 +++++++++++++++++++ 5 files changed, 79 insertions(+), 1 deletion(-) 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 3e79f950c..13a8eac25 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 @@ -36,6 +36,18 @@ public interface ConfigService { */ String getConfig(String dataId, String group, long timeoutMs) throws NacosException; + /** + * Get config + * + * @param dataId dataId + * @param group group + * @param timeoutMs read timeout + * @param listener {@link Listener} + * @return config value + * @throws NacosException NacosException + */ + String getConfigAndSignListener(String dataId, String group, long timeoutMs, Listener listener) throws NacosException; + /** * Add a listener to the configuration, after the server modified the * configuration, the client will use the incoming listener callback. 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 9d2be89bd..85d82c37a 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 @@ -27,6 +27,7 @@ import com.alibaba.nacos.client.config.filter.impl.ConfigResponse; import com.alibaba.nacos.client.config.http.HttpAgent; import com.alibaba.nacos.client.config.http.MetricsHttpAgent; import com.alibaba.nacos.client.config.http.ServerHttpAgent; +import com.alibaba.nacos.client.config.impl.CacheData; import com.alibaba.nacos.client.config.impl.ClientWorker; import com.alibaba.nacos.client.config.impl.HttpSimpleClient.HttpResult; import com.alibaba.nacos.client.config.impl.LocalConfigInfoProcessor; @@ -122,6 +123,13 @@ public class NacosConfigService implements ConfigService { return getConfigInner(namespace, dataId, group, timeoutMs); } + @Override + public String getConfigAndSignListener(String dataId, String group, long timeoutMs, Listener listener) throws NacosException { + String content = getConfig(dataId, group, timeoutMs); + worker.addTenantListenersWithContent(dataId, group, content, Arrays.asList(listener)); + return content; + } + @Override public void addListener(String dataId, String group, Listener listener) throws NacosException { worker.addTenantListeners(dataId, group, Arrays.asList(listener)); @@ -166,6 +174,12 @@ public class NacosConfigService implements ConfigService { content = worker.getServerConfig(dataId, group, tenant, timeoutMs); 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 47c1d262d..67cbb3fd2 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 @@ -66,6 +66,7 @@ public class CacheData { /** * Add listener + * if CacheData already set new content, Listener should init lastCallMd5 by CacheData.md5 * * @param listener listener */ @@ -74,6 +75,7 @@ public class CacheData { throw new IllegalArgumentException("listener is null"); } ManagerListenerWrap wrap = new ManagerListenerWrap(listener); + wrap.lastCallMd5 = md5; if (listeners.addIfAbsent(wrap)) { LOGGER.info("[{}] [add-listener] ok, tenant={}, dataId={}, group={}, cnt={}", name, tenant, dataId, group, listeners.size()); @@ -167,6 +169,8 @@ public class CacheData { final Listener listener = listenerWrap.listener; Runnable job = new Runnable() { + + @Override public void run() { ClassLoader myClassLoader = Thread.currentThread().getContextClassLoader(); ClassLoader appClassLoader = listener.getClass().getClassLoader(); @@ -284,7 +288,7 @@ public class CacheData { class ManagerListenerWrap { final Listener listener; - String lastCallMd5 = CacheData.getMd5String(null); + volatile String lastCallMd5 = CacheData.getMd5String(null); ManagerListenerWrap(Listener listener) { this.listener = listener; 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 a7665f051..93022337d 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 @@ -91,6 +91,16 @@ public class ClientWorker { } } + public void addTenantListenersWithContent(String dataId, String group, String content, List listeners) { + group = null2defaultGroup(group); + String tenant = agent.getTenant(); + CacheData cache = addCacheDataIfAbsent(dataId, group, tenant); + cache.setContent(content); + for (Listener listener : listeners) { + cache.addListener(listener); + } + } + public void removeTenantListener(String dataId, String group, Listener listener) { group = null2defaultGroup(group); String tenant = agent.getTenant(); 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 103fce8dd..5fc386106 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 @@ -435,6 +435,44 @@ public class ConfigAPI_ITCase { 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_5() throws InterruptedException, NacosException { + 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(3000); + + Listener ml = new AbstractListener() { + @Override + public void receiveConfigInfo(String configInfo) { + count.incrementAndGet(); + System.out.println("Listener receive : [" + configInfo + "]"); + Assert.assertEquals(content, newContent); + } + }; + String receiveContent = iconfig.getConfigAndSignListener(dataId, group, 1000, ml); + System.out.println(receiveContent); + + result = iconfig.publishConfig(dataId, group, newContent); + Assert.assertTrue(result); + + Assert.assertEquals(content, receiveContent); + Thread.sleep(3000); + + Assert.assertEquals(1, count.get()); + iconfig.removeListener(dataId, group, ml); + } + /** * @TCDescription : nacos_正常移除监听器 * @TestStep : TODO Test steps