From fcd1af81fd2fd6ad55c78f281d7b29feb10a006a Mon Sep 17 00:00:00 2001 From: xujingfeng <250577914@qq.com> Date: Wed, 22 Aug 2018 16:17:44 +0800 Subject: [PATCH] [Dubbo- support tag router feature] Add a new Router implement -- TagRouter (#2228) * tagRouter feature * update dubbo.xsd * remove reference router param * add Unit Test * rollback pom.xml for merge * rollback pom.xml for merge * fix checkstyle * fix checkstyle * fix unit test * format import style * add license&remove author info * trigger again --- .../rpc/cluster/router/tag/TagRouter.java | 109 +++++++++++ .../cluster/router/tag/TagRouterFactory.java | 32 ++++ ...org.apache.dubbo.rpc.cluster.RouterFactory | 3 +- .../rpc/cluster/router/tag/TagRouterTest.java | 169 ++++++++++++++++++ .../org/apache/dubbo/common/Constants.java | 4 + .../dubbo/config/AbstractInterfaceConfig.java | 1 - .../dubbo/config/AbstractReferenceConfig.java | 1 - .../dubbo/config/AbstractServiceConfig.java | 10 ++ .../dubbo/config/annotation/Service.java | 5 + .../dubbo/config/spring/AnnotationBean.java | 24 +-- .../main/resources/META-INF/compat/dubbo.xsd | 6 + .../src/main/resources/META-INF/dubbo.xsd | 6 + .../integration/RegistryDirectory.java | 8 +- 13 files changed, 360 insertions(+), 18 deletions(-) create mode 100644 dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouter.java create mode 100644 dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouterFactory.java create mode 100644 dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouterTest.java diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouter.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouter.java new file mode 100644 index 00000000000..38fd6166eff --- /dev/null +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouter.java @@ -0,0 +1,109 @@ +/* + * 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.rpc.cluster.router.tag; + + +import org.apache.dubbo.common.Constants; +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.logger.Logger; +import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.common.utils.StringUtils; +import org.apache.dubbo.rpc.Invocation; +import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.RpcContext; +import org.apache.dubbo.rpc.RpcException; +import org.apache.dubbo.rpc.cluster.Router; + +import java.util.ArrayList; +import java.util.List; + +/** + * TagRouter + */ +public class TagRouter implements Router, Comparable { + + private static final Logger logger = LoggerFactory.getLogger(TagRouter.class); + + private final int priority; + private final URL url; + + public static final URL ROUTER_URL = new URL("tag", Constants.ANYHOST_VALUE, 0, Constants.ANY_VALUE).addParameters(Constants.RUNTIME_KEY, "true"); + + public TagRouter(URL url) { + this.url = url; + this.priority = url.getParameter(Constants.PRIORITY_KEY, 0); + } + + public TagRouter() { + this.url = ROUTER_URL; + this.priority = url.getParameter(Constants.PRIORITY_KEY, 0); + } + + @Override + public URL getUrl() { + return url; + } + + @Override + public List> route(List> invokers, URL url, Invocation invocation) throws RpcException { + // filter + List> result = new ArrayList<>(); + try { + // Dynamic param + String tag = RpcContext.getContext().getAttachment(Constants.REQUEST_TAG_KEY); + // Tag request + if (!StringUtils.isEmpty(tag)) { + // Select tag invokers first + for (Invoker invoker : invokers) { + if (tag.equals(invoker.getUrl().getParameter(Constants.TAG_KEY))) { + result.add(invoker); + } + } + // If no invoker be selected, downgrade to normal invokers + if (result.isEmpty()) { + for (Invoker invoker : invokers) { + if (StringUtils.isEmpty(invoker.getUrl().getParameter(Constants.TAG_KEY))) { + result.add(invoker); + } + } + } + // Normal request + } else { + for (Invoker invoker : invokers) { + // Can't access tag invoker,only normal invoker should be selected + if (StringUtils.isEmpty(invoker.getUrl().getParameter(Constants.TAG_KEY))) { + result.add(invoker); + } + } + } + return result; + } catch (Exception e) { + logger.error("Route by tag error,return all invokers.", e); + } + // Downgrade to all invokers + return invokers; + } + + @Override + public int compareTo(Router o) { + if (o == null || o.getClass() != TagRouter.class) { + return 1; + } + TagRouter c = (TagRouter) o; + return this.priority == c.priority ? url.toFullString().compareTo(c.url.toFullString()) : (this.priority > c.priority ? 1 : -1); + } +} diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouterFactory.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouterFactory.java new file mode 100644 index 00000000000..05ad427ce6e --- /dev/null +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouterFactory.java @@ -0,0 +1,32 @@ +/* + * 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.rpc.cluster.router.tag; + + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.rpc.cluster.Router; +import org.apache.dubbo.rpc.cluster.RouterFactory; + +public class TagRouterFactory implements RouterFactory { + + public static final String NAME = "tag"; + + @Override + public Router getRouter(URL url) { + return new TagRouter(url); + } +} diff --git a/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.RouterFactory b/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.RouterFactory index 0ada9c3be9c..2d4717cfaa3 100644 --- a/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.RouterFactory +++ b/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.RouterFactory @@ -1,3 +1,4 @@ file=org.apache.dubbo.rpc.cluster.router.file.FileRouterFactory script=org.apache.dubbo.rpc.cluster.router.script.ScriptRouterFactory -condition=org.apache.dubbo.rpc.cluster.router.condition.ConditionRouterFactory \ No newline at end of file +condition=org.apache.dubbo.rpc.cluster.router.condition.ConditionRouterFactory +tag=org.apache.dubbo.rpc.cluster.router.tag.TagRouterFactory \ No newline at end of file diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouterTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouterTest.java new file mode 100644 index 00000000000..839af44efe9 --- /dev/null +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouterTest.java @@ -0,0 +1,169 @@ +/* + * 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.rpc.cluster.router.tag; + +import org.apache.dubbo.common.Constants; +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.extension.ExtensionLoader; +import org.apache.dubbo.common.utils.NetUtils; +import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.RpcContext; +import org.apache.dubbo.rpc.RpcInvocation; +import org.apache.dubbo.rpc.cluster.Router; +import org.apache.dubbo.rpc.cluster.RouterFactory; +import org.apache.dubbo.rpc.cluster.router.MockInvoker; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +public class TagRouterTest { + + private URL tagUrl = new URL("tag" + , Constants.ANYHOST_VALUE, 0 + , Constants.ANY_VALUE) + .addParameters( + Constants.RUNTIME_KEY, "true" + ); + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + } + + @Before + public void setUp() throws Exception { + } + + @Test + public void testRoute_matchTag() { + + RpcContext.getContext().setAttachment(Constants.REQUEST_TAG_KEY, "red"); + + List> invokers = new ArrayList<>(); + Invoker redInvoker = new MockInvoker<>(URL.valueOf( + "dubbo://10.20.3.1:20880/com.foo.BarService?tag=red")); + Invoker yellowInvoker = new MockInvoker<>(URL.valueOf( + "dubbo://10.20.3.2:20880/com.foo.BarService?tag=yellow")); + Invoker blueInvoker = new MockInvoker<>(URL.valueOf( + "dubbo://10.20.3.3:20880/com.foo.BarService?tag=blue")); + Invoker defaultInvoker = new MockInvoker<>(URL.valueOf( + "dubbo://10.20.3.4:20880/com.foo.BarService")); + + invokers.add(redInvoker); + invokers.add(yellowInvoker); + invokers.add(blueInvoker); + invokers.add(defaultInvoker); + + Router tagRouter = new TagRouterFactory().getRouter(tagUrl); + List> filteredInvokers = tagRouter.route(invokers, URL.valueOf("consumer://" + NetUtils.getLocalHost() + "/com.foo.BarService"), new RpcInvocation()); + Assert.assertTrue(filteredInvokers.contains(redInvoker)); + Assert.assertFalse(filteredInvokers.contains(yellowInvoker)); + Assert.assertFalse(filteredInvokers.contains(blueInvoker)); + Assert.assertFalse(filteredInvokers.contains(defaultInvoker)); + } + + @Test + public void testRoute_matchDefault() { + + RpcContext.getContext().setAttachment(Constants.REQUEST_TAG_KEY, ""); + + List> invokers = new ArrayList<>(); + Invoker redInvoker = new MockInvoker<>(URL.valueOf( + "dubbo://10.20.3.1:20880/com.foo.BarService?tag=red")); + Invoker yellowInvoker = new MockInvoker<>(URL.valueOf( + "dubbo://10.20.3.2:20880/com.foo.BarService?tag=yellow")); + Invoker blueInvoker = new MockInvoker<>(URL.valueOf( + "dubbo://10.20.3.3:20880/com.foo.BarService?tag=blue")); + Invoker defaultInvoker = new MockInvoker<>(URL.valueOf( + "dubbo://10.20.3.4:20880/com.foo.BarService")); + + invokers.add(redInvoker); + invokers.add(yellowInvoker); + invokers.add(blueInvoker); + invokers.add(defaultInvoker); + + Router tagRouter = new TagRouterFactory().getRouter(tagUrl); + List> filteredInvokers = tagRouter.route(invokers, URL.valueOf("consumer://" + NetUtils.getLocalHost() + "/com.foo.BarService"), new RpcInvocation()); + Assert.assertTrue(filteredInvokers.contains(defaultInvoker)); + Assert.assertFalse(filteredInvokers.contains(yellowInvoker)); + Assert.assertFalse(filteredInvokers.contains(blueInvoker)); + Assert.assertFalse(filteredInvokers.contains(redInvoker)); + } + + @Test + public void testRoute_requestWithTag_shouldDowngrade() { + + RpcContext.getContext().setAttachment(Constants.REQUEST_TAG_KEY, "black"); + + List> invokers = new ArrayList<>(); + Invoker redInvoker = new MockInvoker<>(URL.valueOf( + "dubbo://10.20.3.1:20880/com.foo.BarService?tag=red")); + Invoker yellowInvoker = new MockInvoker<>(URL.valueOf( + "dubbo://10.20.3.2:20880/com.foo.BarService?tag=yellow")); + Invoker blueInvoker = new MockInvoker<>(URL.valueOf( + "dubbo://10.20.3.3:20880/com.foo.BarService?tag=blue")); + Invoker defaultInvoker = new MockInvoker<>(URL.valueOf( + "dubbo://10.20.3.4:20880/com.foo.BarService")); + + invokers.add(redInvoker); + invokers.add(yellowInvoker); + invokers.add(blueInvoker); + invokers.add(defaultInvoker); + + Router tagRouter = new TagRouterFactory().getRouter(tagUrl); + List> filteredInvokers = tagRouter.route(invokers, URL.valueOf("consumer://" + NetUtils.getLocalHost() + "/com.foo.BarService"), new RpcInvocation()); + Assert.assertTrue(filteredInvokers.contains(defaultInvoker)); + Assert.assertFalse(filteredInvokers.contains(yellowInvoker)); + Assert.assertFalse(filteredInvokers.contains(blueInvoker)); + Assert.assertFalse(filteredInvokers.contains(redInvoker)); + } + + @Test + public void testRoute_requestWithoutTag_shouldNotDowngrade() { + + RpcContext.getContext().setAttachment(Constants.REQUEST_TAG_KEY, ""); + + List> invokers = new ArrayList<>(); + Invoker redInvoker = new MockInvoker<>(URL.valueOf( + "dubbo://10.20.3.1:20880/com.foo.BarService?tag=red")); + Invoker yellowInvoker = new MockInvoker<>(URL.valueOf( + "dubbo://10.20.3.2:20880/com.foo.BarService?tag=yellow")); + Invoker blueInvoker = new MockInvoker<>(URL.valueOf( + "dubbo://10.20.3.3:20880/com.foo.BarService?tag=blue")); + + invokers.add(redInvoker); + invokers.add(yellowInvoker); + invokers.add(blueInvoker); + + Router tagRouter = new TagRouterFactory().getRouter(tagUrl); + List> filteredInvokers = tagRouter.route(invokers, URL.valueOf("consumer://" + NetUtils.getLocalHost() + "/com.foo.BarService"), new RpcInvocation()); + Assert.assertEquals(0, filteredInvokers.size()); + } + + @Test + public void testRoute_createBySpi() { + URL zkProvider = URL.valueOf("zookeeper://10.20.3.1:20880/com.foo.BarService?router=tag"); + String parameter = zkProvider.getParameter(Constants.ROUTER_KEY); + RouterFactory routerFactory = ExtensionLoader.getExtensionLoader(RouterFactory.class).getExtension(parameter); + Router tagRouter = routerFactory.getRouter(zkProvider); + Assert.assertTrue(tagRouter instanceof TagRouter); + } + +} diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/Constants.java b/dubbo-common/src/main/java/org/apache/dubbo/common/Constants.java index a1c8fac34c6..95069306907 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/Constants.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/Constants.java @@ -641,6 +641,10 @@ public class Constants { public static final String MULTICAST = "multicast"; + public static final String TAG_KEY = "tag"; + + public static final String REQUEST_TAG_KEY = "request.tag"; + /* * private Constants(){ } */ diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java index 91a4a1641d6..70ab62e4493 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java @@ -522,5 +522,4 @@ public String getScope() { public void setScope(String scope) { this.scope = scope; } - } \ No newline at end of file diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractReferenceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractReferenceConfig.java index 08f3ad5e97b..552ccf1e4a7 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractReferenceConfig.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractReferenceConfig.java @@ -197,5 +197,4 @@ public void setGroup(String group) { checkKey("group", group); this.group = group; } - } diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractServiceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractServiceConfig.java index f23341fff17..4da1ffa89db 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractServiceConfig.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractServiceConfig.java @@ -73,6 +73,9 @@ public abstract class AbstractServiceConfig extends AbstractInterfaceConfig { // serialization private String serialization; + // provider tag + protected String tag; + public String getVersion() { return version; } @@ -240,4 +243,11 @@ public void setSerialization(String serialization) { this.serialization = serialization; } + public String getTag() { + return tag; + } + + public void setTag(String tag) { + this.tag = tag; + } } diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/annotation/Service.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/annotation/Service.java index bee838745e4..6f956f50c05 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/annotation/Service.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/annotation/Service.java @@ -263,4 +263,9 @@ * Registry spring bean name */ String[] registry() default {}; + + /** + * Service tag name + */ + String tag() default ""; } diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/AnnotationBean.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/AnnotationBean.java index 61513547c15..7612c3302a3 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/AnnotationBean.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/AnnotationBean.java @@ -33,7 +33,6 @@ import org.apache.dubbo.config.ServiceConfig; import org.apache.dubbo.config.annotation.Reference; import org.apache.dubbo.config.annotation.Service; - import org.springframework.beans.BeansException; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; @@ -76,7 +75,7 @@ public String getPackage() { public void setPackage(String annotationPackage) { this.annotationPackage = annotationPackage; this.annotationPackages = (annotationPackage == null || annotationPackage.length() == 0) ? null - : Constants.COMMA_SPLIT_PATTERN.split(annotationPackage); + : Constants.COMMA_SPLIT_PATTERN.split(annotationPackage); } @Override @@ -86,7 +85,7 @@ public void setApplicationContext(ApplicationContext applicationContext) throws @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) - throws BeansException { + throws BeansException { if (annotationPackage == null || annotationPackage.length() == 0) { return; } @@ -135,7 +134,7 @@ public void destroy() { @Override public Object postProcessAfterInitialization(Object bean, String beanName) - throws BeansException { + throws BeansException { if (!isMatchPackage(bean)) { return bean; } @@ -144,7 +143,7 @@ public Object postProcessAfterInitialization(Object bean, String beanName) ServiceBean serviceConfig = new ServiceBean(service); serviceConfig.setRef(bean); if (void.class.equals(service.interfaceClass()) - && "".equals(service.interfaceName())) { + && "".equals(service.interfaceName())) { if (bean.getClass().getInterfaces().length > 0) { serviceConfig.setInterface(bean.getClass().getInterfaces()[0]); } else { @@ -186,6 +185,9 @@ public Object postProcessAfterInitialization(Object bean, String beanName) } serviceConfig.setProtocols(protocolConfigs); } + if (service.tag().length() > 0) { + serviceConfig.setTag(service.tag()); + } try { serviceConfig.afterPropertiesSet(); } catch (RuntimeException e) { @@ -202,7 +204,7 @@ public Object postProcessAfterInitialization(Object bean, String beanName) @Override public Object postProcessBeforeInitialization(Object bean, String beanName) - throws BeansException { + throws BeansException { if (!isMatchPackage(bean)) { return bean; } @@ -210,9 +212,9 @@ public Object postProcessBeforeInitialization(Object bean, String beanName) for (Method method : methods) { String name = method.getName(); if (name.length() > 3 && name.startsWith("set") - && method.getParameterTypes().length == 1 - && Modifier.isPublic(method.getModifiers()) - && !Modifier.isStatic(method.getModifiers())) { + && method.getParameterTypes().length == 1 + && Modifier.isPublic(method.getModifiers()) + && !Modifier.isStatic(method.getModifiers())) { try { Reference reference = method.getAnnotation(Reference.class); if (reference != null) { @@ -262,8 +264,8 @@ private Object refer(Reference reference, Class referenceClass) { //method.ge if (referenceConfig == null) { referenceConfig = new ReferenceBean(reference); if (void.class.equals(reference.interfaceClass()) - && "".equals(reference.interfaceName()) - && referenceClass.isInterface()) { + && "".equals(reference.interfaceName()) + && referenceClass.isInterface()) { referenceConfig.setInterface(referenceClass); } if (applicationContext != null) { diff --git a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/compat/dubbo.xsd b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/compat/dubbo.xsd index 6206048311b..290c750c93b 100644 --- a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/compat/dubbo.xsd +++ b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/compat/dubbo.xsd @@ -307,6 +307,12 @@ + + + + + + diff --git a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd index ecf7d7b7a5d..ecec23acc0a 100644 --- a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd +++ b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd @@ -307,6 +307,12 @@ + + + + + + diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryDirectory.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryDirectory.java index 727bca297e2..6b366b2921b 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryDirectory.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryDirectory.java @@ -55,7 +55,6 @@ /** * RegistryDirectory - * */ public class RegistryDirectory extends AbstractDirectory implements NotifyListener { @@ -445,7 +444,8 @@ private List> route(List> invokers, String method) { List routers = getRouters(); if (routers != null) { for (Router router : routers) { - if (router.getUrl() != null) { + // If router's url not null and is not route by runtime,we filter invokers here + if (router.getUrl() != null && !router.getUrl().getParameter(Constants.RUNTIME_KEY, false)) { invokers = router.route(invokers, getConsumerUrl(), invocation); } } @@ -573,8 +573,8 @@ public List> doList(Invocation invocation) { if (forbidden) { // 1. No service provider 2. Service providers are disabled throw new RpcException(RpcException.FORBIDDEN_EXCEPTION, - "No provider available from registry " + getUrl().getAddress() + " for service " + getConsumerUrl().getServiceKey() + " on consumer " + NetUtils.getLocalHost() - + " use dubbo version " + Version.getVersion() + ", please check status of providers(disabled, not registered or in blacklist)."); + "No provider available from registry " + getUrl().getAddress() + " for service " + getConsumerUrl().getServiceKey() + " on consumer " + NetUtils.getLocalHost() + + " use dubbo version " + Version.getVersion() + ", please check status of providers(disabled, not registered or in blacklist)."); } List> invokers = null; Map>> localMethodInvokerMap = this.methodInvokerMap; // local reference