From 326fb7250c8b6e175785167da6ea1188a7582cd5 Mon Sep 17 00:00:00 2001
From: Albumen Kevin <jhq0812@gmail.com>
Date: Wed, 21 Dec 2022 23:38:49 +0800
Subject: [PATCH] Fix Nacos ServiceName error (#11180)

---
 .../dubbo/registry/nacos/NacosRegistry.java   | 60 +++++++++----------
 1 file changed, 30 insertions(+), 30 deletions(-)

diff --git a/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosRegistry.java b/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosRegistry.java
index af356373ee2..4aba61cf02c 100644
--- a/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosRegistry.java
+++ b/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosRegistry.java
@@ -38,19 +38,19 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.LinkedHashSet;
 import java.util.LinkedList;
 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.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ConcurrentHashMap;
 import java.util.stream.Collectors;
-import java.util.Collections;
 
 import static org.apache.dubbo.common.constants.CommonConstants.ANY_VALUE;
 import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
@@ -123,7 +123,7 @@ public class NacosRegistry extends FailbackRegistry {
 
     private final NacosNamingServiceWrapper namingService;
 
-    private final ConcurrentMap<URL, ConcurrentMap<NotifyListener, EventListener>> nacosListeners = new ConcurrentHashMap<>();
+    private final ConcurrentMap<URL, Map<NotifyListener, Map<String, EventListener>>> nacosListeners = new ConcurrentHashMap<>();
 
     public NacosRegistry(URL url, NacosNamingServiceWrapper namingService) {
         super(url);
@@ -242,8 +242,7 @@ private boolean isServiceNamesWithCompatibleMode(final URL url) {
     public void doUnsubscribe(URL url, NotifyListener listener) {
         if (isAdminProtocol(url)) {
             shutdownServiceNamesLookup();
-        }
-        else {
+        } else {
             Set<String> serviceNames = getServiceNames(url, listener);
 
             doUnsubscribe(url, listener, serviceNames);
@@ -305,7 +304,7 @@ private Set<String> filterServiceNames(NacosServiceName serviceName) {
         Set<String> serviceNames = new LinkedHashSet<>();
 
         execute(namingService -> serviceNames.addAll(namingService.getServicesOfServer(1, Integer.MAX_VALUE,
-                getUrl().getParameter(GROUP_KEY, Constants.DEFAULT_GROUP)).getData()
+                        getUrl().getParameter(GROUP_KEY, Constants.DEFAULT_GROUP)).getData()
                 .stream()
                 .filter(this::isConformRules)
                 .map(NacosServiceName::new)
@@ -511,27 +510,24 @@ private List<URL> buildURLs(URL consumerURL, Collection<Instance> instances) {
 
     private void subscribeEventListener(String serviceName, final URL url, final NotifyListener listener)
             throws NacosException {
-        ConcurrentMap<NotifyListener, EventListener> listeners = nacosListeners.computeIfAbsent(url, k -> new ConcurrentHashMap<>());
-        EventListener nacosListener = listeners.computeIfAbsent(listener, k -> {
-            EventListener eventListener = event -> {
-                if (event instanceof NamingEvent) {
-                    NamingEvent e = (NamingEvent) event;
-                    List<Instance> instances = e.getInstances();
-
-
-                    if (isServiceNamesWithCompatibleMode(url)) {
+        Map<NotifyListener, Map<String, EventListener>> listeners = nacosListeners.computeIfAbsent(url, k -> new ConcurrentHashMap<>());
+        Map<String, EventListener> eventListenerMap = listeners.computeIfAbsent(listener, k -> new ConcurrentHashMap<>());
+        EventListener nacosListener = eventListenerMap.computeIfAbsent(serviceName,
+                name -> event -> {
+                    if (event instanceof NamingEvent) {
+                        NamingEvent e = (NamingEvent) event;
+                        List<Instance> instances = e.getInstances();
+                        if (isServiceNamesWithCompatibleMode(url)) {
+
+                            // Get all instances with corresponding serviceNames to avoid instance overwrite and but with empty instance mentioned
+                            // in https://github.com/apache/dubbo/issues/5885 and https://github.com/apache/dubbo/issues/5899
+                            NacosInstanceManageUtil.initOrRefreshServiceInstanceList(name, instances);
+                            instances = NacosInstanceManageUtil.getAllCorrespondingServiceInstanceList(name);
+                        }
 
-                        // Get all instances with corresponding serviceNames to avoid instance overwrite and but with empty instance mentioned
-                        // in https://github.com/apache/dubbo/issues/5885 and https://github.com/apache/dubbo/issues/5899
-                        NacosInstanceManageUtil.initOrRefreshServiceInstanceList(e.getServiceName(), instances);
-                        instances = NacosInstanceManageUtil.getAllCorrespondingServiceInstanceList(e.getServiceName());
+                        notifySubscriber(url, listener, instances);
                     }
-
-                    notifySubscriber(url, listener, instances);
-                }
-            };
-            return eventListener;
-        });
+                });
         namingService.subscribe(serviceName,
                 getUrl().getParameter(GROUP_KEY, Constants.DEFAULT_GROUP),
                 nacosListener);
@@ -539,12 +535,16 @@ private void subscribeEventListener(String serviceName, final URL url, final Not
 
     private void unsubscribeEventListener(String serviceName, final URL url, final NotifyListener listener)
             throws NacosException {
-        ConcurrentMap<NotifyListener, EventListener> notifyListenerEventListenerConcurrentMap = nacosListeners.get(url);
-        if(notifyListenerEventListenerConcurrentMap == null){
+        Map<NotifyListener, Map<String, EventListener>> notifyListenerEventListenerConcurrentMap = nacosListeners.get(url);
+        if (notifyListenerEventListenerConcurrentMap == null) {
+            return;
+        }
+        Map<String, EventListener> listenerMap = notifyListenerEventListenerConcurrentMap.get(listener);
+        if (listenerMap == null) {
             return;
         }
-        EventListener nacosListener = notifyListenerEventListenerConcurrentMap.get(listener);
-        if(nacosListener == null){
+        EventListener nacosListener = listenerMap.remove(serviceName);
+        if (nacosListener == null) {
             return;
         }
         namingService.unsubscribe(serviceName,