This is an automated email from the ASF dual-hosted git repository.

liujun pushed a commit to branch 3.1
in repository https://gitbox.apache.org/repos/asf/dubbo.git


The following commit(s) were added to refs/heads/3.1 by this push:
     new 671c7ff950 Enhance nacos regsitry (#11262)
671c7ff950 is described below

commit 671c7ff9506982efa2054b3b8de0f97940bb1af5
Author: Albumen Kevin <[email protected]>
AuthorDate: Wed Jan 11 11:04:52 2023 +0800

    Enhance nacos regsitry (#11262)
---
 .../registry/nacos/NacosNamingServiceWrapper.java  | 102 +++++++-
 .../registry/nacos/NacosServiceDiscovery.java      |  29 +++
 .../registry/nacos/function/NacosConsumer.java     |  40 +++
 .../registry/nacos/function/NacosFunction.java     |  41 +++
 .../nacos/util/NacosNamingServiceUtils.java        |  18 +-
 .../dubbo/registry/nacos/MockNamingService.java    | 289 +++++++++++++++++++++
 .../nacos/NacosNamingServiceWrapperTest.java       | 116 +++++++++
 .../dubbo/registry/nacos/NacosRegistryTest.java    |  30 +--
 8 files changed, 632 insertions(+), 33 deletions(-)

diff --git 
a/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosNamingServiceWrapper.java
 
b/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosNamingServiceWrapper.java
index de4dc69480..e1185aa15b 100644
--- 
a/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosNamingServiceWrapper.java
+++ 
b/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosNamingServiceWrapper.java
@@ -16,7 +16,14 @@
  */
 package org.apache.dubbo.registry.nacos;
 
+import java.util.List;
+
+import org.apache.dubbo.common.constants.LoggerCodeConstants;
+import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
+import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.registry.nacos.function.NacosConsumer;
+import org.apache.dubbo.registry.nacos.function.NacosFunction;
 
 import com.alibaba.nacos.api.exception.NacosException;
 import com.alibaba.nacos.api.naming.NamingService;
@@ -24,9 +31,8 @@ import com.alibaba.nacos.api.naming.listener.EventListener;
 import com.alibaba.nacos.api.naming.pojo.Instance;
 import com.alibaba.nacos.api.naming.pojo.ListView;
 
-import java.util.List;
-
 public class NacosNamingServiceWrapper {
+    private static final ErrorTypeAwareLogger logger = 
LoggerFactory.getErrorTypeAwareLogger(NacosNamingServiceWrapper.class);
 
     private static final String INNERCLASS_SYMBOL = "$";
 
@@ -34,8 +40,14 @@ public class NacosNamingServiceWrapper {
 
     private final NamingService namingService;
 
-    public NacosNamingServiceWrapper(NamingService namingService) {
+    private final int retryTimes;
+
+    private final int sleepMsBetweenRetries;
+
+    public NacosNamingServiceWrapper(NamingService namingService, int 
retryTimes, int sleepMsBetweenRetries) {
         this.namingService = namingService;
+        this.retryTimes = Math.max(retryTimes, 0);
+        this.sleepMsBetweenRetries = sleepMsBetweenRetries;
     }
 
 
@@ -44,36 +56,36 @@ public class NacosNamingServiceWrapper {
     }
 
     public void subscribe(String serviceName, String group, EventListener 
eventListener) throws NacosException {
-        namingService.subscribe(handleInnerSymbol(serviceName), group, 
eventListener);
+        accept(naming -> naming.subscribe(handleInnerSymbol(serviceName), 
group, eventListener));
     }
 
     public void unsubscribe(String serviceName, String group, EventListener 
eventListener) throws NacosException {
-        namingService.unsubscribe(handleInnerSymbol(serviceName), group, 
eventListener);
+        accept(naming -> naming.unsubscribe(handleInnerSymbol(serviceName), 
group, eventListener));
     }
 
     public List<Instance> getAllInstances(String serviceName, String group) 
throws NacosException {
-        return namingService.getAllInstances(handleInnerSymbol(serviceName), 
group);
+        return apply(naming -> 
naming.getAllInstances(handleInnerSymbol(serviceName), group));
     }
 
     public void registerInstance(String serviceName, String group, Instance 
instance) throws NacosException {
-        namingService.registerInstance(handleInnerSymbol(serviceName), group, 
instance);
+        accept(naming -> 
naming.registerInstance(handleInnerSymbol(serviceName), group, instance));
     }
 
     public void deregisterInstance(String serviceName, String group, String 
ip, int port) throws NacosException {
-        namingService.deregisterInstance(handleInnerSymbol(serviceName), 
group, ip, port);
+        accept(naming -> 
naming.deregisterInstance(handleInnerSymbol(serviceName), group, ip, port));
     }
 
 
     public void deregisterInstance(String serviceName, String group, Instance 
instance) throws NacosException {
-        namingService.deregisterInstance(handleInnerSymbol(serviceName), 
group, instance);
+        accept(naming -> 
naming.deregisterInstance(handleInnerSymbol(serviceName), group, instance));
     }
 
     public ListView<String> getServicesOfServer(int pageNo, int pageSize, 
String group) throws NacosException {
-        return namingService.getServicesOfServer(pageNo, pageSize, group);
+        return apply(naming -> naming.getServicesOfServer(pageNo, pageSize, 
group));
     }
 
     public List<Instance> selectInstances(String serviceName, String group, 
boolean healthy) throws NacosException {
-        return namingService.selectInstances(handleInnerSymbol(serviceName), 
group, healthy);
+        return apply(naming -> 
naming.selectInstances(handleInnerSymbol(serviceName), group, healthy));
     }
 
     public void shutdown() throws NacosException {
@@ -90,4 +102,72 @@ public class NacosNamingServiceWrapper {
         }
         return serviceName.replace(INNERCLASS_SYMBOL, 
INNERCLASS_COMPATIBLE_SYMBOL);
     }
+
+    private <R> R apply(NacosFunction<NamingService, R> command) throws 
NacosException {
+        NacosException le = null;
+        R result = null;
+        int times = 0;
+        for (; times < retryTimes + 1; times++) {
+            try {
+                result = command.apply(namingService);
+                le = null;
+                break;
+            } catch (NacosException e) {
+                le = e;
+                logger.warn(LoggerCodeConstants.REGISTRY_NACOS_EXCEPTION, "", 
"",
+                    "Failed to request nacos naming server. " +
+                    (times < retryTimes ? "Dubbo will try to retry in " + 
sleepMsBetweenRetries + ". " : "Exceed retry max times.") +
+                    "Try times: " + times + 1, e);
+                if (times < retryTimes) {
+                    try {
+                        Thread.sleep(sleepMsBetweenRetries);
+                    } catch (InterruptedException ex) {
+                        logger.warn(LoggerCodeConstants.INTERNAL_INTERRUPTED, 
"", "", "Interrupted when waiting to retry.", ex);
+                        Thread.currentThread().interrupt();
+                    }
+                }
+            }
+        }
+        if (le != null) {
+            throw le;
+        }
+        if (times > 1) {
+            logger.info("Failed to request nacos naming server for " + (times 
- 1) + " times and finally success. " +
+                "This may caused by high stress of nacos server.");
+        }
+        return result;
+    }
+
+    private void accept(NacosConsumer<NamingService> command) throws 
NacosException {
+        NacosException le = null;
+        int times = 0;
+        for (; times < retryTimes + 1; times++) {
+            try {
+                command.accept(namingService);
+                le = null;
+                break;
+            } catch (NacosException e) {
+                le = e;
+                logger.warn(LoggerCodeConstants.REGISTRY_NACOS_EXCEPTION, "", 
"",
+                    "Failed to request nacos naming server. " +
+                        (times < retryTimes ? "Dubbo will try to retry in " + 
sleepMsBetweenRetries + ". " : "Exceed retry max times.") +
+                        "Try times: " + times + 1, e);
+                if (times < retryTimes) {
+                    try {
+                        Thread.sleep(sleepMsBetweenRetries);
+                    } catch (InterruptedException ex) {
+                        logger.warn(LoggerCodeConstants.INTERNAL_INTERRUPTED, 
"", "", "Interrupted when waiting to retry.", ex);
+                        Thread.currentThread().interrupt();
+                    }
+                }
+            }
+        }
+        if (le != null) {
+            throw le;
+        }
+        if (times > 1) {
+            logger.info("Failed to request nacos naming server for " + (times 
- 1) + " times and finally success. " +
+                "This may caused by high stress of nacos server.");
+        }
+    }
 }
diff --git 
a/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosServiceDiscovery.java
 
b/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosServiceDiscovery.java
index f2b3c2d4ba..28c2efd44e 100644
--- 
a/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosServiceDiscovery.java
+++ 
b/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosServiceDiscovery.java
@@ -18,6 +18,7 @@ package org.apache.dubbo.registry.nacos;
 
 import java.util.LinkedHashSet;
 import java.util.List;
+import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.stream.Collectors;
@@ -34,6 +35,7 @@ import org.apache.dubbo.registry.client.ServiceInstance;
 import org.apache.dubbo.registry.client.event.ServiceInstancesChangedEvent;
 import 
org.apache.dubbo.registry.client.event.listener.ServiceInstancesChangedListener;
 import org.apache.dubbo.registry.nacos.util.NacosNamingServiceUtils;
+import org.apache.dubbo.rpc.RpcException;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 
 import com.alibaba.nacos.api.exception.NacosException;
@@ -46,9 +48,12 @@ import com.alibaba.nacos.api.naming.pojo.ListView;
 import static com.alibaba.nacos.api.common.Constants.DEFAULT_GROUP;
 import static 
org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_NACOS_EXCEPTION;
 import static org.apache.dubbo.common.function.ThrowableConsumer.execute;
+import static org.apache.dubbo.metadata.RevisionResolver.EMPTY_REVISION;
+import static 
org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.getExportedServicesRevision;
 import static 
org.apache.dubbo.registry.nacos.util.NacosNamingServiceUtils.createNamingService;
 import static 
org.apache.dubbo.registry.nacos.util.NacosNamingServiceUtils.getGroup;
 import static 
org.apache.dubbo.registry.nacos.util.NacosNamingServiceUtils.toInstance;
+import static org.apache.dubbo.rpc.RpcException.REGISTRY_EXCEPTION;
 
 /**
  * Nacos {@link ServiceDiscovery} implementation
@@ -98,6 +103,30 @@ public class NacosServiceDiscovery extends 
AbstractServiceDiscovery {
         });
     }
 
+    @Override
+    protected void doUpdate(ServiceInstance oldServiceInstance, 
ServiceInstance newServiceInstance) throws RuntimeException {
+        if 
(EMPTY_REVISION.equals(getExportedServicesRevision(newServiceInstance))) {
+            super.doUpdate(oldServiceInstance, newServiceInstance);
+            return;
+        }
+
+        if (!Objects.equals(oldServiceInstance.getServiceName(), 
newServiceInstance.getServiceName()) ||
+            !Objects.equals(oldServiceInstance.getAddress(), 
newServiceInstance.getAddress()) ||
+            !Objects.equals(oldServiceInstance.getPort(), 
newServiceInstance.getPort())) {
+            // ignore if host-ip changed
+            super.doUpdate(oldServiceInstance, newServiceInstance);
+            return;
+        }
+
+        try {
+            this.serviceInstance = newServiceInstance;
+            // override without unregister
+            this.doRegister(newServiceInstance);
+        } catch (Exception e) {
+            throw new RpcException(REGISTRY_EXCEPTION, "Failed register 
instance " + newServiceInstance.toString(), e);
+        }
+    }
+
     @Override
     public Set<String> getServices() {
         return ThrowableFunction.execute(namingService, service -> {
diff --git 
a/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/function/NacosConsumer.java
 
b/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/function/NacosConsumer.java
new file mode 100644
index 0000000000..1fd3557426
--- /dev/null
+++ 
b/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/function/NacosConsumer.java
@@ -0,0 +1,40 @@
+/*
+ * 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.dubbo.registry.nacos.function;
+
+import java.util.function.Function;
+
+import com.alibaba.nacos.api.exception.NacosException;
+
+/**
+ * A function interface for action with {@link NacosException}
+ *
+ * @see Function
+ * @see NacosException
+ * @since 3.1.5
+ */
+@FunctionalInterface
+public interface NacosConsumer<T> {
+
+    /**
+     * Applies this function to the given argument.
+     *
+     * @param t the function argument
+     * @throws NacosException if met with any error
+     */
+    void accept(T t) throws NacosException;
+}
diff --git 
a/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/function/NacosFunction.java
 
b/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/function/NacosFunction.java
new file mode 100644
index 0000000000..1d0050b75f
--- /dev/null
+++ 
b/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/function/NacosFunction.java
@@ -0,0 +1,41 @@
+/*
+ * 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.dubbo.registry.nacos.function;
+
+import java.util.function.Function;
+
+import com.alibaba.nacos.api.exception.NacosException;
+
+/**
+ * A function interface for action with {@link NacosException}
+ *
+ * @see Function
+ * @see NacosException
+ * @since 3.1.5
+ */
+@FunctionalInterface
+public interface NacosFunction<T, R> {
+
+    /**
+     * Applies this function to the given argument.
+     *
+     * @param t the function argument
+     * @return the function result
+     * @throws NacosException if met with any error
+     */
+    R apply(T t) throws NacosException;
+}
diff --git 
a/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/util/NacosNamingServiceUtils.java
 
b/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/util/NacosNamingServiceUtils.java
index 08f046a76b..c085701d86 100644
--- 
a/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/util/NacosNamingServiceUtils.java
+++ 
b/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/util/NacosNamingServiceUtils.java
@@ -16,6 +16,9 @@
  */
 package org.apache.dubbo.registry.nacos.util;
 
+import java.util.Map;
+import java.util.Properties;
+
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
 import org.apache.dubbo.common.logger.LoggerFactory;
@@ -32,10 +35,6 @@ import com.alibaba.nacos.api.naming.NamingService;
 import com.alibaba.nacos.api.naming.pojo.Instance;
 import com.alibaba.nacos.api.naming.utils.NamingUtils;
 
-import java.util.Map;
-import java.util.Properties;
-
-import static 
com.alibaba.nacos.api.PropertyKeyConst.NAMING_LOAD_CACHE_AT_START;
 import static com.alibaba.nacos.api.PropertyKeyConst.PASSWORD;
 import static com.alibaba.nacos.api.PropertyKeyConst.SERVER_ADDR;
 import static com.alibaba.nacos.api.PropertyKeyConst.USERNAME;
@@ -56,6 +55,11 @@ public class NacosNamingServiceUtils {
     private static final ErrorTypeAwareLogger logger = 
LoggerFactory.getErrorTypeAwareLogger(NacosNamingServiceUtils.class);
     private static final String NACOS_GROUP_KEY = "nacos.group";
 
+    private static final String NACOS_RETRY_KEY = "nacos.retry";
+
+    private static final String NACOS_RETRY_WAIT_KEY = "nacos.retry-wait";
+
+
     /**
      * Convert the {@link ServiceInstance} to {@link Instance}
      *
@@ -124,7 +128,9 @@ public class NacosNamingServiceUtils {
             }
             throw new IllegalStateException(e);
         }
-        return new NacosNamingServiceWrapper(namingService);
+        int retryTimes = connectionURL.getParameter(NACOS_RETRY_KEY, 10);
+        int sleepMsBetweenRetries = 
connectionURL.getParameter(NACOS_RETRY_WAIT_KEY, 10);
+        return new NacosNamingServiceWrapper(namingService, retryTimes, 
sleepMsBetweenRetries);
     }
 
     private static Properties buildNacosProperties(URL url) {
@@ -164,8 +170,6 @@ public class NacosNamingServiceUtils {
         if (StringUtils.isNotEmpty(url.getPassword())) {
             properties.put(PASSWORD, url.getPassword());
         }
-
-        putPropertyIfAbsent(url, properties, NAMING_LOAD_CACHE_AT_START, 
"true");
     }
 
     private static void putPropertyIfAbsent(URL url, Properties properties, 
String propertyName, String defaultValue) {
diff --git 
a/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/MockNamingService.java
 
b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/MockNamingService.java
new file mode 100644
index 0000000000..e6e7896908
--- /dev/null
+++ 
b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/MockNamingService.java
@@ -0,0 +1,289 @@
+/*
+ * 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.dubbo.registry.nacos;
+
+import java.util.List;
+
+import com.alibaba.nacos.api.exception.NacosException;
+import com.alibaba.nacos.api.naming.NamingService;
+import com.alibaba.nacos.api.naming.listener.EventListener;
+import com.alibaba.nacos.api.naming.pojo.Instance;
+import com.alibaba.nacos.api.naming.pojo.ListView;
+import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
+import com.alibaba.nacos.api.selector.AbstractSelector;
+
+public class MockNamingService implements NamingService {
+    @Override
+    public void registerInstance(String serviceName, String ip, int port) 
throws NacosException {
+
+    }
+
+    @Override
+    public void registerInstance(String serviceName, String groupName, String 
ip, int port) throws NacosException {
+
+    }
+
+    @Override
+    public void registerInstance(String serviceName, String ip, int port, 
String clusterName) throws NacosException {
+
+    }
+
+    @Override
+    public void registerInstance(String serviceName, String groupName, String 
ip, int port, String clusterName) throws NacosException {
+
+    }
+
+    @Override
+    public void registerInstance(String serviceName, Instance instance) throws 
NacosException {
+
+    }
+
+    @Override
+    public void registerInstance(String serviceName, String groupName, 
Instance instance) throws NacosException {
+
+    }
+
+    @Override
+    public void batchRegisterInstance(String serviceName, String groupName, 
List<Instance> instances) throws NacosException {
+
+    }
+
+    @Override
+    public void deregisterInstance(String serviceName, String ip, int port) 
throws NacosException {
+
+    }
+
+    @Override
+    public void deregisterInstance(String serviceName, String groupName, 
String ip, int port) throws NacosException {
+
+    }
+
+    @Override
+    public void deregisterInstance(String serviceName, String ip, int port, 
String clusterName) throws NacosException {
+
+    }
+
+    @Override
+    public void deregisterInstance(String serviceName, String groupName, 
String ip, int port, String clusterName) throws NacosException {
+
+    }
+
+    @Override
+    public void deregisterInstance(String serviceName, Instance instance) 
throws NacosException {
+
+    }
+
+    @Override
+    public void deregisterInstance(String serviceName, String groupName, 
Instance instance) throws NacosException {
+
+    }
+
+    @Override
+    public List<Instance> getAllInstances(String serviceName) throws 
NacosException {
+        return null;
+    }
+
+    @Override
+    public List<Instance> getAllInstances(String serviceName, String 
groupName) throws NacosException {
+        return null;
+    }
+
+    @Override
+    public List<Instance> getAllInstances(String serviceName, boolean 
subscribe) throws NacosException {
+        return null;
+    }
+
+    @Override
+    public List<Instance> getAllInstances(String serviceName, String 
groupName, boolean subscribe) throws NacosException {
+        return null;
+    }
+
+    @Override
+    public List<Instance> getAllInstances(String serviceName, List<String> 
clusters) throws NacosException {
+        return null;
+    }
+
+    @Override
+    public List<Instance> getAllInstances(String serviceName, String 
groupName, List<String> clusters) throws NacosException {
+        return null;
+    }
+
+    @Override
+    public List<Instance> getAllInstances(String serviceName, List<String> 
clusters, boolean subscribe) throws NacosException {
+        return null;
+    }
+
+    @Override
+    public List<Instance> getAllInstances(String serviceName, String 
groupName, List<String> clusters, boolean subscribe) throws NacosException {
+        return null;
+    }
+
+    @Override
+    public List<Instance> selectInstances(String serviceName, boolean healthy) 
throws NacosException {
+        return null;
+    }
+
+    @Override
+    public List<Instance> selectInstances(String serviceName, String 
groupName, boolean healthy) throws NacosException {
+        return null;
+    }
+
+    @Override
+    public List<Instance> selectInstances(String serviceName, boolean healthy, 
boolean subscribe) throws NacosException {
+        return null;
+    }
+
+    @Override
+    public List<Instance> selectInstances(String serviceName, String 
groupName, boolean healthy, boolean subscribe) throws NacosException {
+        return null;
+    }
+
+    @Override
+    public List<Instance> selectInstances(String serviceName, List<String> 
clusters, boolean healthy) throws NacosException {
+        return null;
+    }
+
+    @Override
+    public List<Instance> selectInstances(String serviceName, String 
groupName, List<String> clusters, boolean healthy) throws NacosException {
+        return null;
+    }
+
+    @Override
+    public List<Instance> selectInstances(String serviceName, List<String> 
clusters, boolean healthy, boolean subscribe) throws NacosException {
+        return null;
+    }
+
+    @Override
+    public List<Instance> selectInstances(String serviceName, String 
groupName, List<String> clusters, boolean healthy, boolean subscribe) throws 
NacosException {
+        return null;
+    }
+
+    @Override
+    public Instance selectOneHealthyInstance(String serviceName) throws 
NacosException {
+        return null;
+    }
+
+    @Override
+    public Instance selectOneHealthyInstance(String serviceName, String 
groupName) throws NacosException {
+        return null;
+    }
+
+    @Override
+    public Instance selectOneHealthyInstance(String serviceName, boolean 
subscribe) throws NacosException {
+        return null;
+    }
+
+    @Override
+    public Instance selectOneHealthyInstance(String serviceName, String 
groupName, boolean subscribe) throws NacosException {
+        return null;
+    }
+
+    @Override
+    public Instance selectOneHealthyInstance(String serviceName, List<String> 
clusters) throws NacosException {
+        return null;
+    }
+
+    @Override
+    public Instance selectOneHealthyInstance(String serviceName, String 
groupName, List<String> clusters) throws NacosException {
+        return null;
+    }
+
+    @Override
+    public Instance selectOneHealthyInstance(String serviceName, List<String> 
clusters, boolean subscribe) throws NacosException {
+        return null;
+    }
+
+    @Override
+    public Instance selectOneHealthyInstance(String serviceName, String 
groupName, List<String> clusters, boolean subscribe) throws NacosException {
+        return null;
+    }
+
+    @Override
+    public void subscribe(String serviceName, EventListener listener) throws 
NacosException {
+
+    }
+
+    @Override
+    public void subscribe(String serviceName, String groupName, EventListener 
listener) throws NacosException {
+
+    }
+
+    @Override
+    public void subscribe(String serviceName, List<String> clusters, 
EventListener listener) throws NacosException {
+
+    }
+
+    @Override
+    public void subscribe(String serviceName, String groupName, List<String> 
clusters, EventListener listener) throws NacosException {
+
+    }
+
+    @Override
+    public void unsubscribe(String serviceName, EventListener listener) throws 
NacosException {
+
+    }
+
+    @Override
+    public void unsubscribe(String serviceName, String groupName, 
EventListener listener) throws NacosException {
+
+    }
+
+    @Override
+    public void unsubscribe(String serviceName, List<String> clusters, 
EventListener listener) throws NacosException {
+
+    }
+
+    @Override
+    public void unsubscribe(String serviceName, String groupName, List<String> 
clusters, EventListener listener) throws NacosException {
+
+    }
+
+    @Override
+    public ListView<String> getServicesOfServer(int pageNo, int pageSize) 
throws NacosException {
+        return null;
+    }
+
+    @Override
+    public ListView<String> getServicesOfServer(int pageNo, int pageSize, 
String groupName) throws NacosException {
+        return null;
+    }
+
+    @Override
+    public ListView<String> getServicesOfServer(int pageNo, int pageSize, 
AbstractSelector selector) throws NacosException {
+        return null;
+    }
+
+    @Override
+    public ListView<String> getServicesOfServer(int pageNo, int pageSize, 
String groupName, AbstractSelector selector) throws NacosException {
+        return null;
+    }
+
+    @Override
+    public List<ServiceInfo> getSubscribeServices() throws NacosException {
+        return null;
+    }
+
+    @Override
+    public String getServerStatus() {
+        return null;
+    }
+
+    @Override
+    public void shutDown() throws NacosException {
+
+    }
+}
diff --git 
a/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosNamingServiceWrapperTest.java
 
b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosNamingServiceWrapperTest.java
new file mode 100644
index 0000000000..f348255d7e
--- /dev/null
+++ 
b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosNamingServiceWrapperTest.java
@@ -0,0 +1,116 @@
+/*
+ * 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.dubbo.registry.nacos;
+
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import com.alibaba.nacos.api.exception.NacosException;
+import com.alibaba.nacos.api.naming.NamingService;
+import com.alibaba.nacos.api.naming.pojo.Instance;
+
+class NacosNamingServiceWrapperTest {
+
+    @Test
+    void testSuccess() {
+        NamingService namingService = new MockNamingService() {
+            @Override
+            public void registerInstance(String serviceName, String groupName, 
Instance instance) throws NacosException {
+
+            }
+
+            @Override
+            public List<Instance> getAllInstances(String serviceName, String 
groupName) throws NacosException {
+                return null;
+            }
+        };
+
+        NacosNamingServiceWrapper nacosNamingServiceWrapper = new 
NacosNamingServiceWrapper(namingService, 0, 0);
+        try {
+            nacosNamingServiceWrapper.registerInstance("Test", "Test", null);
+        } catch (NacosException e) {
+            Assertions.fail(e);
+        }
+        try {
+            nacosNamingServiceWrapper.getAllInstances("Test", "Test");
+        } catch (NacosException e) {
+            Assertions.fail(e);
+        }
+    }
+
+    @Test
+    void testFailNoRetry() {
+        NamingService namingService = new MockNamingService() {
+            @Override
+            public void registerInstance(String serviceName, String groupName, 
Instance instance) throws NacosException {
+                throw new NacosException();
+            }
+
+            @Override
+            public List<Instance> getAllInstances(String serviceName, String 
groupName) throws NacosException {
+                throw new NacosException();
+            }
+        };
+
+        NacosNamingServiceWrapper nacosNamingServiceWrapper = new 
NacosNamingServiceWrapper(namingService, 0, 0);
+        Assertions.assertThrows(NacosException.class, () -> 
nacosNamingServiceWrapper.registerInstance("Test", "Test", null));
+        Assertions.assertThrows(NacosException.class, () -> 
nacosNamingServiceWrapper.getAllInstances("Test", "Test"));
+    }
+
+
+    @Test
+    void testFailRetry() {
+        NamingService namingService = new MockNamingService() {
+            private final AtomicInteger count1 = new AtomicInteger(0);
+            private final AtomicInteger count2 = new AtomicInteger(0);
+
+            @Override
+            public void registerInstance(String serviceName, String groupName, 
Instance instance) throws NacosException {
+                if (count1.incrementAndGet() < 10) {
+                    throw new NacosException();
+                }
+            }
+
+            @Override
+            public List<Instance> getAllInstances(String serviceName, String 
groupName) throws NacosException {
+                if (count2.incrementAndGet() < 10) {
+                    throw new NacosException();
+                }
+                return null;
+            }
+        };
+
+        NacosNamingServiceWrapper nacosNamingServiceWrapper = new 
NacosNamingServiceWrapper(namingService, 5, 10);
+        Assertions.assertThrows(NacosException.class, () -> 
nacosNamingServiceWrapper.registerInstance("Test", "Test", null));
+        try {
+            nacosNamingServiceWrapper.registerInstance("Test", "Test", null);
+        } catch (NacosException e) {
+            Assertions.fail(e);
+        }
+
+        Assertions.assertThrows(NacosException.class, () -> 
nacosNamingServiceWrapper.getAllInstances("Test", "Test"));
+        try {
+            nacosNamingServiceWrapper.getAllInstances("Test", "Test");
+        } catch (NacosException e) {
+            Assertions.fail(e);
+        }
+
+    }
+}
diff --git 
a/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosRegistryTest.java
 
b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosRegistryTest.java
index b5c9ee55ff..c0568d3c52 100644
--- 
a/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosRegistryTest.java
+++ 
b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosRegistryTest.java
@@ -16,9 +16,19 @@
  */
 package org.apache.dubbo.registry.nacos;
 
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.utils.NetUtils;
 import org.apache.dubbo.registry.NotifyListener;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 
 import com.alibaba.nacos.api.common.Constants;
 import com.alibaba.nacos.api.exception.NacosException;
@@ -26,16 +36,6 @@ import com.alibaba.nacos.api.naming.NamingService;
 import com.alibaba.nacos.api.naming.pojo.Instance;
 import com.alibaba.nacos.api.naming.pojo.ListView;
 import com.alibaba.nacos.client.naming.NacosNamingService;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
 
 import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;
@@ -103,7 +103,7 @@ class NacosRegistryTest {
             // ignore
         }
 
-        NacosNamingServiceWrapper nacosNamingServiceWrapper = new 
NacosNamingServiceWrapper(namingService);
+        NacosNamingServiceWrapper nacosNamingServiceWrapper = new 
NacosNamingServiceWrapper(namingService, 0, 0);
         nacosRegistry = new NacosRegistry(this.registryUrl, 
nacosNamingServiceWrapper);
 
         Set<URL> registered;
@@ -143,7 +143,7 @@ class NacosRegistryTest {
             // ignore
         }
 
-        NacosNamingServiceWrapper nacosNamingServiceWrapper = new 
NacosNamingServiceWrapper(namingService);
+        NacosNamingServiceWrapper nacosNamingServiceWrapper = new 
NacosNamingServiceWrapper(namingService, 0, 0);
         nacosRegistry = new NacosRegistry(this.registryUrl, 
nacosNamingServiceWrapper);
 
         nacosRegistry.register(serviceUrl);
@@ -183,7 +183,7 @@ class NacosRegistryTest {
             // ignore
         }
 
-        NacosNamingServiceWrapper nacosNamingServiceWrapper = new 
NacosNamingServiceWrapper(namingService);
+        NacosNamingServiceWrapper nacosNamingServiceWrapper = new 
NacosNamingServiceWrapper(namingService, 0, 0);
         nacosRegistry = new NacosRegistry(this.registryUrl, 
nacosNamingServiceWrapper);
 
         NotifyListener listener = mock(NotifyListener.class);
@@ -222,7 +222,7 @@ class NacosRegistryTest {
         }
 
         NacosNamingServiceWrapper nacosNamingServiceWrapper = new
-            NacosNamingServiceWrapper(namingService);
+            NacosNamingServiceWrapper(namingService, 0, 0);
         nacosRegistry = new NacosRegistry(this.registryUrl, 
nacosNamingServiceWrapper);
 
         NotifyListener listener = mock(NotifyListener.class);
@@ -276,7 +276,7 @@ class NacosRegistryTest {
         }
 
         NacosNamingServiceWrapper nacosNamingServiceWrapper = new
-            NacosNamingServiceWrapper(namingService);
+            NacosNamingServiceWrapper(namingService, 0, 0);
         nacosRegistry = new NacosRegistry(this.registryUrl, 
nacosNamingServiceWrapper);
 
         Set<URL> registered;


Reply via email to