Merge branch '2.7.1-release'

This commit is contained in:
Ian Luo 2019-03-26 17:10:57 +08:00
commit 91101cf741
129 changed files with 2140 additions and 662 deletions

View File

@ -1,5 +1,86 @@
# Release Notes
## 2.7.1
### Notice
'zkclient' extension for 'org.apache.dubbo.remoting.zookeeper.ZookeeperTransporter' is removed from Dubbo 2.7.1, and 'curator' extension becomes the default extension. If you happen to config your application to use 'zkclient' explicitly, pls. switch to use 'curator' instead.
### New Features
- service register support on nacos [#3582](https://github.com/apache/incubator-dubbo/issues/3582)
- support consul as registry center, config center and metadata center [#983](https://github.com/apache/incubator-dubbo/issues/983)
- service registry support/config center support on etcd [#808](https://github.com/apache/incubator-dubbo/issues/808)
- metrics support in dubbo 2.7.1 [#3598](https://github.com/apache/incubator-dubbo/issues/3598)
- @Argument @Method support [#2405](https://github.com/apache/incubator-dubbo/issues/2045)
### Enhancement
- [Enhancement] @EnableDubboConfigBinding annotates @Repeatable [#1770](https://github.com/apache/incubator-dubbo/issues/1770)
- [Enhancement] Change the default behavior of @EnableDubboConfig.multiple() [#3193](https://github.com/apache/incubator-dubbo/issues/3193)
- Should make annotation easier to use in multiple items circumstance [#3039](https://github.com/apache/incubator-dubbo/issues/3039)
- NoSuchMethodError are thrown when add custom Filter using dubbo2.6.5 and JDK1.6 and upgrade to dubbo2.7.0 [#3570](https://github.com/apache/incubator-dubbo/issues/3570)
- introduce dubbo-dependencies-zookeeper [#3607](https://github.com/apache/incubator-dubbo/pull/3607)
- Zookeeper ConfigCenter reuse the client abstraction and connection session [#3288](https://github.com/apache/incubator-dubbo/issues/3288)
- [Survey] Is it necessary to continue to maintain zkclient in dubbo project? [#3569](https://github.com/apache/incubator-dubbo/issues/3569)
- Start to use IdleStateHandler in Netty4 [#3341](https://github.com/apache/incubator-dubbo/pull/3341)
- Support multiple shared links [#2457](https://github.com/apache/incubator-dubbo/pull/2457)
- Optimize heartbeat [#3299](https://github.com/apache/incubator-dubbo/pull/3299)
- AccessLogFilter simple date format reduce instance creation [#3026](https://github.com/apache/incubator-dubbo/issues/3026)
- Support wildcard ip for tag router rule. [#3289](https://github.com/apache/incubator-dubbo/issues/3289)
- ScriptRouter should cache CompiledScript [#390](https://github.com/apache/incubator-dubbo/issues/390)
- Optimize compareTo in Router to guarantee consistent behaviour. [#3302](https://github.com/apache/incubator-dubbo/issues/3302)
- RMI protocol doesn't support generic invocation [#2779](https://github.com/apache/incubator-dubbo/issues/2779)
- a more elegant way to enhance HashedWheelTimer [#3567](https://github.com/apache/incubator-dubbo/pull/3567)
- obtain local address incorrectly sometimes in dubbo [#538](https://github.com/apache/incubator-dubbo/issues/538)
- implement pull request #3412 on master branch [#3418](https://github.com/apache/incubator-dubbo/pull/3418)
- enhancement for event of response (follow up for pull request #3043) [#3244](https://github.com/apache/incubator-dubbo/issues/3244)
- bump up hessian-lite version #3423 [#3513](https://github.com/apache/incubator-dubbo/pull/3513)
- [Dubbo-3610]make snakeyaml transitive, should we do this? [#3659](https://github.com/apache/incubator-dubbo/pull/3659)
### Bugfixes
- cannot register REST service in 2.7 due to the changes in RestProtoco#getContextPath [#3445](https://github.com/apache/incubator-dubbo/issues/3445)
- Conflict between curator client and dubbo [#3574](https://github.com/apache/incubator-dubbo/issues/3574)
- is there a problem in NettyBackedChannelBuffer.setBytes(...)? [#2619](https://github.com/apache/incubator-dubbo/issues/2619)
- [Dubbo - client always reconnect offline provider] Dubbo client bug [#3158](https://github.com/apache/incubator-dubbo/issues/3158)
- fix heartbeat internal [#3579](https://github.com/apache/incubator-dubbo/pull/3579)
- logic issue in RedisRegistry leads to services cannot be discovered. [#3291](https://github.com/apache/incubator-dubbo/pull/3291)
- Multicast demo fails with message "Can't assign requested address" [#2423](https://github.com/apache/incubator-dubbo/issues/2423)
- Fix thrift protocol, use path to locate exporter. [#3331](https://github.com/apache/incubator-dubbo/pull/3331)
- cannot use override to modify provider's configuration when hessian protocol is used [#900](https://github.com/apache/incubator-dubbo/issues/900)
- Condition is not properly used ? [#1917](https://github.com/apache/incubator-dubbo/issues/1917)
- connectionMonitor in RestProtocol seems not work [#3237](https://github.com/apache/incubator-dubbo/issues/3237)
- fail to parse config text with white space [#3367](https://github.com/apache/incubator-dubbo/issues/3367)
- @Reference check=false doesn't take effect [#195](https://github.com/apache/incubator-dubbo/issues/195)
- [Issue] SpringStatusChecker execute errors on non-XML Spring configuration [#3615](https://github.com/apache/incubator-dubbo/issues/3615)
- monitor's cluster config is set to failsafe and set to failsafe only [#274](https://github.com/apache/incubator-dubbo/issues/274)
- A question for ReferenceConfigCache. [#1293](https://github.com/apache/incubator-dubbo/issues/1293)
- referenceconfig#destroy never invoke unregister [#3294](https://github.com/apache/incubator-dubbo/issues/3294)
- Fix when qos is disable,log will print every time [#3397](https://github.com/apache/incubator-dubbo/pull/3397)
- service group is not supported in generic direct invocation [#3555](https://github.com/apache/incubator-dubbo/issues/3555)
- setOnreturn doesn't take effect in async generic invocation [#208](https://github.com/apache/incubator-dubbo/issues/208)
- Fix timeout filter not work in async way [#3174](https://github.com/apache/incubator-dubbo/pull/3174)
- java.lang.NumberFormatException: For input string: "" [#3069](https://github.com/apache/incubator-dubbo/issues/3069)
- NPE occurred when the configuration was deleted [#3533](https://github.com/apache/incubator-dubbo/issues/3533)
- NPE when package of interface is empty [#3556](https://github.com/apache/incubator-dubbo/issues/3556)
- NPE when exporting rest service using a given path. [#3477](https://github.com/apache/incubator-dubbo/issues/3477)
- NullPointerException happened when using SpringContainer.getContext() [#3476](https://github.com/apache/incubator-dubbo/issues/3476)
- Why does not tomcat throw an exception when `server.start` failed with a socket binding error. [#3236](https://github.com/apache/incubator-dubbo/issues/3236)
- No such extension org.apache.dubbo.metadata.store.MetadataReportFactory by name redis [#3514](https://github.com/apache/incubator-dubbo/issues/3514)
- dubbo 2.7.1-SNAPSHOT NoClassDefFoundError when use springboot [#3426](https://github.com/apache/incubator-dubbo/issues/3426)
- NPE occurs when use @Reference in junit in spring boot application [#3429](https://github.com/apache/incubator-dubbo/issues/3429)
- When refer the same service with more than one @References(with different configs) on consumer side, only one take effect [#1306](https://github.com/apache/incubator-dubbo/issues/1306)
- consumer always catch java.lang.reflect.UndeclaredThrowableException for the exception thrown from provider [#3386](https://github.com/apache/incubator-dubbo/issues/3386)
- dubbo2.7.0 com.alibaba.com.caucho.hessian.io.HessianProtocolException: 'com.alibaba.dubbo.common.URL' could not be instantiated [#3342](https://github.com/apache/incubator-dubbo/issues/3342)
- Close Resources Properly [#3473](https://github.com/apache/incubator-dubbo/issues/3473)
- SPI entires dup by 3 times. [#2842](https://github.com/apache/incubator-dubbo/issues/2842)
- provider gets wrong interface name from attachment when use generic invocation in 2.6.3 [#2981](https://github.com/apache/incubator-dubbo/issues/2981)
- HashedWheelTimer's queue gets full [#3449](https://github.com/apache/incubator-dubbo/issues/3449)
- Modify MetadataReportRetry ThreadName [#3550](https://github.com/apache/incubator-dubbo/pull/3550)
- Keep interface key in the URL in simplify mode when it's different from path. [#3478](https://github.com/apache/incubator-dubbo/issues/3478)
- nc is not stable in dubbo's bootstrap script [#936](https://github.com/apache/incubator-dubbo/issues/936)
## 2.7.0
Requirements: **Java 8+** required
@ -64,6 +145,32 @@ We have always keep compatibility in mind during the whole process of 2.7.0. We
5. Configuration
## 2.6.6
Enhancement / New feature
* tag route. #3065
* Use Netty4 as default Netty version. #3029
* upporting Java 8 Date/Time type when serializing with Kryo #3519
* supoort config telnet #3511
* add annotation driven in MethodConfig and ArgumentConfig #2603
* add nacos-registry module #3296
* add `protocol` attribute in `@Rerefence` #3555
*support the hierarchical interface in @Service #3251
* change the default behavior in `@EnableDubboConfig.multiple()` #3193
* inline source code of `spring-context-support` #3192
* Simplify externalized configuration of Dubbo Protocol name #3189
BugFix
* update hessian-lite to 2.3.5, fix unnecessary class load #3538
* Fix unregister when client destroyedreferenceconfig#destroy) #3502
* SPI entires dup by 3 times #3315
* fix Consumer throws RpcException after RegistryDirectory notify in high QPS #2016
* fix NPE in @Reference when using Junit to test dubbo service #3429
* fix consuer always catch java.lang.reflect.UndeclaredThrowableException for any exception throws in provider #3386
* fix the priority of `DubboConfigConfigurationSelector ` #2897
* fix `@Rerefence#parameters()` not work #2301
## 2.6.5

View File

@ -42,21 +42,9 @@ There's a [README](https://github.com/apache/incubator-dubbo-samples/tree/master
```xml
<properties>
<dubbo.version>2.7.0</dubbo.version>
<dubbo.version>2.7.1</dubbo.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-bom</artifactId>
<version>${dubbo.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.dubbo</groupId>
@ -64,20 +52,9 @@ There's a [README](https://github.com/apache/incubator-dubbo-samples/tree/master
<version>${dubbo.version}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<version>${dubbo.version}</version>
</dependency>
</dependencies>
```

View File

@ -19,11 +19,11 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-parent</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>dubbo</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
<packaging>jar</packaging>
<name>dubbo-all</name>
<description>The all in one project of dubbo</description>

View File

@ -6,12 +6,12 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-parent</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-bom</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
<packaging>pom</packaging>
<name>dubbo-bom</name>

View File

@ -19,7 +19,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-parent</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-cluster</artifactId>
<packaging>jar</packaging>

View File

@ -20,7 +20,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-parent</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-common</artifactId>
<packaging>jar</packaging>

View File

@ -20,7 +20,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-parent</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-compatible</artifactId>
<packaging>jar</packaging>

View File

@ -19,7 +19,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-config</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-config-api</artifactId>
<packaging>jar</packaging>

View File

@ -1,132 +1,132 @@
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-config</artifactId>
<version>2.7.1-SNAPSHOT</version>
</parent>
<artifactId>dubbo-config-spring</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>The spring config module of dubbo project</description>
<properties>
<skip_maven_deploy>false</skip_maven_deploy>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-config-api</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-default</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-monitor-default</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-dubbo</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-rmi</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-injvm</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-remoting-netty4</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-serialization-hessian2</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-config</artifactId>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-config-spring</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>The spring config module of dubbo project</description>
<properties>
<skip_maven_deploy>false</skip_maven_deploy>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-config-api</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-default</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-monitor-default</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-dubbo</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-rmi</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-injvm</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-remoting-netty4</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-serialization-hessian2</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,142 @@
/*
* 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.config.spring.beans.factory.annotation;
import org.apache.dubbo.common.Constants;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.apache.dubbo.registry.Registry;
import org.springframework.core.env.Environment;
import static org.apache.dubbo.common.Constants.CONSUMERS_CATEGORY;
import static org.apache.dubbo.common.Constants.DEFAULT_PROTOCOL;
import static org.apache.dubbo.common.Constants.PROVIDERS_CATEGORY;
import static org.apache.dubbo.config.spring.util.AnnotationUtils.resolveInterfaceName;
import static org.springframework.util.StringUtils.arrayToCommaDelimitedString;
import static org.springframework.util.StringUtils.hasText;
/**
* The Bean Name Builder for the annotations {@link Service} and {@link Reference}
* <p>
* The naming rule is consistent with the the implementation {@link Registry} that is based on the service-name aware
* infrastructure, e.g Spring Cloud, Cloud Native and so on.
* <p>
* The pattern of bean name : ${category}:${protocol}:${serviceInterface}:${version}:${group}.
* <p>
* ${version} and ${group} are optional.
*
* @since 2.6.6
*/
class AnnotationBeanNameBuilder {
private static final String SEPARATOR = ":";
// Required properties
private final String category;
private final String protocol;
private final String interfaceClassName;
// Optional properties
private String version;
private String group;
private Environment environment;
private AnnotationBeanNameBuilder(String category, String protocol, String interfaceClassName) {
this.category = category;
this.protocol = protocol;
this.interfaceClassName = interfaceClassName;
}
private AnnotationBeanNameBuilder(Service service, Class<?> interfaceClass) {
this(PROVIDERS_CATEGORY, resolveProtocol(service.protocol()), resolveInterfaceName(service, interfaceClass));
this.group(service.group());
this.version(service.version());
}
private AnnotationBeanNameBuilder(Reference reference, Class<?> interfaceClass) {
this(CONSUMERS_CATEGORY, resolveProtocol(reference.protocol()), resolveInterfaceName(reference, interfaceClass));
this.group(reference.group());
this.version(reference.version());
}
public static AnnotationBeanNameBuilder create(Service service, Class<?> interfaceClass) {
return new AnnotationBeanNameBuilder(service, interfaceClass);
}
public static AnnotationBeanNameBuilder create(Reference reference, Class<?> interfaceClass) {
return new AnnotationBeanNameBuilder(reference, interfaceClass);
}
private static void append(StringBuilder builder, String value) {
if (hasText(value)) {
builder.append(SEPARATOR).append(value);
}
}
public AnnotationBeanNameBuilder group(String group) {
this.group = group;
return this;
}
public AnnotationBeanNameBuilder version(String version) {
this.version = version;
return this;
}
public AnnotationBeanNameBuilder environment(Environment environment) {
this.environment = environment;
return this;
}
/**
* Resolve the protocol
*
* @param protocols one or more protocols
* @return if <code>protocols</code> == <code>null</code>, it will return
* {@link Constants#DEFAULT_PROTOCOL "dubbo"} as the default protocol
* @see Constants#DEFAULT_PROTOCOL
*/
private static String resolveProtocol(String... protocols) {
String protocol = arrayToCommaDelimitedString(protocols);
return hasText(protocol) ? protocol : DEFAULT_PROTOCOL;
}
/**
* Build bean name while resolve the placeholders if possible.
*
* @return pattern : ${category}:${protocol}:${serviceInterface}:${version}:${group}
*/
public String build() {
// Append the required properties
StringBuilder beanNameBuilder = new StringBuilder(category);
append(beanNameBuilder, protocol);
append(beanNameBuilder, interfaceClassName);
// Append the optional properties
append(beanNameBuilder, version);
append(beanNameBuilder, group);
String beanName = beanNameBuilder.toString();
// Resolve placeholders
return environment != null ? environment.resolvePlaceholders(beanName) : beanName;
}
}

View File

@ -20,6 +20,7 @@ import org.apache.dubbo.common.utils.Assert;
import org.apache.dubbo.config.AbstractConfig;
import org.apache.dubbo.config.spring.context.annotation.DubboConfigBindingRegistrar;
import org.apache.dubbo.config.spring.context.annotation.EnableDubboConfigBinding;
import org.apache.dubbo.config.spring.context.config.DubboConfigBeanCustomizer;
import org.apache.dubbo.config.spring.context.properties.DefaultDubboConfigBinder;
import org.apache.dubbo.config.spring.context.properties.DubboConfigBinder;
@ -30,8 +31,16 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.core.env.Environment;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import static org.springframework.beans.factory.BeanFactoryUtils.beansOfTypeIncludingAncestors;
/**
* Dubbo Config Binding {@link BeanPostProcessor}
*
@ -62,6 +71,8 @@ public class DubboConfigBindingBeanPostProcessor implements BeanPostProcessor, A
private boolean ignoreInvalidFields = true;
private List<DubboConfigBeanCustomizer> configBeanCustomizers = Collections.emptyList();
/**
* @param prefix the prefix of Configuration Properties
* @param beanName the binding Bean Name
@ -80,18 +91,34 @@ public class DubboConfigBindingBeanPostProcessor implements BeanPostProcessor, A
AbstractConfig dubboConfig = (AbstractConfig) bean;
dubboConfigBinder.bind(prefix, dubboConfig);
bind(prefix, dubboConfig);
customize(beanName, dubboConfig);
if (log.isInfoEnabled()) {
log.info("The properties of bean [name : " + beanName + "] have been binding by prefix of " +
"configuration properties : " + prefix);
}
}
return bean;
}
private void bind(String prefix, AbstractConfig dubboConfig) {
dubboConfigBinder.bind(prefix, dubboConfig);
if (log.isInfoEnabled()) {
log.info("The properties of bean [name : " + beanName + "] have been binding by prefix of " +
"configuration properties : " + prefix);
}
}
private void customize(String beanName, AbstractConfig dubboConfig) {
for (DubboConfigBeanCustomizer customizer : configBeanCustomizers) {
customizer.customize(beanName, dubboConfig);
}
}
public boolean isIgnoreUnknownFields() {
return ignoreUnknownFields;
}
@ -129,6 +156,14 @@ public class DubboConfigBindingBeanPostProcessor implements BeanPostProcessor, A
@Override
public void afterPropertiesSet() throws Exception {
initDubboConfigBinder();
initConfigBeanCustomizers();
}
private void initDubboConfigBinder() {
if (dubboConfigBinder == null) {
try {
dubboConfigBinder = applicationContext.getBean(DubboConfigBinder.class);
@ -146,6 +181,16 @@ public class DubboConfigBindingBeanPostProcessor implements BeanPostProcessor, A
}
private void initConfigBeanCustomizers() {
Collection<DubboConfigBeanCustomizer> configBeanCustomizers =
beansOfTypeIncludingAncestors(applicationContext, DubboConfigBeanCustomizer.class).values();
this.configBeanCustomizers = new ArrayList<DubboConfigBeanCustomizer>(configBeanCustomizers);
AnnotationAwareOrderComparator.sort(this.configBeanCustomizers);
}
/**
* Create {@link DubboConfigBinder} instance.
*
@ -158,4 +203,4 @@ public class DubboConfigBindingBeanPostProcessor implements BeanPostProcessor, A
return defaultDubboConfigBinder;
}
}
}

View File

@ -32,6 +32,7 @@ import org.springframework.context.event.ContextRefreshedEvent;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Collection;
@ -155,7 +156,18 @@ public class ReferenceAnnotationBeanPostProcessor extends AnnotationInjectedBean
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(bean, args);
Object result = null;
try {
if (bean == null) { // If the bean is not initialized, invoke init()
// issue: https://github.com/apache/incubator-dubbo/issues/3429
init();
}
result = method.invoke(bean, args);
} catch (InvocationTargetException e) {
// re-throws the actual Exception.
throw e.getTargetException();
}
return result;
}
private void init() {
@ -176,7 +188,9 @@ public class ReferenceAnnotationBeanPostProcessor extends AnnotationInjectedBean
private String buildReferencedBeanName(Reference reference, Class<?> injectedType) {
ServiceBeanNameBuilder builder = ServiceBeanNameBuilder.create(reference, injectedType, getEnvironment());
AnnotationBeanNameBuilder builder = AnnotationBeanNameBuilder.create(reference, injectedType);
builder.environment(getEnvironment());
return getEnvironment().resolvePlaceholders(builder.build());
}
@ -249,4 +263,4 @@ public class ReferenceAnnotationBeanPostProcessor extends AnnotationInjectedBean
this.injectedFieldReferenceBeanCache.clear();
this.injectedMethodReferenceBeanCache.clear();
}
}
}

View File

@ -18,7 +18,6 @@ package org.apache.dubbo.config.spring.beans.factory.annotation;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.config.MethodConfig;
import org.apache.dubbo.config.annotation.Service;
import org.apache.dubbo.config.spring.ServiceBean;
import org.apache.dubbo.config.spring.context.annotation.DubboClassPathBeanDefinitionScanner;
@ -290,8 +289,9 @@ public class ServiceAnnotationBeanPostProcessor implements BeanDefinitionRegistr
*/
private String generateServiceBeanName(Service service, Class<?> interfaceClass, String annotatedServiceBeanName) {
ServiceBeanNameBuilder builder = ServiceBeanNameBuilder.create(service, interfaceClass, environment);
AnnotationBeanNameBuilder builder = AnnotationBeanNameBuilder.create(service, interfaceClass);
builder.environment(environment);
return builder.build();
@ -316,8 +316,9 @@ public class ServiceAnnotationBeanPostProcessor implements BeanDefinitionRegistr
}
if (interfaceClass == null) {
Class<?>[] allInterfaces = annotatedServiceBeanClass.getInterfaces();
// Find all interfaces from the annotated class
// To resolve an issue : https://github.com/apache/incubator-dubbo/issues/3251
Class<?>[] allInterfaces = ClassUtils.getAllInterfacesForClass(annotatedServiceBeanClass);
if (allInterfaces.length > 0) {
interfaceClass = allInterfaces[0];
@ -435,11 +436,6 @@ public class ServiceAnnotationBeanPostProcessor implements BeanDefinitionRegistr
builder.addPropertyValue("protocols", protocolRuntimeBeanReferences);
}
List<MethodConfig> methodConfigs = MethodConfig.constructMethodConfig(service.methods());
if (!methodConfigs.isEmpty()) {
builder.addPropertyValue("methods", methodConfigs);
}
return builder.getBeanDefinition();
}
@ -490,4 +486,4 @@ public class ServiceAnnotationBeanPostProcessor implements BeanDefinitionRegistr
this.classLoader = classLoader;
}
}
}

View File

@ -1,113 +0,0 @@
/*
* 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.config.spring.beans.factory.annotation;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.apache.dubbo.config.spring.ReferenceBean;
import org.apache.dubbo.config.spring.ServiceBean;
import org.springframework.core.env.Environment;
import org.springframework.util.StringUtils;
import static org.apache.dubbo.config.spring.util.AnnotationUtils.resolveInterfaceName;
/**
* Dubbo {@link Service @Service} Bean Builder
*
* @see Service
* @see Reference
* @see ServiceBean
* @see ReferenceBean
* @since 2.6.5
*/
class ServiceBeanNameBuilder {
private static final String SEPARATOR = ":";
private final String interfaceClassName;
private final Environment environment;
// Optional
private String version;
private String group;
private ServiceBeanNameBuilder(String interfaceClassName, Environment environment) {
this.interfaceClassName = interfaceClassName;
this.environment = environment;
}
private ServiceBeanNameBuilder(Class<?> interfaceClass, Environment environment) {
this(interfaceClass.getName(), environment);
}
private ServiceBeanNameBuilder(Service service, Class<?> interfaceClass, Environment environment) {
this(resolveInterfaceName(service, interfaceClass), environment);
this.group(service.group());
this.version(service.version());
}
private ServiceBeanNameBuilder(Reference reference, Class<?> interfaceClass, Environment environment) {
this(resolveInterfaceName(reference, interfaceClass), environment);
this.group(reference.group());
this.version(reference.version());
}
public static ServiceBeanNameBuilder create(Class<?> interfaceClass, Environment environment) {
return new ServiceBeanNameBuilder(interfaceClass, environment);
}
public static ServiceBeanNameBuilder create(Service service, Class<?> interfaceClass, Environment environment) {
return new ServiceBeanNameBuilder(service, interfaceClass, environment);
}
public static ServiceBeanNameBuilder create(Reference reference, Class<?> interfaceClass, Environment environment) {
return new ServiceBeanNameBuilder(reference, interfaceClass, environment);
}
private static void append(StringBuilder builder, String value) {
if (StringUtils.hasText(value)) {
builder.append(SEPARATOR).append(value);
}
}
public ServiceBeanNameBuilder group(String group) {
this.group = group;
return this;
}
public ServiceBeanNameBuilder version(String version) {
this.version = version;
return this;
}
public String build() {
StringBuilder beanNameBuilder = new StringBuilder("ServiceBean");
// Required
append(beanNameBuilder, interfaceClassName);
// Optional
append(beanNameBuilder, version);
append(beanNameBuilder, group);
// Build
String rawBeanName = beanNameBuilder.toString();
// Resolve placeholders
return environment.resolvePlaceholders(rawBeanName);
}
}

View File

@ -18,6 +18,7 @@ package org.apache.dubbo.config.spring.context.annotation;
import org.apache.dubbo.config.AbstractConfig;
import org.apache.dubbo.config.spring.beans.factory.annotation.DubboConfigBindingBeanPostProcessor;
import org.apache.dubbo.config.spring.context.config.NamePropertyDefaultValueDubboConfigBeanCustomizer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -41,6 +42,8 @@ import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import static org.apache.dubbo.config.spring.context.config.NamePropertyDefaultValueDubboConfigBeanCustomizer.BEAN_NAME;
import static org.apache.dubbo.config.spring.util.BeanRegistrar.registerInfrastructureBean;
import static org.apache.dubbo.config.spring.util.PropertySourcesUtils.getSubProperties;
import static org.apache.dubbo.config.spring.util.PropertySourcesUtils.normalizePrefix;
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.rootBeanDefinition;
@ -107,6 +110,8 @@ public class DubboConfigBindingRegistrar implements ImportBeanDefinitionRegistra
}
registerDubboConfigBeanCustomizers(registry);
}
private void registerDubboConfigBean(String beanName, Class<? extends AbstractConfig> configClass,
@ -149,6 +154,10 @@ public class DubboConfigBindingRegistrar implements ImportBeanDefinitionRegistra
}
private void registerDubboConfigBeanCustomizers(BeanDefinitionRegistry registry) {
registerInfrastructureBean(registry, BEAN_NAME, NamePropertyDefaultValueDubboConfigBeanCustomizer.class);
}
@Override
public void setEnvironment(Environment environment) {
@ -193,4 +202,4 @@ public class DubboConfigBindingRegistrar implements ImportBeanDefinitionRegistra
}
}
}

View File

@ -44,10 +44,11 @@ public class DubboConfigConfigurationRegistrar implements ImportBeanDefinitionRe
boolean multiple = attributes.getBoolean("multiple");
if (multiple) {
// Single Config Bindings
registerBeans(registry, DubboConfigConfiguration.Single.class);
if (multiple) { // Since 2.6.6 https://github.com/apache/incubator-dubbo/issues/3193
registerBeans(registry, DubboConfigConfiguration.Multiple.class);
} else {
registerBeans(registry, DubboConfigConfiguration.Single.class);
}
}

View File

@ -76,6 +76,6 @@ public @interface EnableDubbo {
* @see EnableDubboConfig#multiple()
*/
@AliasFor(annotation = EnableDubboConfig.class, attribute = "multiple")
boolean multipleConfig() default false;
boolean multipleConfig() default true;
}

View File

@ -59,7 +59,7 @@ import java.lang.annotation.Target;
*
* @see EnableDubboConfigBinding
* @see DubboConfigConfiguration
* @see DubboConfigConfigurationSelector
* @see DubboConfigConfigurationRegistrar
* @since 2.5.8
*/
@Target({ElementType.TYPE})
@ -75,6 +75,6 @@ public @interface EnableDubboConfig {
* @return the default value is <code>false</code>
* @revised 2.5.9
*/
boolean multiple() default false;
boolean multiple() default true;
}

View File

@ -0,0 +1,47 @@
/*
* 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.config.spring.context.config;
import org.apache.dubbo.config.AbstractConfig;
import org.apache.dubbo.config.spring.beans.factory.annotation.DubboConfigBindingBeanPostProcessor;
import org.apache.dubbo.config.spring.context.properties.DubboConfigBinder;
import org.springframework.context.ApplicationContext;
import org.springframework.core.Ordered;
/**
* The Bean customizer for {@link AbstractConfig Dubbo Config}. Generally, The subclass will be registered as a Spring
* Bean that is used to {@link #customize(String, AbstractConfig) customize} {@link AbstractConfig Dubbo Config} bean
* after {@link DubboConfigBinder#bind(String, AbstractConfig) its binding}.
* <p>
* If There are multiple {@link DubboConfigBeanCustomizer} beans in the Spring {@link ApplicationContext context}, they
* are executed orderly, thus the subclass should be aware to implement the {@link #getOrder()} method.
*
* @see DubboConfigBinder#bind(String, AbstractConfig)
* @see DubboConfigBindingBeanPostProcessor
* @since 2.6.6
*/
public interface DubboConfigBeanCustomizer extends Ordered {
/**
* Customize {@link AbstractConfig Dubbo Config Bean}
*
* @param beanName the name of {@link AbstractConfig Dubbo Config Bean}
* @param dubboConfigBean the instance of {@link AbstractConfig Dubbo Config Bean}
*/
void customize(String beanName, AbstractConfig dubboConfigBean);
}

View File

@ -0,0 +1,83 @@
/*
* 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.config.spring.context.config;
import org.apache.dubbo.config.AbstractConfig;
import org.springframework.util.ReflectionUtils;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.Arrays;
import static org.apache.dubbo.config.spring.util.ObjectUtils.of;
import static org.springframework.beans.BeanUtils.getPropertyDescriptor;
/**
* {@link DubboConfigBeanCustomizer} for the default value for the "name" property that will be taken bean name
* if absent.
*
* @since 2.6.6
*/
public class NamePropertyDefaultValueDubboConfigBeanCustomizer implements DubboConfigBeanCustomizer {
/**
* The bean name of {@link NamePropertyDefaultValueDubboConfigBeanCustomizer}
*
* @since 2.7.1
*/
public static final String BEAN_NAME = "namePropertyDefaultValueDubboConfigBeanCustomizer";
/**
* The name of property that is "name" maybe is absent in target class
*/
private static final String PROPERTY_NAME = "name";
@Override
public void customize(String beanName, AbstractConfig dubboConfigBean) {
PropertyDescriptor propertyDescriptor = getPropertyDescriptor(dubboConfigBean.getClass(), PROPERTY_NAME);
if (propertyDescriptor != null) { // "name" property is present
Method getNameMethod = propertyDescriptor.getReadMethod();
if (getNameMethod == null) { // if "getName" method is absent
return;
}
Object propertyValue = ReflectionUtils.invokeMethod(getNameMethod, dubboConfigBean);
if (propertyValue != null) { // If The return value of "getName" method is not null
return;
}
Method setNameMethod = propertyDescriptor.getWriteMethod();
if (setNameMethod != null && getNameMethod != null) { // "setName" and "getName" methods are present
if (Arrays.equals(of(String.class), setNameMethod.getParameterTypes())) { // the param type is String
// set bean name to the value of the "name" property
ReflectionUtils.invokeMethod(setNameMethod, dubboConfigBean, beanName);
}
}
}
}
@Override
public int getOrder() {
return HIGHEST_PRECEDENCE;
}
}

View File

@ -1,94 +1,101 @@
/*
* 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.config.spring.status;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.status.Status;
import org.apache.dubbo.common.status.StatusChecker;
import org.apache.dubbo.config.spring.extension.SpringExtensionFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.Lifecycle;
import java.lang.reflect.Method;
/**
* SpringStatusChecker
*/
@Activate
public class SpringStatusChecker implements StatusChecker {
private static final Logger logger = LoggerFactory.getLogger(SpringStatusChecker.class);
@Override
public Status check() {
ApplicationContext context = null;
for (ApplicationContext c : SpringExtensionFactory.getContexts()) {
if (c != null) {
context = c;
break;
}
}
if (context == null) {
return new Status(Status.Level.UNKNOWN);
}
Status.Level level = Status.Level.OK;
if (context instanceof Lifecycle) {
if (((Lifecycle) context).isRunning()) {
level = Status.Level.OK;
} else {
level = Status.Level.ERROR;
}
} else {
level = Status.Level.UNKNOWN;
}
StringBuilder buf = new StringBuilder();
try {
Class<?> cls = context.getClass();
Method method = null;
while (cls != null && method == null) {
try {
method = cls.getDeclaredMethod("getConfigLocations", new Class<?>[0]);
} catch (NoSuchMethodException t) {
cls = cls.getSuperclass();
}
}
if (method != null) {
if (!method.isAccessible()) {
method.setAccessible(true);
}
String[] configs = (String[]) method.invoke(context, new Object[0]);
if (configs != null && configs.length > 0) {
for (String config : configs) {
if (buf.length() > 0) {
buf.append(",");
}
buf.append(config);
}
}
}
} catch (Throwable t) {
logger.warn(t.getMessage(), t);
}
return new Status(level, buf.toString());
}
}
/*
* 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.config.spring.status;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.status.Status;
import org.apache.dubbo.common.status.StatusChecker;
import org.apache.dubbo.config.spring.extension.SpringExtensionFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.Lifecycle;
import org.springframework.web.context.support.GenericWebApplicationContext;
import java.lang.reflect.Method;
/**
* SpringStatusChecker
*/
@Activate
public class SpringStatusChecker implements StatusChecker {
private static final Logger logger = LoggerFactory.getLogger(SpringStatusChecker.class);
@Override
public Status check() {
ApplicationContext context = null;
for (ApplicationContext c : SpringExtensionFactory.getContexts()) {
// [Issue] SpringStatusChecker execute errors on non-XML Spring configuration
// issue : https://github.com/apache/incubator-dubbo/issues/3615
if(c instanceof GenericWebApplicationContext) { // ignore GenericXmlApplicationContext
continue;
}
if (c != null) {
context = c;
break;
}
}
if (context == null) {
return new Status(Status.Level.UNKNOWN);
}
Status.Level level = Status.Level.OK;
if (context instanceof Lifecycle) {
if (((Lifecycle) context).isRunning()) {
level = Status.Level.OK;
} else {
level = Status.Level.ERROR;
}
} else {
level = Status.Level.UNKNOWN;
}
StringBuilder buf = new StringBuilder();
try {
Class<?> cls = context.getClass();
Method method = null;
while (cls != null && method == null) {
try {
method = cls.getDeclaredMethod("getConfigLocations", new Class<?>[0]);
} catch (NoSuchMethodException t) {
cls = cls.getSuperclass();
}
}
if (method != null) {
if (!method.isAccessible()) {
method.setAccessible(true);
}
String[] configs = (String[]) method.invoke(context, new Object[0]);
if (configs != null && configs.length > 0) {
for (String config : configs) {
if (buf.length() > 0) {
buf.append(",");
}
buf.append(config);
}
}
}
} catch (Throwable t) {
logger.warn(t.getMessage(), t);
}
return new Status(level, buf.toString());
}
}

View File

@ -16,29 +16,31 @@
*/
package org.apache.dubbo.config.spring.beans.factory.annotation;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.apache.dubbo.config.spring.api.DemoService;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.mock.env.MockEnvironment;
import org.springframework.util.ReflectionUtils;
import static org.apache.dubbo.config.spring.beans.factory.annotation.AnnotationBeanNameBuilderTest.GROUP;
import static org.apache.dubbo.config.spring.beans.factory.annotation.AnnotationBeanNameBuilderTest.VERSION;
/**
* {@link ServiceBeanNameBuilder} Test
* {@link AnnotationBeanNameBuilder} Test
*
* @see ServiceBeanNameBuilder
* @since 2.6.5
* @see AnnotationBeanNameBuilder
* @since 2.6.6
*/
@Service(interfaceClass = DemoService.class, group = ServiceBeanNameBuilderTest.GROUP, version = ServiceBeanNameBuilderTest.VERSION,
@Service(interfaceClass = DemoService.class, group = GROUP, version = VERSION,
application = "application", module = "module", registry = {"1", "2", "3"})
public class ServiceBeanNameBuilderTest {
public class AnnotationBeanNameBuilderTest {
@Reference(interfaceClass = DemoService.class, group = "DUBBO", version = "1.0.0",
@Reference(interfaceClass = DemoService.class, group = "DUBBO", version = "${dubbo.version}",
application = "application", module = "module", registry = {"1", "2", "3"})
static final Class<?> INTERFACE_CLASS = DemoService.class;
@ -46,30 +48,36 @@ public class ServiceBeanNameBuilderTest {
static final String VERSION = "1.0.0";
static final String BEAN_NAME = "ServiceBean:org.apache.dubbo.config.spring.api.DemoService:1.0.0:DUBBO";
private MockEnvironment environment;
private MockEnvironment environment = new MockEnvironment();
@Test
public void testRequiredAttributes() {
ServiceBeanNameBuilder builder = ServiceBeanNameBuilder.create(INTERFACE_CLASS, environment);
Assertions.assertEquals("ServiceBean:org.apache.dubbo.config.spring.api.DemoService", builder.build());
@Before
public void prepare() {
environment = new MockEnvironment();
environment.setProperty("dubbo.version", "1.0.0");
}
@Test
public void testServiceAnnotation() {
Service service = AnnotationUtils.getAnnotation(ServiceBeanNameBuilderTest.class, Service.class);
ServiceBeanNameBuilder builder = ServiceBeanNameBuilder.create(service, INTERFACE_CLASS, environment);
Assertions.assertEquals(BEAN_NAME,
Service service = AnnotationUtils.getAnnotation(AnnotationBeanNameBuilderTest.class, Service.class);
AnnotationBeanNameBuilder builder = AnnotationBeanNameBuilder.create(service, INTERFACE_CLASS);
Assert.assertEquals("providers:dubbo:org.apache.dubbo.config.spring.api.DemoService:1.0.0:DUBBO",
builder.build());
builder.environment(environment);
Assert.assertEquals("providers:dubbo:org.apache.dubbo.config.spring.api.DemoService:1.0.0:DUBBO",
builder.build());
}
@Test
public void testReferenceAnnotation() {
Reference reference = AnnotationUtils.getAnnotation(ReflectionUtils.findField(ServiceBeanNameBuilderTest.class, "INTERFACE_CLASS"), Reference.class);
ServiceBeanNameBuilder builder = ServiceBeanNameBuilder.create(reference, INTERFACE_CLASS, environment);
Assertions.assertEquals(BEAN_NAME,
Reference reference = AnnotationUtils.getAnnotation(ReflectionUtils.findField(AnnotationBeanNameBuilderTest.class, "INTERFACE_CLASS"), Reference.class);
AnnotationBeanNameBuilder builder = AnnotationBeanNameBuilder.create(reference, INTERFACE_CLASS);
Assert.assertEquals("consumers:dubbo:org.apache.dubbo.config.spring.api.DemoService:${dubbo.version}:DUBBO",
builder.build());
builder.environment(environment);
Assert.assertEquals("consumers:dubbo:org.apache.dubbo.config.spring.api.DemoService:1.0.0:DUBBO",
builder.build());
}
}
}

View File

@ -96,7 +96,7 @@ public class AnnotationPropertyValuesAdapterTest {
Assert.assertEquals("dubbo://localhost:12345", referenceBean.getUrl());
Assert.assertEquals("client", referenceBean.getClient());
Assert.assertEquals(true, referenceBean.isGeneric());
Assert.assertEquals(true, referenceBean.isInjvm());
Assert.assertNull(referenceBean.isInjvm());
Assert.assertEquals(false, referenceBean.isCheck());
Assert.assertEquals(true, referenceBean.isInit());
Assert.assertEquals(true, referenceBean.getLazy());

View File

@ -17,50 +17,56 @@
package org.apache.dubbo.config.spring.beans.factory.annotation;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.spring.context.config.NamePropertyDefaultValueDubboConfigBeanCustomizer;
import org.apache.dubbo.config.spring.context.properties.DefaultDubboConfigBinder;
import org.apache.dubbo.config.spring.context.properties.DubboConfigBinder;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.rootBeanDefinition;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
/**
* {@link DubboConfigBindingBeanPostProcessor}
*/
@PropertySource({"classpath:/META-INF/config.properties"})
@Configuration
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {
DefaultDubboConfigBinder.class,
NamePropertyDefaultValueDubboConfigBeanCustomizer.class,
DubboConfigBindingBeanPostProcessorTest.class
})
@TestPropertySource(properties = {
"dubbo.application.id = dubbo-demo-application",
"dubbo.application.owner = mercyblitz",
"dubbo.application.organization = Apache",
})
public class DubboConfigBindingBeanPostProcessorTest {
@Bean("applicationBean")
@Bean("dubbo-demo-application")
public ApplicationConfig applicationConfig() {
return new ApplicationConfig();
}
@Bean
public DubboConfigBinder dubboConfigBinder() {
return new DefaultDubboConfigBinder();
public DubboConfigBindingBeanPostProcessor bindingBeanPostProcessor() {
return new DubboConfigBindingBeanPostProcessor("dubbo.application", "dubbo-demo-application");
}
@Autowired
private ApplicationContext applicationContext;
@Test
public void test() {
final AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.register(getClass());
Class<?> processorClass = DubboConfigBindingBeanPostProcessor.class;
applicationContext.registerBeanDefinition("DubboConfigBindingBeanPostProcessor", rootBeanDefinition(processorClass).addConstructorArgValue("dubbo.application").addConstructorArgValue("applicationBean").getBeanDefinition());
applicationContext.refresh();
ApplicationConfig applicationConfig = applicationContext.getBean(ApplicationConfig.class);
Assertions.assertEquals("dubbo-demo-application", applicationConfig.getName());
Assert.assertEquals("dubbo-demo-application", applicationConfig.getName());
Assert.assertEquals("mercyblitz", applicationConfig.getOwner());
Assert.assertEquals("Apache", applicationConfig.getOrganization());
}
}
}

View File

@ -81,7 +81,7 @@ public class ReferenceBeanBuilderTest {
Assert.assertEquals("dubbo://localhost:12345", referenceBean.getUrl());
Assert.assertEquals("client", referenceBean.getClient());
Assert.assertEquals(true, referenceBean.isGeneric());
Assert.assertEquals(true, referenceBean.isInjvm());
Assert.assertNull(referenceBean.isInjvm());
Assert.assertEquals(false, referenceBean.isCheck());
Assert.assertEquals(null, referenceBean.isInit());
Assert.assertEquals(true, referenceBean.getLazy());

View File

@ -26,7 +26,6 @@ import org.apache.dubbo.config.RegistryConfig;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.PropertySource;
@ -95,15 +94,15 @@ public class EnableDubboConfigTest {
}
@EnableDubboConfig(multiple = true)
@EnableDubboConfig
@PropertySource("META-INF/config.properties")
private static class TestMultipleConfig {
}
@EnableDubboConfig
@EnableDubboConfig(multiple = false)
@PropertySource("META-INF/config.properties")
private static class TestConfig {
}
}
}

View File

@ -45,11 +45,6 @@ public class DemoServiceImpl implements DemoService {
@Override
public Box getBox() {
return new Box() {
@Override
public String getName() {
return "MyBox";
}
};
throw new UnsupportedOperationException("For Purposes!");
}
}

View File

@ -25,11 +25,14 @@ import org.apache.dubbo.config.ProviderConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.spring.context.annotation.EnableDubboConfig;
import org.junit.Assert;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.PropertySource;
import java.util.Map;
/**
* {@link EnableDubboConfig} Test
*
@ -93,16 +96,24 @@ public class EnableDubboConfigTest {
ApplicationConfig applicationBean3 = context.getBean("applicationBean3", ApplicationConfig.class);
Assertions.assertEquals("dubbo-demo-application3", applicationBean3.getName());
}
Map<String, ProtocolConfig> protocolConfigs = context.getBeansOfType(ProtocolConfig.class);
@EnableDubboConfig(multiple = true)
@PropertySource("META-INF/config.properties")
private static class TestMultipleConfig {
for (Map.Entry<String, ProtocolConfig> entry : protocolConfigs.entrySet()) {
String beanName = entry.getKey();
ProtocolConfig protocol = entry.getValue();
Assert.assertEquals(beanName, protocol.getName());
}
}
@EnableDubboConfig
@PropertySource("META-INF/config.properties")
private static class TestMultipleConfig {
}
@EnableDubboConfig(multiple = false)
@PropertySource("META-INF/config.properties")
private static class TestConfig {
}

View File

@ -20,14 +20,15 @@ import org.apache.dubbo.common.status.Status;
import org.apache.dubbo.config.spring.ServiceBean;
import org.apache.dubbo.config.spring.extension.SpringExtensionFactory;
import org.junit.Assert;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.springframework.context.ApplicationContext;
import org.springframework.context.Lifecycle;
import org.springframework.web.context.support.GenericWebApplicationContext;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
@ -90,4 +91,14 @@ public class SpringStatusCheckerTest {
interface ApplicationLifeCycle extends Lifecycle, ApplicationContext {
String[] getConfigLocations();
}
@Test
public void testGenericWebApplicationContext() {
SpringExtensionFactory.clearContexts();
GenericWebApplicationContext context = new GenericWebApplicationContext();
SpringExtensionFactory.addApplicationContext(context);
SpringStatusChecker checker = new SpringStatusChecker();
Status status = checker.check();
Assert.assertEquals(Status.Level.UNKNOWN, status.getLevel());
}
}

View File

@ -14,9 +14,13 @@ dubbo.module.name = dubbo-demo-module
dubbo.registry.address = zookeeper://192.168.99.100:32770
## protocol
dubbo.protocol.id = dubbo
dubbo.protocol.name = dubbo
dubbo.protocol.port = 20880
dubbo.protocols.rest.port=8080
dubbo.protocols.thrift.port=9090
## monitor
dubbo.monitor.address = zookeeper://127.0.0.1:32770

View File

@ -19,7 +19,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-parent</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-config</artifactId>
<packaging>pom</packaging>

View File

@ -19,7 +19,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-configcenter</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-configcenter-api</artifactId>
<packaging>jar</packaging>

View File

@ -19,7 +19,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-configcenter</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-configcenter-apollo</artifactId>
<packaging>jar</packaging>

View File

@ -16,13 +16,11 @@
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dubbo-configcenter</artifactId>
<groupId>org.apache.dubbo</groupId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -23,6 +23,7 @@ import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.NamedThreadFactory;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.configcenter.ConfigChangeEvent;
import org.apache.dubbo.configcenter.ConfigChangeType;
import org.apache.dubbo.configcenter.ConfigurationListener;
import org.apache.dubbo.configcenter.DynamicConfiguration;
@ -40,6 +41,7 @@ import java.util.concurrent.ExecutorService;
import static java.util.concurrent.Executors.newCachedThreadPool;
import static org.apache.dubbo.common.Constants.CONFIG_NAMESPACE_KEY;
import static org.apache.dubbo.common.Constants.PATH_SEPARATOR;
import static org.apache.dubbo.configcenter.ConfigChangeType.ADDED;
/**
* config center implementation for consul
@ -104,11 +106,23 @@ public class ConsulDynamicConfiguration implements DynamicConfiguration {
@Override
public Object getInternalProperty(String key) {
logger.info("get config from: " + key);
Long currentIndex = consulIndexes.computeIfAbsent(key, k -> -1L);
Response<GetValue> response = client.getKVValue(key, new QueryParams(watchTimeout, currentIndex));
GetValue value = response.getValue();
consulIndexes.put(key, response.getConsulIndex());
return value != null ? value.getDecodedValue() : null;
Response<GetValue> response = getValue(key);
if (response != null) {
GetValue value = response.getValue();
consulIndexes.put(key, response.getConsulIndex());
return value != null ? value.getDecodedValue() : null;
}
return null;
}
private Response<GetValue> getValue(String key) {
try {
Long currentIndex = consulIndexes.computeIfAbsent(key, k -> -1L);
return client.getKVValue(key, new QueryParams(watchTimeout, currentIndex));
} catch (Throwable t) {
logger.warn("fail to get value for key: " + key);
}
return null;
}
private int buildWatchTimeout(URL url) {
@ -119,6 +133,7 @@ public class ConsulDynamicConfiguration implements DynamicConfiguration {
private String key;
private Set<ConfigurationListener> listeners;
private boolean running = true;
private boolean existing = false;
public ConsulKVWatcher(String key) {
this.key = convertKey(key);
@ -129,19 +144,45 @@ public class ConsulDynamicConfiguration implements DynamicConfiguration {
public void run() {
while (running) {
Long lastIndex = consulIndexes.computeIfAbsent(key, k -> -1L);
Response<GetValue> response = client.getKVValue(key, new QueryParams(watchTimeout, lastIndex));
Response<GetValue> response = getValue(key);
if (response == null) {
try {
Thread.sleep(watchTimeout);
} catch (InterruptedException e) {
// ignore
}
continue;
}
GetValue getValue = response.getValue();
Long currentIndex = response.getConsulIndex();
if (currentIndex == null || currentIndex <= lastIndex) {
continue;
}
consulIndexes.put(key, currentIndex);
String value = response.getValue().getDecodedValue();
logger.info("notify change for key: " + key + ", the value is: " + value);
ConfigChangeEvent event = new ConfigChangeEvent(key, value);
for (ConfigurationListener listener : listeners) {
listener.process(event);
ConfigChangeEvent event = null;
if (getValue != null) {
String value = getValue.getDecodedValue();
if (existing) {
logger.info("notify change for key: " + key + ", the changed value is: " + value);
event = new ConfigChangeEvent(key, value);
} else {
logger.info("notify change for key: " + key + ", the added value is: " + value);
event = new ConfigChangeEvent(key, value, ADDED);
}
} else {
if (existing) {
logger.info("notify change for key: " + key + ", the value is deleted");
event = new ConfigChangeEvent(key, null, ConfigChangeType.DELETED);
}
}
existing = getValue != null;
if (event != null) {
for (ConfigurationListener listener : listeners) {
listener.process(event);
}
}
}
}

View File

@ -18,11 +18,11 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent>
<parent>
<artifactId>dubbo-configcenter</artifactId>
<groupId>org.apache.dubbo</groupId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -43,4 +43,4 @@
<version>${project.parent.version}</version>
</dependency>
</dependencies>
</project>
</project>

View File

@ -19,7 +19,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-configcenter</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-configcenter-zookeeper</artifactId>
<packaging>jar</packaging>

View File

@ -19,7 +19,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-parent</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-configcenter</artifactId>
<packaging>pom</packaging>

View File

@ -19,7 +19,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-container</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-container-api</artifactId>
<packaging>jar</packaging>

View File

@ -19,7 +19,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-container</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-container-log4j</artifactId>
<packaging>jar</packaging>

View File

@ -19,7 +19,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-container</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-container-logback</artifactId>
<packaging>jar</packaging>

View File

@ -19,7 +19,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-container</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-container-spring</artifactId>
<packaging>jar</packaging>

View File

@ -19,7 +19,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-parent</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-container</artifactId>
<packaging>pom</packaging>

View File

@ -22,7 +22,7 @@
<parent>
<artifactId>dubbo-demo-annotation</artifactId>
<groupId>org.apache.dubbo</groupId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -22,7 +22,7 @@
<parent>
<artifactId>dubbo-demo-annotation</artifactId>
<groupId>org.apache.dubbo</groupId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -22,7 +22,7 @@
<parent>
<artifactId>dubbo-demo</artifactId>
<groupId>org.apache.dubbo</groupId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>

View File

@ -22,7 +22,7 @@
<parent>
<artifactId>dubbo-demo-api</artifactId>
<groupId>org.apache.dubbo</groupId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -22,7 +22,7 @@
<parent>
<artifactId>dubbo-demo-api</artifactId>
<groupId>org.apache.dubbo</groupId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -22,7 +22,7 @@
<parent>
<artifactId>dubbo-demo</artifactId>
<groupId>org.apache.dubbo</groupId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>

View File

@ -19,7 +19,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-demo</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-demo-interface</artifactId>
<packaging>jar</packaging>

View File

@ -19,7 +19,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-demo-xml</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-demo-xml-consumer</artifactId>
<packaging>jar</packaging>

View File

@ -19,7 +19,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-demo-xml</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-demo-xml-provider</artifactId>
<packaging>jar</packaging>

View File

@ -22,7 +22,7 @@
<parent>
<artifactId>dubbo-demo</artifactId>
<groupId>org.apache.dubbo</groupId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>

View File

@ -19,7 +19,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-parent</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-demo</artifactId>
<packaging>pom</packaging>

View File

@ -16,20 +16,19 @@
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache</groupId>
<artifactId>apache</artifactId>
<version>21</version>
<relativePath></relativePath>
<relativePath />
</parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-bom</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
<packaging>pom</packaging>
<name>dubbo-dependencies-bom</name>

View File

@ -16,21 +16,19 @@
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache</groupId>
<artifactId>apache</artifactId>
<version>21</version>
<relativePath></relativePath>
<relativePath />
</parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
<packaging>pom</packaging>
<dependencyManagement>
@ -38,7 +36,7 @@
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-bom</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@ -77,5 +75,4 @@
</build>
</profile>
</profiles>
</project>

View File

@ -16,13 +16,11 @@
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dubbo-parent</artifactId>
<groupId>org.apache.dubbo</groupId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -19,7 +19,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-parent</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-distribution</artifactId>
<packaging>pom</packaging>
@ -267,7 +267,7 @@
<version>3.1.0</version>
<executions>
<execution>
<id>bin-release</id>
<id>bin</id>
<phase>package</phase>
<goals>
<goal>single</goal>
@ -279,7 +279,7 @@
</configuration>
</execution>
<execution>
<id>source-release</id>
<id>src</id>
<phase>package</phase>
<goals>
<goal>single</goal>

View File

@ -16,12 +16,12 @@
-->
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
<id>bin-release</id>
<id>bin</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>true</includeBaseDirectory>
<baseDirectory>${project.build.finalName}-bin-release</baseDirectory>
<baseDirectory>${project.build.finalName}-bin</baseDirectory>
<fileSets>
<fileSet>
<directory>../</directory>

View File

@ -16,12 +16,12 @@
-->
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
<id>source-release</id>
<id>src</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>true</includeBaseDirectory>
<baseDirectory>${project.build.finalName}-source-release</baseDirectory>
<baseDirectory>${project.build.finalName}-src</baseDirectory>
<fileSets>
<fileSet>

View File

@ -19,7 +19,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-filter</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-filter-cache</artifactId>
<packaging>jar</packaging>

View File

@ -19,7 +19,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-filter</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-filter-validation</artifactId>
<packaging>jar</packaging>

View File

@ -19,7 +19,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-parent</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-filter</artifactId>
<packaging>pom</packaging>

View File

@ -18,7 +18,7 @@
<parent>
<artifactId>dubbo-metadata-report</artifactId>
<groupId>org.apache.dubbo</groupId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -18,7 +18,7 @@
<parent>
<artifactId>dubbo-metadata-report</artifactId>
<groupId>org.apache.dubbo</groupId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -16,13 +16,11 @@
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dubbo-metadata-report</artifactId>
<groupId>org.apache.dubbo</groupId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -18,7 +18,7 @@
<parent>
<artifactId>dubbo-metadata-report</artifactId>
<groupId>org.apache.dubbo</groupId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -18,7 +18,7 @@
<parent>
<artifactId>dubbo-metadata-report</artifactId>
<groupId>org.apache.dubbo</groupId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -18,7 +18,7 @@
<parent>
<artifactId>dubbo-parent</artifactId>
<groupId>org.apache.dubbo</groupId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -19,7 +19,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-monitor</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-monitor-api</artifactId>
<packaging>jar</packaging>

View File

@ -19,7 +19,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-monitor</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-monitor-default</artifactId>
<packaging>jar</packaging>

View File

@ -19,7 +19,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-parent</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-monitor</artifactId>
<packaging>pom</packaging>

View File

@ -18,7 +18,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-plugin</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -18,7 +18,7 @@
<parent>
<artifactId>dubbo-parent</artifactId>
<groupId>org.apache.dubbo</groupId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -19,7 +19,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-registry-api</artifactId>
<packaging>jar</packaging>

View File

@ -16,13 +16,11 @@
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dubbo-registry</artifactId>
<groupId>org.apache.dubbo</groupId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -20,7 +20,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-registry-default</artifactId>
<packaging>jar</packaging>

View File

@ -16,14 +16,12 @@
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>dubbo-registry</artifactId>
<groupId>org.apache.dubbo</groupId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-registry-etcd3</artifactId>

View File

@ -19,7 +19,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-registry-multicast</artifactId>
<packaging>jar</packaging>

View File

@ -0,0 +1,151 @@
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry</artifactId>
<version>2.7.2-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-nacos</artifactId>
<name>${project.artifactId}</name>
<description>The Nacos registry module of Dubbo project</description>
<properties>
<nacos.version>0.9.0</nacos.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-api</artifactId>
<version>${project.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-common</artifactId>
<version>${project.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>${nacos.version}</version>
<optional>true</optional>
</dependency>
<!-- Test Libraries -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-config-api</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-serialization-hessian2</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-config-spring</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-dubbo</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-remoting-netty4</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
<!-- REST support dependencies -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-rest</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-netty4</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson-provider</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxb-provider</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,530 @@
/*
* 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.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.UrlUtils;
import org.apache.dubbo.registry.NotifyListener;
import org.apache.dubbo.registry.Registry;
import org.apache.dubbo.registry.support.FailbackRegistry;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.listener.Event;
import com.alibaba.nacos.api.naming.listener.EventListener;
import com.alibaba.nacos.api.naming.listener.NamingEvent;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.ListView;
import org.apache.commons.lang3.ArrayUtils;
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.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
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 static org.apache.dubbo.common.Constants.ADMIN_PROTOCOL;
import static org.apache.dubbo.common.Constants.CATEGORY_KEY;
import static org.apache.dubbo.common.Constants.CONFIGURATORS_CATEGORY;
import static org.apache.dubbo.common.Constants.CONSUMERS_CATEGORY;
import static org.apache.dubbo.common.Constants.DEFAULT_CATEGORY;
import static org.apache.dubbo.common.Constants.GROUP_KEY;
import static org.apache.dubbo.common.Constants.INTERFACE_KEY;
import static org.apache.dubbo.common.Constants.PROVIDERS_CATEGORY;
import static org.apache.dubbo.common.Constants.ROUTERS_CATEGORY;
import static org.apache.dubbo.common.Constants.VERSION_KEY;
/**
* Nacos {@link Registry}
*
* @see #SERVICE_NAME_SEPARATOR
* @see #PAGINATION_SIZE
* @see #LOOKUP_INTERVAL
* @since 2.6.5
*/
public class NacosRegistry extends FailbackRegistry {
/**
* All supported categories
*/
private static final String[] ALL_SUPPORTED_CATEGORIES = of(
PROVIDERS_CATEGORY,
CONSUMERS_CATEGORY,
ROUTERS_CATEGORY,
CONFIGURATORS_CATEGORY
);
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 static final String WILDCARD = "*";
/**
* The separator for service name
*
* @revert change a constant to be configurable, it's designed for Windows file name that is compatible with old
* Nacos binary release(< 0.6.1)
*/
private static final String SERVICE_NAME_SEPARATOR = System.getProperty("nacos.service.name.separator", ":");
/**
* The pagination size of query for Nacos service names(only for Dubbo-OPS)
*/
private static final int PAGINATION_SIZE = Integer.getInteger("nacos.service.names.pagination.size", 100);
/**
* The interval in second of lookup Nacos service names(only for Dubbo-OPS)
*/
private static final long LOOKUP_INTERVAL = Long.getLong("nacos.service.names.lookup.interval", 30);
/**
* {@link ScheduledExecutorService} lookup Nacos service names(only for Dubbo-OPS)
*/
private volatile ScheduledExecutorService scheduledExecutorService;
private final Logger logger = LoggerFactory.getLogger(getClass());
private final NamingService namingService;
private final ConcurrentMap<String, EventListener> nacosListeners;
public NacosRegistry(URL url, NamingService namingService) {
super(url);
this.namingService = namingService;
this.nacosListeners = new ConcurrentHashMap<String, EventListener>();
}
@Override
public boolean isAvailable() {
return "UP".equals(namingService.getServerStatus());
}
@Override
public List<URL> lookup(final URL url) {
final List<URL> urls = new LinkedList<URL>();
execute(new NamingServiceCallback() {
@Override
public void callback(NamingService namingService) throws NacosException {
List<String> serviceNames = getServiceNames(url, null);
for (String serviceName : serviceNames) {
List<Instance> instances = namingService.getAllInstances(serviceName);
urls.addAll(buildURLs(url, instances));
}
}
});
return urls;
}
@Override
public void doRegister(URL url) {
final String serviceName = getServiceName(url);
final Instance instance = createInstance(url);
execute(new NamingServiceCallback() {
public void callback(NamingService namingService) throws NacosException {
namingService.registerInstance(serviceName, instance);
}
});
}
@Override
public void doUnregister(final URL url) {
execute(new NamingServiceCallback() {
public void callback(NamingService namingService) throws NacosException {
String serviceName = getServiceName(url);
Instance instance = createInstance(url);
namingService.deregisterInstance(serviceName, instance.getIp(), instance.getPort());
}
});
}
@Override
public void doSubscribe(final URL url, final NotifyListener listener) {
List<String> serviceNames = getServiceNames(url, listener);
doSubscribe(url, listener, serviceNames);
}
private void doSubscribe(final URL url, final NotifyListener listener, final List<String> serviceNames) {
execute(new NamingServiceCallback() {
@Override
public void callback(NamingService namingService) throws NacosException {
for (String serviceName : serviceNames) {
List<Instance> instances = namingService.getAllInstances(serviceName);
notifySubscriber(url, listener, instances);
subscribeEventListener(serviceName, url, listener);
}
}
});
}
@Override
public void doUnsubscribe(URL url, NotifyListener listener) {
if (isAdminProtocol(url)) {
shutdownServiceNamesLookup();
}
}
private void shutdownServiceNamesLookup() {
if (scheduledExecutorService != null) {
scheduledExecutorService.shutdown();
}
}
/**
* Get the service names from the specified {@link URL url}
*
* @param url {@link URL}
* @param listener {@link NotifyListener}
* @return non-null
*/
private List<String> getServiceNames(URL url, NotifyListener listener) {
if (isAdminProtocol(url)) {
scheduleServiceNamesLookup(url, listener);
return getServiceNamesForOps(url);
} else {
return doGetServiceNames(url);
}
}
private boolean isAdminProtocol(URL url) {
return ADMIN_PROTOCOL.equals(url.getProtocol());
}
private void scheduleServiceNamesLookup(final URL url, final NotifyListener listener) {
if (scheduledExecutorService == null) {
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
List<String> serviceNames = getAllServiceNames();
filterData(serviceNames, new NacosDataFilter<String>() {
@Override
public boolean accept(String serviceName) {
boolean accepted = false;
for (String category : ALL_SUPPORTED_CATEGORIES) {
String prefix = category + SERVICE_NAME_SEPARATOR;
if (StringUtils.startsWith(serviceName, prefix)) {
accepted = true;
break;
}
}
return accepted;
}
});
doSubscribe(url, listener, serviceNames);
}
}, LOOKUP_INTERVAL, LOOKUP_INTERVAL, TimeUnit.SECONDS);
}
}
/**
* Get the service names for Dubbo OPS
*
* @param url {@link URL}
* @return non-null
*/
private List<String> getServiceNamesForOps(URL url) {
List<String> serviceNames = getAllServiceNames();
filterServiceNames(serviceNames, url);
return serviceNames;
}
private List<String> getAllServiceNames() {
final List<String> serviceNames = new LinkedList<String>();
execute(new NamingServiceCallback() {
@Override
public void callback(NamingService namingService) throws NacosException {
int pageIndex = 1;
ListView<String> listView = namingService.getServicesOfServer(pageIndex, PAGINATION_SIZE);
// First page data
List<String> firstPageData = listView.getData();
// Append first page into list
serviceNames.addAll(firstPageData);
// the total count
int count = listView.getCount();
// the number of pages
int pageNumbers = count / PAGINATION_SIZE;
int remainder = count % PAGINATION_SIZE;
// remain
if (remainder > 0) {
pageNumbers += 1;
}
// If more than 1 page
while (pageIndex < pageNumbers) {
listView = namingService.getServicesOfServer(++pageIndex, PAGINATION_SIZE);
serviceNames.addAll(listView.getData());
}
}
});
return serviceNames;
}
private void filterServiceNames(List<String> serviceNames, URL url) {
final String[] categories = getCategories(url);
final String targetServiceInterface = url.getServiceInterface();
final String targetVersion = url.getParameter(VERSION_KEY);
final String targetGroup = url.getParameter(GROUP_KEY);
filterData(serviceNames, new NacosDataFilter<String>() {
@Override
public boolean accept(String serviceName) {
// split service name to segments
// (required) segments[0] = category
// (required) segments[1] = serviceInterface
// (required) segments[2] = version
// (optional) segments[3] = group
String[] segments = StringUtils.split(serviceName, SERVICE_NAME_SEPARATOR);
int length = segments.length;
if (length < 3) { // must present 3 segments or more
return false;
}
String category = segments[CATEGORY_INDEX];
if (!ArrayUtils.contains(categories, category)) { // no match category
return false;
}
String serviceInterface = segments[SERVICE_INTERFACE_INDEX];
if (!WILDCARD.equals(targetServiceInterface) &&
!StringUtils.equals(targetServiceInterface, serviceInterface)) { // no match service interface
return false;
}
String version = segments[SERVICE_VERSION_INDEX];
if (!WILDCARD.equals(targetVersion) &&
!StringUtils.equals(targetVersion, version)) { // no match service version
return false;
}
String group = length > 3 ? segments[SERVICE_GROUP_INDEX] : null;
if (group != null && !WILDCARD.equals(targetGroup)
&& !StringUtils.equals(targetGroup, group)) { // no match service group
return false;
}
return true;
}
});
}
private <T> void filterData(Collection<T> collection, NacosDataFilter<T> filter) {
Iterator<T> iterator = collection.iterator();
while (iterator.hasNext()) {
T data = iterator.next();
if (!filter.accept(data)) { // remove if not accept
iterator.remove();
}
}
}
private List<String> doGetServiceNames(URL url) {
String[] categories = getCategories(url);
List<String> serviceNames = new ArrayList<String>(categories.length);
for (String category : categories) {
final String serviceName = getServiceName(url, category);
serviceNames.add(serviceName);
}
return serviceNames;
}
private List<URL> buildURLs(URL consumerURL, Collection<Instance> instances) {
if (instances.isEmpty()) {
return Collections.emptyList();
}
List<URL> urls = new LinkedList<URL>();
for (Instance instance : instances) {
URL url = buildURL(instance);
if (UrlUtils.isMatch(consumerURL, url)) {
urls.add(url);
}
}
return urls;
}
private void subscribeEventListener(String serviceName, final URL url, final NotifyListener listener)
throws NacosException {
if (!nacosListeners.containsKey(serviceName)) {
EventListener eventListener = new EventListener() {
public void onEvent(Event event) {
if (event instanceof NamingEvent) {
NamingEvent e = (NamingEvent) event;
notifySubscriber(url, listener, e.getInstances());
}
}
};
namingService.subscribe(serviceName, eventListener);
nacosListeners.put(serviceName, eventListener);
}
}
/**
* Notify the Healthy {@link Instance instances} to subscriber.
*
* @param url {@link URL}
* @param listener {@link NotifyListener}
* @param instances all {@link Instance instances}
*/
private void notifySubscriber(URL url, NotifyListener listener, Collection<Instance> instances) {
List<Instance> healthyInstances = new LinkedList<Instance>(instances);
// Healthy Instances
filterHealthyInstances(healthyInstances);
List<URL> urls = buildURLs(url, healthyInstances);
NacosRegistry.this.notify(url, listener, urls);
}
/**
* Get the categories from {@link URL}
*
* @param url {@link URL}
* @return non-null array
*/
private String[] getCategories(URL url) {
return Constants.ANY_VALUE.equals(url.getServiceInterface()) ?
ALL_SUPPORTED_CATEGORIES : of(Constants.DEFAULT_CATEGORY);
}
private URL buildURL(Instance instance) {
Map<String, String> metadata = instance.getMetadata();
String protocol = metadata.get(Constants.PROTOCOL_KEY);
String path = metadata.get(Constants.PATH_KEY);
URL url = new URL(protocol,
instance.getIp(),
instance.getPort(),
path,
instance.getMetadata());
return url;
}
private Instance createInstance(URL url) {
// Append default category if absent
String category = url.getParameter(Constants.CATEGORY_KEY, Constants.DEFAULT_CATEGORY);
URL newURL = url.addParameter(Constants.CATEGORY_KEY, category);
newURL = newURL.addParameter(Constants.PROTOCOL_KEY, url.getProtocol());
newURL = newURL.addParameter(Constants.PATH_KEY, url.getPath());
String ip = url.getHost();
int port = url.getPort();
Instance instance = new Instance();
instance.setIp(ip);
instance.setPort(port);
instance.setMetadata(new HashMap<String, String>(newURL.getParameters()));
return instance;
}
private String getServiceName(URL url) {
String category = url.getParameter(CATEGORY_KEY, DEFAULT_CATEGORY);
return getServiceName(url, category);
}
private String getServiceName(URL url, String category) {
StringBuilder serviceNameBuilder = new StringBuilder(category);
appendIfPresent(serviceNameBuilder, url, INTERFACE_KEY);
appendIfPresent(serviceNameBuilder, url, VERSION_KEY);
appendIfPresent(serviceNameBuilder, url, GROUP_KEY);
return serviceNameBuilder.toString();
}
private void appendIfPresent(StringBuilder target, URL url, String parameterName) {
String parameterValue = url.getParameter(parameterName);
if (!StringUtils.isBlank(parameterValue)) {
target.append(SERVICE_NAME_SEPARATOR).append(parameterValue);
}
}
private void execute(NamingServiceCallback callback) {
try {
callback.callback(namingService);
} catch (NacosException e) {
if (logger.isErrorEnabled()) {
logger.error(e.getErrMsg(), e);
}
}
}
private void filterHealthyInstances(Collection<Instance> instances) {
filterData(instances, new NacosDataFilter<Instance>() {
@Override
public boolean accept(Instance data) {
return data.isEnabled();
}
});
}
private static <T> T[] of(T... values) {
return values;
}
/**
* A filter for Nacos data
*
* @since 2.6.5
*/
private interface NacosDataFilter<T> {
/**
* Tests whether or not the specified data should be accepted.
*
* @param data The data to be tested
* @return <code>true</code> if and only if <code>data</code>
* should be accepted
*/
boolean accept(T data);
}
/**
* {@link NamingService} Callback
*
* @since 2.6.5
*/
interface NamingServiceCallback {
/**
* Callback
*
* @param namingService {@link NamingService}
* @throws NacosException
*/
void callback(NamingService namingService) throws NacosException;
}
}

View File

@ -0,0 +1,108 @@
/*
* 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.dubbo.registry.Registry;
import org.apache.dubbo.registry.RegistryFactory;
import org.apache.dubbo.registry.support.AbstractRegistryFactory;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.client.naming.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Properties;
import static com.alibaba.nacos.api.PropertyKeyConst.ACCESS_KEY;
import static com.alibaba.nacos.api.PropertyKeyConst.CLUSTER_NAME;
import static com.alibaba.nacos.api.PropertyKeyConst.ENDPOINT;
import static com.alibaba.nacos.api.PropertyKeyConst.NAMESPACE;
import static com.alibaba.nacos.api.PropertyKeyConst.SECRET_KEY;
import static com.alibaba.nacos.api.PropertyKeyConst.SERVER_ADDR;
import static com.alibaba.nacos.client.naming.utils.UtilAndComs.NACOS_NAMING_LOG_NAME;
import static org.apache.dubbo.common.Constants.BACKUP_KEY;
/**
* Nacos {@link RegistryFactory}
*
* @since 2.6.5
*/
public class NacosRegistryFactory extends AbstractRegistryFactory {
private final Logger logger = LoggerFactory.getLogger(getClass());
protected Registry createRegistry(URL url) {
return new NacosRegistry(url, buildNamingService(url));
}
private NamingService buildNamingService(URL url) {
Properties nacosProperties = buildNacosProperties(url);
NamingService namingService = null;
try {
namingService = NacosFactory.createNamingService(nacosProperties);
} catch (NacosException e) {
if (logger.isErrorEnabled()) {
logger.error(e.getErrMsg(), e);
}
throw new IllegalStateException(e);
}
return namingService;
}
private Properties buildNacosProperties(URL url) {
Properties properties = new Properties();
setServerAddr(url, properties);
setProperties(url, properties);
return properties;
}
private void setServerAddr(URL url, Properties properties) {
StringBuilder serverAddrBuilder =
new StringBuilder(url.getHost()) // Host
.append(":")
.append(url.getPort()); // Port
// Append backup parameter as other servers
String backup = url.getParameter(BACKUP_KEY);
if (backup != null) {
serverAddrBuilder.append(",").append(backup);
}
String serverAddr = serverAddrBuilder.toString();
properties.put(SERVER_ADDR, serverAddr);
}
private void setProperties(URL url, Properties properties) {
putPropertyIfAbsent(url, properties, NAMESPACE);
putPropertyIfAbsent(url, properties, NACOS_NAMING_LOG_NAME);
putPropertyIfAbsent(url, properties, ENDPOINT);
putPropertyIfAbsent(url, properties, NAMESPACE);
putPropertyIfAbsent(url, properties, ACCESS_KEY);
putPropertyIfAbsent(url, properties, SECRET_KEY);
putPropertyIfAbsent(url, properties, CLUSTER_NAME);
}
private void putPropertyIfAbsent(URL url, Properties properties, String propertyName) {
String propertyValue = url.getParameter(propertyName);
if (StringUtils.isNotEmpty(propertyValue)) {
properties.setProperty(propertyName, propertyValue);
}
}
}

View File

@ -0,0 +1 @@
nacos=org.apache.dubbo.registry.nacos.NacosRegistryFactory

View File

@ -0,0 +1,59 @@
/*
* 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.demo.consumer;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.apache.dubbo.demo.service.DemoService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.PropertySource;
import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
/**
* {@link DemoService} consumer demo
*/
@EnableDubbo
@PropertySource(value = "classpath:/consumer-config.properties")
public class DemoServiceConsumerBootstrap {
@Reference(version = "${demo.service.version}")
private DemoService demoService;
@Reference(version = "${demo.service.version}", protocol = "rest")
private DemoService restDemoService;
@PostConstruct
public void init() throws InterruptedException {
for (int j = 0; j < 10; j++) {
System.out.println(demoService.sayName("小马哥mercyblitz"));
System.out.println(restDemoService.sayName("小马哥mercyblitz"));
}
Thread.sleep(TimeUnit.SECONDS.toMillis(5));
}
public static void main(String[] args) throws IOException {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(DemoServiceConsumerBootstrap.class);
context.refresh();
System.in.read();
context.close();
}
}

View File

@ -0,0 +1,42 @@
/*
* 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.demo.consumer;
import org.apache.dubbo.demo.service.DemoService;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
/**
* {@link DemoService} consumer demo XML bootstrap
*/
public class DemoServiceConsumerXmlBootstrap {
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext();
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"));
}
System.in.read();
context.close();
}
}

View File

@ -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.demo.provider;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.apache.dubbo.demo.service.DemoService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.PropertySource;
import java.io.IOException;
/**
* {@link DemoService} provider demo
*/
@EnableDubbo(scanBasePackages = "org.apache.dubbo.demo.service")
@PropertySource(value = "classpath:/provider-config.properties")
public class DemoServiceProviderBootstrap {
public static void main(String[] args) throws IOException {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(DemoServiceProviderBootstrap.class);
context.refresh();
System.out.println("DemoService provider is starting...");
System.in.read();
}
}

View File

@ -0,0 +1,37 @@
/*
* 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.demo.provider;
import org.apache.dubbo.demo.service.DemoService;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
/**
* {@link DemoService} provider demo XML bootstrap
*/
public class DemoServiceProviderXmlBootstrap {
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext();
context.setConfigLocation("/META-INF/spring/dubbo-provider-context.xml");
context.refresh();
System.out.println("DemoService provider (XML) is starting...");
System.in.read();
}
}

View File

@ -0,0 +1,46 @@
/*
* 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.demo.service;
import org.apache.dubbo.config.annotation.Service;
import org.apache.dubbo.rpc.RpcContext;
import org.springframework.beans.factory.annotation.Value;
/**
* Default {@link DemoService}
*
* @since 2.6.5
*/
@Service(version = "${demo.service.version}")
public class DefaultService implements DemoService {
@Value("${demo.service.name}")
private String serviceName;
public String sayName(String name) {
RpcContext rpcContext = RpcContext.getContext();
return String.format("Service [name :%s , protocol: %s , port : %d] %s(\"%s\") : Hello,%s",
serviceName,
rpcContext.getUrl().getProtocol(),
rpcContext.getLocalPort(),
rpcContext.getMethodName(),
name,
name);
}
}

View File

@ -0,0 +1,34 @@
/*
* 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.demo.service;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
/**
* DemoService
*
* @since 2.6.5
*/
@Path("/demo-service")
public interface DemoService {
@GET
String sayName(@QueryParam("name") String name);
}

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<dubbo:application name="dubbo-consumer-xml-demo"/>
<!-- Nacos Registry -->
<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"/>
</beans>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<dubbo:application name="dubbo-provider-xml-demo"/>
<!-- Nacos Registry -->
<dubbo:registry address="nacos://127.0.0.1:8848"/>
<!-- 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"/>
<bean id="demoService" class="org.apache.dubbo.demo.service.DefaultService"/>
</beans>

View File

@ -0,0 +1,6 @@
## Dubbo Application info
dubbo.application.name=dubbo-consumer-demo
## Nacos registry address
dubbo.registry.address=nacos://127.0.0.1:8848
# @Reference version
demo.service.version=1.0.0

View File

@ -0,0 +1,14 @@
## Dubbo Application info
dubbo.application.name=dubbo-provider-demo
## Nacos registry address
dubbo.registry.protocol=nacos
dubbo.registry.address=127.0.0.1:8848
## Exports multiple protocols
### Dubbo Protocol using random port
dubbo.protocols.dubbo.port=-1
### REST protocol
dubbo.protocols.rest.port=9090
dubbo.protocols.rest.server=netty
# Provider @Service info
demo.service.version=1.0.0
demo.service.name=demoService

View File

@ -19,7 +19,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-registry-redis</artifactId>
<packaging>jar</packaging>

View File

@ -19,7 +19,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-registry-zookeeper</artifactId>
<packaging>jar</packaging>

View File

@ -19,7 +19,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-parent</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-registry</artifactId>
<packaging>pom</packaging>
@ -36,5 +36,6 @@
<module>dubbo-registry-redis</module>
<module>dubbo-registry-consul</module>
<module>dubbo-registry-etcd3</module>
<module>dubbo-registry-nacos</module>
</modules>
</project>

View File

@ -19,7 +19,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-remoting</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-remoting-api</artifactId>
<packaging>jar</packaging>

View File

@ -16,14 +16,12 @@
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>dubbo-remoting</artifactId>
<groupId>org.apache.dubbo</groupId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-remoting-etcd3</artifactId>
<packaging>jar</packaging>

View File

@ -550,7 +550,7 @@ public class JEtcdClientWrapper {
try {
cancelKeepAlive = true;
if (globalLeaseId != 0) {
if (globalLeaseId > 0) {
revokeLease(this.globalLeaseId);
}
} catch (Exception e) {

View File

@ -19,7 +19,7 @@
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-remoting</artifactId>
<version>2.7.1-SNAPSHOT</version>
<version>2.7.2-SNAPSHOT</version>
</parent>
<artifactId>dubbo-remoting-grizzly</artifactId>
<packaging>jar</packaging>

Some files were not shown because too many files have changed in this diff Show More