This is an automated email from the ASF dual-hosted git repository.
liujun pushed a commit to branch 2.7.3-release
in repository https://gitbox.apache.org/repos/asf/dubbo.git
The following commit(s) were added to refs/heads/2.7.3-release by this push:
new 1bf5fce Nacos registry enhancement & register reference bean (#4454)
1bf5fce is described below
commit 1bf5fceb13e6332c83332a6d991eebcedb60666b
Author: Mercy Ma <[email protected]>
AuthorDate: Thu Jul 4 09:39:58 2019 +0800
Nacos registry enhancement & register reference bean (#4454)
fixes #4439, #4455
---
dubbo-bom/pom.xml | 4 +-
.../org/apache/dubbo/common/bytecode/Proxy.java | 2 +-
.../dubbo/common/extension/ExtensionLoader.java | 2 +-
.../org/apache/dubbo/common/utils/NetUtils.java | 2 +-
.../apache/dubbo/config/annotation/Reference.java | 25 ++-
.../AnnotationInjectedBeanPostProcessor.java | 8 +-
.../ReferenceAnnotationBeanPostProcessor.java | 92 +++++++-
.../ReferenceAnnotationBeanPostProcessorTest.java | 22 +-
.../spring/context/annotation/EnableDubboTest.java | 5 +
.../annotation/consumer/ConsumerConfiguration.java | 12 ++
.../consumer/test/TestConsumerConfiguration.java | 8 +
.../DubboComponentScanRegistrarTest.java | 2 +
.../registry/multicast/MulticastRegistry.java | 4 +-
.../apache/dubbo/registry/nacos/NacosRegistry.java | 100 +++++----
.../dubbo/registry/nacos/NacosRegistryFactory.java | 2 +-
.../dubbo/registry/nacos/NacosServiceName.java | 239 +++++++++++++++++++++
.../consumer/DemoServiceConsumerXmlBootstrap.java | 10 +-
.../dubbo/registry/nacos/NacosServiceNameTest.java | 123 +++++++++++
.../META-INF/spring/dubbo-consumer-context.xml | 14 +-
.../META-INF/spring/dubbo-provider-context.xml | 3 +-
.../apache/dubbo/rpc/filter/ActiveLimitFilter.java | 4 +-
21 files changed, 622 insertions(+), 61 deletions(-)
diff --git a/dubbo-bom/pom.xml b/dubbo-bom/pom.xml
index 3ba9eb2..5ab6604 100644
--- a/dubbo-bom/pom.xml
+++ b/dubbo-bom/pom.xml
@@ -44,8 +44,8 @@
<url>https://github.com/apache/dubbo</url>
<connection>scm:git:https://github.com/apache/dubbo.git</connection>
<developerConnection>scm:git:https://github.com/apache/dubbo.git</developerConnection>
- <tag>HEAD</tag>
- </scm>
+ <tag>HEAD</tag>
+ </scm>
<mailingLists>
<mailingList>
<name>Development List</name>
diff --git
a/dubbo-common/src/main/java/org/apache/dubbo/common/bytecode/Proxy.java
b/dubbo-common/src/main/java/org/apache/dubbo/common/bytecode/Proxy.java
index 2da2818..808a859 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/bytecode/Proxy.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/bytecode/Proxy.java
@@ -102,7 +102,7 @@ public abstract class Proxy {
String key = sb.toString();
// get cache by class loader.
- Map<String, Object> cache;
+ final Map<String, Object> cache;
synchronized (PROXY_CACHE_MAP) {
cache = PROXY_CACHE_MAP.computeIfAbsent(cl, k -> new HashMap<>());
}
diff --git
a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java
b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java
index ff1f6d6..c09d493 100644
---
a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java
+++
b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java
@@ -342,7 +342,7 @@ public class ExtensionLoader<T> {
if ("true".equals(name)) {
return getDefaultExtension();
}
- Holder<Object> holder = getOrCreateHolder(name);
+ final Holder<Object> holder = getOrCreateHolder(name);
Object instance = holder.get();
if (instance == null) {
synchronized (holder) {
diff --git
a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/NetUtils.java
b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/NetUtils.java
index bef5183..c3884e0 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/NetUtils.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/NetUtils.java
@@ -37,9 +37,9 @@ import java.util.concurrent.ThreadLocalRandom;
import java.util.regex.Pattern;
import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_VALUE;
+import static
org.apache.dubbo.common.constants.CommonConstants.DUBBO_IP_TO_BIND;
import static org.apache.dubbo.common.constants.CommonConstants.LOCALHOST_KEY;
import static
org.apache.dubbo.common.constants.CommonConstants.LOCALHOST_VALUE;
-import static
org.apache.dubbo.common.constants.CommonConstants.DUBBO_IP_TO_BIND;
/**
* IP and Port Helper for RPC
diff --git
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/annotation/Reference.java
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/annotation/Reference.java
index f5d09d3..d7d9046 100644
---
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/annotation/Reference.java
+++
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/annotation/Reference.java
@@ -30,6 +30,7 @@ import java.lang.annotation.Target;
* Reference
*
* @export
+ * @since 2.7.0
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@@ -228,32 +229,35 @@ public @interface Reference {
String[] parameters() default {};
/**
- * Application spring bean name
+ * Application associated name
*/
String application() default "";
/**
- * Module spring bean name
+ * Module associated name
*/
String module() default "";
/**
- * Consumer spring bean name
+ * Consumer associated name
*/
String consumer() default "";
/**
- * Monitor spring bean name
+ * Monitor associated name
*/
String monitor() default "";
/**
- * Registry spring bean name
+ * Registry associated name
*/
String[] registry() default {};
/**
- * Protocol spring bean names
+ * The communication protocol of Dubbo Service
+ *
+ * @return the default value is ""
+ * @since 2.6.6
*/
String protocol() default "";
@@ -264,7 +268,16 @@ public @interface Reference {
/**
* methods support
+ *
* @return
*/
Method[] methods() default {};
+
+ /**
+ * The id
+ *
+ * @return default value is empty
+ * @since 2.7.3
+ */
+ String id() default "";
}
diff --git
a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AnnotationInjectedBeanPostProcessor.java
b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AnnotationInjectedBeanPostProcessor.java
index de56d29..aed3a5a 100644
---
a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AnnotationInjectedBeanPostProcessor.java
+++
b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AnnotationInjectedBeanPostProcessor.java
@@ -26,6 +26,7 @@ import
org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.DisposableBean;
+import
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.annotation.InjectionMetadata;
import org.springframework.beans.factory.config.BeanPostProcessor;
import
org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
@@ -91,7 +92,12 @@ public abstract class AnnotationInjectedBeanPostProcessor
extends
private ClassLoader classLoader;
- private int order = Ordered.LOWEST_PRECEDENCE;
+ /**
+ * make sure higher priority than {@link
AutowiredAnnotationBeanPostProcessor}
+ *
+ * @revision 2.7.3
+ */
+ private int order = Ordered.LOWEST_PRECEDENCE - 3;
/**
* @param annotationTypes the multiple types of {@link Annotation
annotations}
diff --git
a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java
b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java
index d477c58..834939a 100644
---
a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java
+++
b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java
@@ -24,6 +24,9 @@ import org.apache.dubbo.config.spring.util.AnnotationUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.InjectionMetadata;
+import
org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
@@ -43,6 +46,8 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import static
org.apache.dubbo.config.spring.beans.factory.annotation.ServiceBeanNameBuilder.create;
+import static org.apache.dubbo.config.spring.util.AnnotationUtils.getAttribute;
+import static org.springframework.util.StringUtils.hasText;
/**
* {@link org.springframework.beans.factory.config.BeanPostProcessor}
implementation
@@ -120,13 +125,96 @@ public class ReferenceAnnotationBeanPostProcessor extends
AnnotationInjectedBean
String referencedBeanName = buildReferencedBeanName(attributes,
injectedType);
- ReferenceBean referenceBean =
buildReferenceBeanIfAbsent(referencedBeanName, attributes, injectedType,
getClassLoader());
+ ReferenceBean referenceBean =
buildReferenceBeanIfAbsent(referencedBeanName, attributes, injectedType);
+
+ registerReferenceBean(referencedBeanName, referenceBean, attributes,
injectedType);
cacheInjectedReferenceBean(referenceBean, injectedElement);
return buildProxy(referencedBeanName, referenceBean, injectedType);
}
+ /**
+ * Register an instance of {@link ReferenceBean} as a Spring Bean
+ *
+ * @param referencedBeanName the referenced bean name
+ * @param referenceBean the instance of {@link ReferenceBean}
+ * @param attributes the {@link AnnotationAttributes attributes}
of {@link Reference @Reference}
+ * @param interfaceClass the {@link Class class} of Service interface
+ * @since 2.7.3
+ */
+ private void registerReferenceBean(String referencedBeanName,
ReferenceBean referenceBean,
+ AnnotationAttributes attributes,
+ Class<?> interfaceClass) {
+
+ ConfigurableListableBeanFactory beanFactory = getBeanFactory();
+
+ String beanName = getReferenceBeanName(attributes, interfaceClass);
+
+ if (beanFactory.containsBean(referencedBeanName)) { // If @Service
bean is local one
+ /**
+ * Get the @Service's BeanDefinition from {@link BeanFactory}
+ * Refer to {@link
ServiceAnnotationBeanPostProcessor#buildServiceBeanDefinition}
+ */
+ AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition)
beanFactory.getBeanDefinition(referencedBeanName);
+ RuntimeBeanReference runtimeBeanReference = (RuntimeBeanReference)
beanDefinition.getPropertyValues().get("ref");
+ // The name of bean annotated @Service
+ String serviceBeanName = runtimeBeanReference.getBeanName();
+ // register Alias rather than a new bean name, in order to reduce
duplicated beans
+ beanFactory.registerAlias(serviceBeanName, beanName);
+ } else { // Remote @Service Bean
+ if (!beanFactory.containsBean(beanName)) {
+ beanFactory.registerSingleton(beanName, referenceBean);
+ }
+ }
+ }
+
+ /**
+ * Get the bean name of {@link ReferenceBean} if {@link Reference#id() id
attribute} is present,
+ * or {@link #generateReferenceBeanName(AnnotationAttributes, Class)
generate}.
+ *
+ * @param attributes the {@link AnnotationAttributes attributes} of
{@link Reference @Reference}
+ * @param interfaceClass the {@link Class class} of Service interface
+ * @return non-null
+ * @since 2.7.3
+ */
+ private String getReferenceBeanName(AnnotationAttributes attributes,
Class<?> interfaceClass) {
+ // id attribute appears since 2.7.3
+ String beanName = getAttribute(attributes, "id");
+ if (!hasText(beanName)) {
+ beanName = generateReferenceBeanName(attributes, interfaceClass);
+ }
+ return beanName;
+ }
+
+ /**
+ * Build the bean name of {@link ReferenceBean}
+ *
+ * @param attributes the {@link AnnotationAttributes attributes} of
{@link Reference @Reference}
+ * @param interfaceClass the {@link Class class} of Service interface
+ * @return
+ * @since 2.7.3
+ */
+ private String generateReferenceBeanName(AnnotationAttributes attributes,
Class<?> interfaceClass) {
+ StringBuilder beanNameBuilder = new StringBuilder("@Reference");
+
+ if (!attributes.isEmpty()) {
+ beanNameBuilder.append('(');
+ for (Map.Entry<String, Object> entry : attributes.entrySet()) {
+ beanNameBuilder.append(entry.getKey())
+ .append('=')
+ .append(entry.getValue())
+ .append(',');
+ }
+ // replace the latest "," to be ")"
+ beanNameBuilder.setCharAt(beanNameBuilder.lastIndexOf(","), ')');
+ }
+
+ beanNameBuilder.append(" ").append(interfaceClass.getName());
+
+ return beanNameBuilder.toString();
+ }
+
private Object buildProxy(String referencedBeanName, ReferenceBean
referenceBean, Class<?> injectedType) {
InvocationHandler handler = buildInvocationHandler(referencedBeanName,
referenceBean);
return Proxy.newProxyInstance(getClassLoader(), new
Class[]{injectedType}, handler);
@@ -199,7 +287,7 @@ public class ReferenceAnnotationBeanPostProcessor extends
AnnotationInjectedBean
}
private ReferenceBean buildReferenceBeanIfAbsent(String
referencedBeanName, AnnotationAttributes attributes,
- Class<?> referencedType,
ClassLoader classLoader)
+ Class<?> referencedType)
throws Exception {
ReferenceBean<?> referenceBean =
referenceBeanCache.get(referencedBeanName);
diff --git
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java
index 1ee01dc..5e904a6 100644
---
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java
+++
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java
@@ -80,10 +80,27 @@ public class ReferenceAnnotationBeanPostProcessorTest {
Assert.assertNotNull(testBean.getDemoServiceFromAncestor());
Assert.assertNotNull(testBean.getDemoServiceFromParent());
Assert.assertNotNull(testBean.getDemoService());
+ Assert.assertNotNull(testBean.autowiredDemoService);
Assert.assertEquals("Hello,Mercy",
testBean.getDemoServiceFromAncestor().sayName("Mercy"));
Assert.assertEquals("Hello,Mercy",
testBean.getDemoServiceFromParent().sayName("Mercy"));
Assert.assertEquals("Hello,Mercy",
testBean.getDemoService().sayName("Mercy"));
+ Assert.assertEquals("Hello,Mercy",
testBean.autowiredDemoService.sayName("Mercy"));
+
+ DemoService myDemoService = context.getBean("my-reference-bean",
DemoService.class);
+
+ Assert.assertEquals("Hello,Mercy", myDemoService.sayName("Mercy"));
+
+ Map<String, DemoService> demoServicesMap =
context.getBeansOfType(DemoService.class);
+
+ Assert.assertEquals(1, demoServicesMap.size());
+
+ for (DemoService demoService1 : demoServicesMap.values()) {
+
+ Assert.assertEquals(myDemoService, demoService1);
+
+ Assert.assertEquals("Hello,Mercy", demoService1.sayName("Mercy"));
+ }
}
@@ -194,7 +211,7 @@ public class ReferenceAnnotationBeanPostProcessorTest {
return demoServiceFromAncestor;
}
- @Reference(version = "2.5.7", url = "dubbo://127.0.0.1:12345")
+ @Reference(id = "my-reference-bean", version = "2.5.7", url =
"dubbo://127.0.0.1:12345")
public void setDemoServiceFromAncestor(DemoService
demoServiceFromAncestor) {
this.demoServiceFromAncestor = demoServiceFromAncestor;
}
@@ -223,6 +240,9 @@ public class ReferenceAnnotationBeanPostProcessorTest {
private DemoService demoService;
@Autowired
+ private DemoService autowiredDemoService;
+
+ @Autowired
private ApplicationContext applicationContext;
public DemoService getDemoService() {
diff --git
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboTest.java
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboTest.java
index b611989..077464e 100644
---
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboTest.java
+++
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboTest.java
@@ -100,6 +100,11 @@ public class EnableDubboTest {
Assertions.assertEquals("Hello,Mercy", value);
+ DemoService autowiredDemoService =
consumerConfiguration.getAutowiredDemoService();
+
+ Assertions.assertEquals("Hello,Mercy",
autowiredDemoService.sayName("Mercy"));
+
+
TestConsumerConfiguration.Child child =
context.getBean(TestConsumerConfiguration.Child.class);
// From Child
diff --git
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/consumer/ConsumerConfiguration.java
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/consumer/ConsumerConfiguration.java
index c12d4d3..47c90e4 100644
---
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/consumer/ConsumerConfiguration.java
+++
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/consumer/ConsumerConfiguration.java
@@ -22,6 +22,7 @@ import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.spring.api.DemoService;
import org.apache.dubbo.config.spring.context.annotation.DubboComponentScan;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@@ -63,6 +64,9 @@ public class ConsumerConfiguration {
return registryConfig;
}
+ @Autowired
+ private DemoService autowiredDemoService;
+
@Reference(version = "2.5.7", url = "dubbo://127.0.0.1:12345")
private DemoService demoService;
@@ -111,9 +115,17 @@ public class ConsumerConfiguration {
public static class Child extends Parent {
+ @Autowired
+ private DemoService demoService;
+
@Reference(version = "2.5.7", url = "dubbo://127.0.0.1:12345")
private DemoService demoServiceFromChild;
+
+ public DemoService getDemoService() {
+ return demoService;
+ }
+
public DemoService getDemoServiceFromChild() {
return demoServiceFromChild;
}
diff --git
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/consumer/test/TestConsumerConfiguration.java
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/consumer/test/TestConsumerConfiguration.java
index 2317545..82960ef 100644
---
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/consumer/test/TestConsumerConfiguration.java
+++
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/consumer/test/TestConsumerConfiguration.java
@@ -20,6 +20,7 @@ import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.spring.api.DemoService;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@@ -37,6 +38,13 @@ public class TestConsumerConfiguration {
@Reference(version = "2.5.7", url = "dubbo://127.0.0.1:12345", application
= "dubbo-demo-application")
private DemoService demoService;
+ @Autowired
+ private DemoService autowiredDemoService;
+
+ public DemoService getAutowiredDemoService() {
+ return autowiredDemoService;
+ }
+
public DemoService getDemoService() {
return demoService;
}
diff --git
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/context/annotation/DubboComponentScanRegistrarTest.java
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/context/annotation/DubboComponentScanRegistrarTest.java
index 5d28adf..6ed8a85 100644
---
a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/context/annotation/DubboComponentScanRegistrarTest.java
+++
b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/context/annotation/DubboComponentScanRegistrarTest.java
@@ -86,6 +86,8 @@ public class DubboComponentScanRegistrarTest {
Assertions.assertEquals("Hello,Mercy", value);
+ Assertions.assertEquals("Hello,Mercy",
child.getDemoService().sayName("Mercy"));
+
// From Parent
demoService = child.getDemoServiceFromParent();
diff --git
a/dubbo-registry/dubbo-registry-multicast/src/main/java/org/apache/dubbo/registry/multicast/MulticastRegistry.java
b/dubbo-registry/dubbo-registry-multicast/src/main/java/org/apache/dubbo/registry/multicast/MulticastRegistry.java
index 27aded1..0c28445 100644
---
a/dubbo-registry/dubbo-registry-multicast/src/main/java/org/apache/dubbo/registry/multicast/MulticastRegistry.java
+++
b/dubbo-registry/dubbo-registry-multicast/src/main/java/org/apache/dubbo/registry/multicast/MulticastRegistry.java
@@ -263,7 +263,7 @@ public class MulticastRegistry extends FailbackRegistry {
}
@Override
- public void doSubscribe(URL url, NotifyListener listener) {
+ public void doSubscribe(URL url, final NotifyListener listener) {
if (ANY_VALUE.equals(url.getServiceInterface())) {
admin = true;
}
@@ -324,7 +324,7 @@ public class MulticastRegistry extends FailbackRegistry {
}
urls.add(url);
List<URL> list = toList(urls);
- for (NotifyListener listener : entry.getValue()) {
+ for (final NotifyListener listener : entry.getValue()) {
notify(key, listener, list);
synchronized (listener) {
listener.notify();
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 24b55c0..c396455 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
@@ -17,7 +17,6 @@
package org.apache.dubbo.registry.nacos;
import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.URLBuilder;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.UrlUtils;
@@ -36,16 +35,21 @@ import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
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.stream.Collectors;
+import static java.util.Collections.singleton;
import static org.apache.dubbo.common.constants.CommonConstants.ANY_VALUE;
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
@@ -56,10 +60,10 @@ import static
org.apache.dubbo.common.constants.RegistryConstants.CATEGORY_KEY;
import static
org.apache.dubbo.common.constants.RegistryConstants.CONFIGURATORS_CATEGORY;
import static
org.apache.dubbo.common.constants.RegistryConstants.CONSUMERS_CATEGORY;
import static
org.apache.dubbo.common.constants.RegistryConstants.DEFAULT_CATEGORY;
-import static
org.apache.dubbo.common.constants.RegistryConstants.EMPTY_PROTOCOL;
import static
org.apache.dubbo.common.constants.RegistryConstants.PROVIDERS_CATEGORY;
import static
org.apache.dubbo.common.constants.RegistryConstants.ROUTERS_CATEGORY;
import static org.apache.dubbo.registry.Constants.ADMIN_PROTOCOL;
+import static org.apache.dubbo.registry.nacos.NacosServiceName.valueOf;
/**
* Nacos {@link Registry}
@@ -134,10 +138,10 @@ public class NacosRegistry extends FailbackRegistry {
public List<URL> lookup(final URL url) {
final List<URL> urls = new LinkedList<>();
execute(namingService -> {
- List<String> serviceNames = getServiceNames(url, null);
+ Set<String> serviceNames = getServiceNames(url, null);
for (String serviceName : serviceNames) {
List<Instance> instances =
namingService.getAllInstances(serviceName);
- urls.addAll(buildURLs(url, serviceName, instances));
+ urls.addAll(buildURLs(url, instances));
}
});
return urls;
@@ -161,15 +165,15 @@ public class NacosRegistry extends FailbackRegistry {
@Override
public void doSubscribe(final URL url, final NotifyListener listener) {
- List<String> serviceNames = getServiceNames(url, listener);
+ Set<String> serviceNames = getServiceNames(url, listener);
doSubscribe(url, listener, serviceNames);
}
- private void doSubscribe(final URL url, final NotifyListener listener,
final List<String> serviceNames) {
+ private void doSubscribe(final URL url, final NotifyListener listener,
final Set<String> serviceNames) {
execute(namingService -> {
for (String serviceName : serviceNames) {
List<Instance> instances =
namingService.getAllInstances(serviceName);
- notifySubscriber(url, serviceName, listener, instances);
+ notifySubscriber(url, listener, instances);
subscribeEventListener(serviceName, url, listener);
}
});
@@ -195,15 +199,47 @@ public class NacosRegistry extends FailbackRegistry {
* @param listener {@link NotifyListener}
* @return non-null
*/
- private List<String> getServiceNames(URL url, NotifyListener listener) {
+ private Set<String> getServiceNames(URL url, NotifyListener listener) {
if (isAdminProtocol(url)) {
scheduleServiceNamesLookup(url, listener);
return getServiceNamesForOps(url);
} else {
- return doGetServiceNames(url);
+ return getServiceNames0(url);
}
}
+ private Set<String> getServiceNames0(URL url) {
+ NacosServiceName serviceName = createServiceName(url);
+
+ final Set<String> serviceNames;
+
+ if (serviceName.isConcrete()) { // is the concrete service name
+ serviceNames = singleton(serviceName.toString());
+ } else {
+ serviceNames = filterServiceNames(serviceName);
+ }
+
+ return serviceNames;
+ }
+
+ private Set<String> filterServiceNames(NacosServiceName serviceName) {
+ Set<String> serviceNames = new LinkedHashSet<>();
+
+ execute(namingService -> {
+
+ serviceNames.addAll(namingService.getServicesOfServer(1,
Integer.MAX_VALUE).getData()
+ .stream()
+ .map(NacosServiceName::new)
+ .filter(serviceName::isCompatible)
+ .map(NacosServiceName::toString)
+ .collect(Collectors.toList()));
+
+ });
+
+ return serviceNames;
+ }
+
+
private boolean isAdminProtocol(URL url) {
return ADMIN_PROTOCOL.equals(url.getProtocol());
}
@@ -212,7 +248,7 @@ public class NacosRegistry extends FailbackRegistry {
if (scheduledExecutorService == null) {
scheduledExecutorService =
Executors.newSingleThreadScheduledExecutor();
scheduledExecutorService.scheduleAtFixedRate(() -> {
- List<String> serviceNames = getAllServiceNames();
+ Set<String> serviceNames = getAllServiceNames();
filterData(serviceNames, serviceName -> {
boolean accepted = false;
for (String category : ALL_SUPPORTED_CATEGORIES) {
@@ -235,15 +271,15 @@ public class NacosRegistry extends FailbackRegistry {
* @param url {@link URL}
* @return non-null
*/
- private List<String> getServiceNamesForOps(URL url) {
- List<String> serviceNames = getAllServiceNames();
+ private Set<String> getServiceNamesForOps(URL url) {
+ Set<String> serviceNames = getAllServiceNames();
filterServiceNames(serviceNames, url);
return serviceNames;
}
- private List<String> getAllServiceNames() {
+ private Set<String> getAllServiceNames() {
- final List<String> serviceNames = new LinkedList<>();
+ final Set<String> serviceNames = new LinkedHashSet<>();
execute(namingService -> {
@@ -273,15 +309,15 @@ public class NacosRegistry extends FailbackRegistry {
return serviceNames;
}
- private void filterServiceNames(List<String> serviceNames, URL url) {
+ private void filterServiceNames(Set<String> serviceNames, URL url) {
final String[] categories = getCategories(url);
final String targetServiceInterface = url.getServiceInterface();
- final String targetVersion = url.getParameter(VERSION_KEY,"");
+ final String targetVersion = url.getParameter(VERSION_KEY, "");
- final String targetGroup = url.getParameter(GROUP_KEY,"");
+ final String targetGroup = url.getParameter(GROUP_KEY, "");
filterData(serviceNames, serviceName -> {
// split service name to segments
@@ -323,6 +359,7 @@ public class NacosRegistry extends FailbackRegistry {
collection.removeIf(data -> !filter.accept(data));
}
+ @Deprecated
private List<String> doGetServiceNames(URL url) {
String[] categories = getCategories(url);
List<String> serviceNames = new ArrayList<>(categories.length);
@@ -333,9 +370,9 @@ public class NacosRegistry extends FailbackRegistry {
return serviceNames;
}
- private List<URL> buildURLs(URL consumerURL, String serviceName,
Collection<Instance> instances) {
+ private List<URL> buildURLs(URL consumerURL, Collection<Instance>
instances) {
if (instances.isEmpty()) {
- return emptyURL(consumerURL, serviceName);
+ return Collections.emptyList();
}
List<URL> urls = new LinkedList<>();
for (Instance instance : instances) {
@@ -353,7 +390,7 @@ public class NacosRegistry extends FailbackRegistry {
EventListener eventListener = event -> {
if (event instanceof NamingEvent) {
NamingEvent e = (NamingEvent) event;
- notifySubscriber(url, serviceName, listener,
e.getInstances());
+ notifySubscriber(url, listener, e.getInstances());
}
};
namingService.subscribe(serviceName, eventListener);
@@ -365,15 +402,14 @@ public class NacosRegistry extends FailbackRegistry {
* Notify the Healthy {@link Instance instances} to subscriber.
*
* @param url {@link URL}
- * @param serviceName
* @param listener {@link NotifyListener}
* @param instances all {@link Instance instances}
*/
- private void notifySubscriber(URL url, String serviceName, NotifyListener
listener, Collection<Instance> instances) {
+ private void notifySubscriber(URL url, NotifyListener listener,
Collection<Instance> instances) {
List<Instance> healthyInstances = new LinkedList<>(instances);
// Healthy Instances
filterHealthyInstances(healthyInstances);
- List<URL> urls = buildURLs(url, serviceName, healthyInstances);
+ List<URL> urls = buildURLs(url, healthyInstances);
NacosRegistry.this.notify(url, listener, urls);
}
@@ -385,7 +421,7 @@ public class NacosRegistry extends FailbackRegistry {
*/
private String[] getCategories(URL url) {
return ANY_VALUE.equals(url.getServiceInterface()) ?
- ALL_SUPPORTED_CATEGORIES : url.getParameter(CATEGORY_KEY,new
String[]{DEFAULT_CATEGORY});
+ ALL_SUPPORTED_CATEGORIES : of(DEFAULT_CATEGORY);
}
private URL buildURL(Instance instance) {
@@ -399,18 +435,6 @@ public class NacosRegistry extends FailbackRegistry {
instance.getMetadata());
}
- private List<URL> emptyURL(URL consumerURL, String serviceName) {
- int i = serviceName.indexOf(SERVICE_NAME_SEPARATOR);
- String category = i < 0 ? serviceName : serviceName.substring(0, i);
- URL empty = URLBuilder.from(consumerURL)
- .setProtocol(EMPTY_PROTOCOL)
- .addParameter(CATEGORY_KEY, category)
- .build();
- List<URL> result = new ArrayList<URL>();
- result.add(empty);
- return result;
- }
-
private Instance createInstance(URL url) {
// Append default category if absent
String category = url.getParameter(CATEGORY_KEY, DEFAULT_CATEGORY);
@@ -426,6 +450,10 @@ public class NacosRegistry extends FailbackRegistry {
return instance;
}
+ private NacosServiceName createServiceName(URL url) {
+ return valueOf(url);
+ }
+
private String getServiceName(URL url) {
String category = url.getParameter(CATEGORY_KEY, DEFAULT_CATEGORY);
return getServiceName(url, category);
diff --git
a/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosRegistryFactory.java
b/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosRegistryFactory.java
index d702acf..1e9ed65 100644
---
a/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosRegistryFactory.java
+++
b/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosRegistryFactory.java
@@ -101,7 +101,7 @@ public class NacosRegistryFactory extends
AbstractRegistryFactory {
private void putPropertyIfAbsent(URL url, Properties properties, String
propertyName) {
String propertyValue = url.getParameter(propertyName);
- if (StringUtils.isNotEmpty(propertyValue)) {
+ if (propertyValue != null && propertyValue.trim().length() != 0) {
properties.setProperty(propertyName, propertyValue);
}
}
diff --git
a/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosServiceName.java
b/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosServiceName.java
new file mode 100644
index 0000000..cae9f19
--- /dev/null
+++
b/dubbo-registry/dubbo-registry-nacos/src/main/java/org/apache/dubbo/registry/nacos/NacosServiceName.java
@@ -0,0 +1,239 @@
+/*
+ * 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 org.apache.dubbo.common.URL;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Objects;
+
+import static org.apache.commons.lang3.ArrayUtils.getLength;
+import static org.apache.commons.lang3.StringUtils.contains;
+import static org.apache.commons.lang3.StringUtils.isBlank;
+import static org.apache.commons.lang3.StringUtils.split;
+import static org.apache.commons.lang3.StringUtils.splitPreserveAllTokens;
+import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
+import static org.apache.dubbo.common.constants.RegistryConstants.CATEGORY_KEY;
+import static
org.apache.dubbo.common.constants.RegistryConstants.DEFAULT_CATEGORY;
+
+/**
+ * The service name of Nacos
+ *
+ * @since 2.7.3
+ */
+public class NacosServiceName {
+
+ public static final String NAME_SEPARATOR = ":";
+
+ public static final String VALUE_SEPARATOR = ",";
+
+ public static final String WILDCARD = "*";
+
+ public static final String DEFAULT_PARAM_VALUE = "";
+
+ private static final int CATEGORY_INDEX = 0;
+
+ private static final int SERVICE_INTERFACE_INDEX = 1;
+
+ private static final int SERVICE_VERSION_INDEX = 2;
+
+ private static final int SERVICE_GROUP_INDEX = 3;
+
+ private String category;
+
+ private String serviceInterface;
+
+ private String version;
+
+ private String group;
+
+ private String value;
+
+ public NacosServiceName() {
+ }
+
+ public NacosServiceName(URL url) {
+ serviceInterface = url.getParameter(INTERFACE_KEY);
+ category = isConcrete(serviceInterface) ? DEFAULT_CATEGORY :
url.getParameter(CATEGORY_KEY);
+ version = url.getParameter(VERSION_KEY, DEFAULT_PARAM_VALUE);
+ group = url.getParameter(GROUP_KEY, DEFAULT_PARAM_VALUE);
+ value = toValue();
+ }
+
+ public NacosServiceName(String value) {
+ this.value = value;
+ String[] segments = splitPreserveAllTokens(value, NAME_SEPARATOR);
+ this.category = segments[CATEGORY_INDEX];
+ this.serviceInterface = segments[SERVICE_INTERFACE_INDEX];
+ this.version = segments[SERVICE_VERSION_INDEX];
+ this.group = segments[SERVICE_GROUP_INDEX];
+ }
+
+ /**
+ * Build an instance of {@link NacosServiceName}
+ *
+ * @param url
+ * @return
+ */
+ public static NacosServiceName valueOf(URL url) {
+ return new NacosServiceName(url);
+ }
+
+ /**
+ * Is the concrete service name or not
+ *
+ * @return if concrete , return <code>true</code>, or <code>false</code>
+ */
+ public boolean isConcrete() {
+ return isConcrete(serviceInterface) && isConcrete(version) &&
isConcrete(group);
+ }
+
+ public boolean isCompatible(NacosServiceName concreteServiceName) {
+
+ if (!concreteServiceName.isConcrete()) { // The argument must be the
concrete NacosServiceName
+ return false;
+ }
+
+ // Not match comparison
+ if (!StringUtils.equals(this.category, concreteServiceName.category) &&
+ !ArrayUtils.contains(splitPreserveAllTokens(this.category,
VALUE_SEPARATOR), concreteServiceName.category)) {
+ return false;
+ }
+
+ if (!StringUtils.equals(this.serviceInterface,
concreteServiceName.serviceInterface)) {
+ return false;
+ }
+
+ // wildcard condition
+ if (isWildcard(this.version)) {
+ return true;
+ }
+
+ if (isWildcard(this.group)) {
+ return true;
+ }
+
+ // range condition
+ if (!StringUtils.equals(this.version, concreteServiceName.version) &&
+ !matchRange(this.version, concreteServiceName.version)) {
+ return false;
+ }
+
+ if (!StringUtils.equals(this.group, concreteServiceName.group) &&
+ !matchRange(this.group, concreteServiceName.group)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ private boolean matchRange(String range, String value) {
+ if (isBlank(range)) {
+ return true;
+ }
+ if (!isRange(range)) {
+ return false;
+ }
+ String[] values = split(range, VALUE_SEPARATOR);
+ return ArrayUtils.contains(values, value);
+ }
+
+ private boolean isConcrete(String value) {
+ return !isWildcard(value) && !isRange(value);
+ }
+
+ private boolean isWildcard(String value) {
+ return WILDCARD.equals(value);
+ }
+
+ private boolean isRange(String value) {
+ if (contains(value, VALUE_SEPARATOR)) {
+ String[] values = split(value, VALUE_SEPARATOR);
+ return getLength(values) > 1;
+ }
+ return false;
+ }
+
+ public String getCategory() {
+ return category;
+ }
+
+ public void setCategory(String category) {
+ this.category = category;
+ }
+
+ public String getServiceInterface() {
+ return serviceInterface;
+ }
+
+ public void setServiceInterface(String serviceInterface) {
+ this.serviceInterface = serviceInterface;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public String getGroup() {
+ return group;
+ }
+
+ public void setGroup(String group) {
+ this.group = group;
+ }
+
+ public String getValue() {
+ if (value == null) {
+ value = toValue();
+ }
+ return value;
+ }
+
+ private String toValue() {
+ return new StringBuilder(category)
+ .append(NAME_SEPARATOR).append(serviceInterface)
+ .append(NAME_SEPARATOR).append(version)
+ .append(NAME_SEPARATOR).append(group)
+ .toString();
+ }
+
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof NacosServiceName)) return false;
+ NacosServiceName that = (NacosServiceName) o;
+ return Objects.equals(getValue(), that.getValue());
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(getValue());
+ }
+
+ public String toString() {
+ return getValue();
+ }
+}
diff --git
a/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/demo/consumer/DemoServiceConsumerXmlBootstrap.java
b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/demo/consumer/DemoServiceConsumerXmlBootstrap.java
index cc25f8c..8f65faf 100644
---
a/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/demo/consumer/DemoServiceConsumerXmlBootstrap.java
+++
b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/demo/consumer/DemoServiceConsumerXmlBootstrap.java
@@ -32,10 +32,14 @@ public class DemoServiceConsumerXmlBootstrap {
context.setConfigLocation("/META-INF/spring/dubbo-consumer-context.xml");
context.refresh();
System.out.println("DemoService consumer (XML) is starting...");
- DemoService demoService = context.getBean("demoService",
DemoService.class);
- for (int i = 0; i < 10; i++) {
- System.out.println(demoService.sayName("小马哥(mercyblitz)"));
+
+ for (int i = 1; i <= 5; i++) {
+ DemoService demoService = context.getBean("demoService" + i,
DemoService.class);
+ for (int j = 0; j < 10; j++) {
+ System.out.println(demoService.sayName("小马哥(mercyblitz)"));
+ }
}
+
System.in.read();
context.close();
}
diff --git
a/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosServiceNameTest.java
b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosServiceNameTest.java
new file mode 100644
index 0000000..2f8e1c3
--- /dev/null
+++
b/dubbo-registry/dubbo-registry-nacos/src/test/java/org/apache/dubbo/registry/nacos/NacosServiceNameTest.java
@@ -0,0 +1,123 @@
+/*
+ * 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 org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static
org.apache.dubbo.common.constants.RegistryConstants.DEFAULT_CATEGORY;
+import static org.apache.dubbo.registry.nacos.NacosServiceName.WILDCARD;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * {@link NacosServiceName} Test
+ *
+ * @since 2.7.3
+ */
+public class NacosServiceNameTest {
+
+ private static final String category = DEFAULT_CATEGORY;
+
+ private static final String serviceInterface =
"org.apache.dubbo.registry.nacos.NacosServiceName";
+
+ private static final String version = "1.0.0";
+
+ private static final String group = "default";
+
+ private final NacosServiceName name = new NacosServiceName();
+
+ @BeforeEach
+ public void init() {
+ name.setCategory(category);
+ name.setServiceInterface(serviceInterface);
+ name.setVersion(version);
+ name.setGroup(group);
+ }
+
+ @Test
+ public void testGetter() {
+ assertEquals(category, name.getCategory());
+ assertEquals(serviceInterface, name.getServiceInterface());
+ assertEquals(version, name.getVersion());
+ assertEquals(group, name.getGroup());
+
assertEquals("providers:org.apache.dubbo.registry.nacos.NacosServiceName:1.0.0:default",
name.getValue());
+ }
+
+ @Test
+ public void testToString() {
+
assertEquals("providers:org.apache.dubbo.registry.nacos.NacosServiceName:1.0.0:default",
name.toString());
+ }
+
+ @Test
+ public void testIsConcrete() {
+
+ assertTrue(name.isConcrete());
+
+ name.setGroup(WILDCARD);
+ assertFalse(name.isConcrete());
+
+ init();
+ name.setVersion(WILDCARD);
+ assertFalse(name.isConcrete());
+
+ init();
+ name.setGroup(null);
+ name.setVersion(null);
+ assertTrue(name.isConcrete());
+
+ }
+
+ @Test
+ public void testIsCompatible() {
+
+ NacosServiceName concrete = new NacosServiceName();
+
+ assertFalse(name.isCompatible(concrete));
+
+ // set category
+ concrete.setCategory(category);
+ assertFalse(name.isCompatible(concrete));
+
+ concrete.setServiceInterface(serviceInterface);
+ assertFalse(name.isCompatible(concrete));
+
+ concrete.setVersion(version);
+ assertFalse(name.isCompatible(concrete));
+
+ concrete.setGroup(group);
+ assertTrue(name.isCompatible(concrete));
+
+ // wildcard cases
+ name.setGroup(WILDCARD);
+ assertTrue(name.isCompatible(concrete));
+
+ init();
+ name.setVersion(WILDCARD);
+ assertTrue(name.isCompatible(concrete));
+
+ // range cases
+ init();
+ name.setGroup(group + ",2.0.0");
+ assertTrue(name.isCompatible(concrete));
+
+ init();
+ name.setVersion(version + ",2.0.0");
+ assertTrue(name.isCompatible(concrete));
+ }
+}
diff --git
a/dubbo-registry/dubbo-registry-nacos/src/test/resources/META-INF/spring/dubbo-consumer-context.xml
b/dubbo-registry/dubbo-registry-nacos/src/test/resources/META-INF/spring/dubbo-consumer-context.xml
index 3fa32d7..9054c4f 100644
---
a/dubbo-registry/dubbo-registry-nacos/src/test/resources/META-INF/spring/dubbo-consumer-context.xml
+++
b/dubbo-registry/dubbo-registry-nacos/src/test/resources/META-INF/spring/dubbo-consumer-context.xml
@@ -10,6 +10,18 @@
<dubbo:registry address="nacos://127.0.0.1:8848"/>
<!-- Reference interface -->
- <dubbo:reference id="demoService"
interface="org.apache.dubbo.demo.service.DemoService" version="2.0.0"/>
+ <dubbo:reference id="demoService1"
interface="org.apache.dubbo.demo.service.DemoService" version="2.0.0"
+ group="default"/>
+
+ <dubbo:reference id="demoService2"
interface="org.apache.dubbo.demo.service.DemoService" version="*"
+ group="default"/>
+
+ <dubbo:reference id="demoService3"
interface="org.apache.dubbo.demo.service.DemoService" version="2.0.0"
+ group="default"/>
+
+ <dubbo:reference id="demoService4"
interface="org.apache.dubbo.demo.service.DemoService" version="2.0.0"
group="*"/>
+
+ <dubbo:reference id="demoService5"
interface="org.apache.dubbo.demo.service.DemoService" version="2.0.0"
+ group="default,test"/>
</beans>
\ No newline at end of file
diff --git
a/dubbo-registry/dubbo-registry-nacos/src/test/resources/META-INF/spring/dubbo-provider-context.xml
b/dubbo-registry/dubbo-registry-nacos/src/test/resources/META-INF/spring/dubbo-provider-context.xml
index 36b1267..207ab7b 100644
---
a/dubbo-registry/dubbo-registry-nacos/src/test/resources/META-INF/spring/dubbo-provider-context.xml
+++
b/dubbo-registry/dubbo-registry-nacos/src/test/resources/META-INF/spring/dubbo-provider-context.xml
@@ -12,7 +12,8 @@
<!-- Use random port as Dubbo -->
<dubbo:protocol name="dubbo" port="-1"/>
- <dubbo:service interface="org.apache.dubbo.demo.service.DemoService"
ref="demoService" version="2.0.0"/>
+ <dubbo:service interface="org.apache.dubbo.demo.service.DemoService"
ref="demoService" version="2.0.0"
+ group="default"/>
<bean id="demoService"
class="org.apache.dubbo.demo.service.DefaultService"/>
</beans>
\ No newline at end of file
diff --git
a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ActiveLimitFilter.java
b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ActiveLimitFilter.java
index 27aa1f5..ee760ee 100644
---
a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ActiveLimitFilter.java
+++
b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ActiveLimitFilter.java
@@ -57,7 +57,7 @@ public class ActiveLimitFilter extends ListenableFilter {
URL url = invoker.getUrl();
String methodName = invocation.getMethodName();
int max = invoker.getUrl().getMethodParameter(methodName, ACTIVES_KEY,
0);
- RpcStatus rpcStatus = RpcStatus.getStatus(invoker.getUrl(),
invocation.getMethodName());
+ final RpcStatus rpcStatus = RpcStatus.getStatus(invoker.getUrl(),
invocation.getMethodName());
if (!RpcStatus.beginCount(url, methodName, max)) {
long timeout =
invoker.getUrl().getMethodParameter(invocation.getMethodName(), TIMEOUT_KEY, 0);
long start = System.currentTimeMillis();
@@ -119,7 +119,7 @@ public class ActiveLimitFilter extends ListenableFilter {
return StringUtils.isNotEmpty(beginTime) ?
System.currentTimeMillis() - Long.parseLong(beginTime) : 0;
}
- private void notifyFinish(RpcStatus rpcStatus, int max) {
+ private void notifyFinish(final RpcStatus rpcStatus, int max) {
if (max > 0) {
synchronized (rpcStatus) {
rpcStatus.notifyAll();