Compare commits
109 Commits
3.2
...
dubbo-3.3.
| Author | SHA1 | Date |
|---|---|---|
|
|
0c9d5e2f73 | |
|
|
bcd5caf7df | |
|
|
0b2b9f735a | |
|
|
a0e7ebc735 | |
|
|
7246fad6b5 | |
|
|
c96a8f3719 | |
|
|
660d5a2ecd | |
|
|
4f32e0aba3 | |
|
|
fb0911de97 | |
|
|
0fd51b1ca0 | |
|
|
54da4da033 | |
|
|
cff9bfd1d2 | |
|
|
9eb49e24c3 | |
|
|
0f61286a78 | |
|
|
abb2d3834d | |
|
|
4b5c186076 | |
|
|
3ed2dacbef | |
|
|
99ba6e3037 | |
|
|
8009c72030 | |
|
|
dad3b070cd | |
|
|
fd04ef711b | |
|
|
d596eeb151 | |
|
|
fe2af7e354 | |
|
|
cfd0be3a3a | |
|
|
7e6a32ba68 | |
|
|
059b75c533 | |
|
|
36a80e4db7 | |
|
|
bf3d4f4ca3 | |
|
|
8e55dae8f9 | |
|
|
f91246ab09 | |
|
|
186ec674bf | |
|
|
98d6a853a9 | |
|
|
679ce4496c | |
|
|
4e9a0a41fc | |
|
|
7a4ec6c525 | |
|
|
ae150c01e5 | |
|
|
56de12127b | |
|
|
629bee3987 | |
|
|
5ae875d951 | |
|
|
04f3fe7d2b | |
|
|
8bfdf1e38c | |
|
|
059fdf2613 | |
|
|
7c971ca1bd | |
|
|
b18eeb7077 | |
|
|
6c5a876f31 | |
|
|
ce65317207 | |
|
|
046898bbc8 | |
|
|
29d9c070d4 | |
|
|
8fefd95a98 | |
|
|
2973426b2a | |
|
|
70605f4dd0 | |
|
|
d1719c5358 | |
|
|
0e17f4f168 | |
|
|
72e5d20ce9 | |
|
|
0db8605974 | |
|
|
80d496c5b1 | |
|
|
093fb7c208 | |
|
|
f78b4f5dea | |
|
|
1f8a0fa5ec | |
|
|
f2ec217f54 | |
|
|
c7d411c3cb | |
|
|
8bb17b85f2 | |
|
|
4b62513dff | |
|
|
9bbf7625a8 | |
|
|
0d4e8304bc | |
|
|
33a8063309 | |
|
|
d4c2852caf | |
|
|
48cc5b24de | |
|
|
37f150263a | |
|
|
95207b9079 | |
|
|
da8d0cd994 | |
|
|
27e6838c3b | |
|
|
1c65617fb1 | |
|
|
cf2a63580e | |
|
|
d6776e4008 | |
|
|
b14201f393 | |
|
|
c96a06eba1 | |
|
|
1e59ab524a | |
|
|
fd14e7b76f | |
|
|
642f741dba | |
|
|
85bc6ea472 | |
|
|
391d3cdb35 | |
|
|
2031a4c531 | |
|
|
e642e72ce8 | |
|
|
4604b8074a | |
|
|
30daba2d74 | |
|
|
1f39543632 | |
|
|
71046bdd6f | |
|
|
ae4899a462 | |
|
|
7661cab6f5 | |
|
|
d798e7c3be | |
|
|
34eb252178 | |
|
|
59758f4b58 | |
|
|
52e4e4e301 | |
|
|
71cc51bf69 | |
|
|
a80ad7f505 | |
|
|
9f0e1589a5 | |
|
|
471f44b52d | |
|
|
992abd2d34 | |
|
|
9d9df82194 | |
|
|
6c8f79c889 | |
|
|
2997fa6a2e | |
|
|
13558a8e6a | |
|
|
59832d45d4 | |
|
|
fe55491d4a | |
|
|
b23bae38cc | |
|
|
0b6f2e4a8d | |
|
|
414785c05b | |
|
|
52611099ab |
43
.artifacts
43
.artifacts
|
|
@ -19,8 +19,8 @@
|
|||
dubbo
|
||||
dubbo-auth
|
||||
dubbo-apache-release
|
||||
dubbo-all-shaded
|
||||
dubbo-bom
|
||||
dubbo-build-tools
|
||||
dubbo-cluster
|
||||
dubbo-common
|
||||
dubbo-compatible
|
||||
|
|
@ -28,7 +28,9 @@ dubbo-compiler
|
|||
dubbo-config
|
||||
dubbo-config-api
|
||||
dubbo-config-spring
|
||||
dubbo-config-spring6
|
||||
dubbo-configcenter
|
||||
dubbo-configcenter-file
|
||||
dubbo-configcenter-apollo
|
||||
dubbo-configcenter-nacos
|
||||
dubbo-configcenter-zookeeper
|
||||
|
|
@ -49,6 +51,7 @@ dubbo-kubernetes
|
|||
dubbo-maven-plugin
|
||||
dubbo-metadata
|
||||
dubbo-metadata-api
|
||||
dubbo-metadata-rest
|
||||
dubbo-metadata-definition-protobuf
|
||||
dubbo-metadata-processor
|
||||
dubbo-metadata-report-nacos
|
||||
|
|
@ -61,11 +64,13 @@ dubbo-metrics-metadata
|
|||
dubbo-metrics-prometheus
|
||||
dubbo-metrics-registry
|
||||
dubbo-metrics-config-center
|
||||
dubbo-metrics-netty
|
||||
dubbo-metrics-event
|
||||
dubbo-monitor
|
||||
dubbo-monitor-api
|
||||
dubbo-monitor-common
|
||||
dubbo-monitor-default
|
||||
dubbo-native
|
||||
dubbo-native-plugin
|
||||
dubbo-parent
|
||||
dubbo-plugin
|
||||
dubbo-qos
|
||||
|
|
@ -80,8 +85,10 @@ dubbo-registry-zookeeper
|
|||
dubbo-remoting
|
||||
dubbo-remoting-api
|
||||
dubbo-remoting-http
|
||||
dubbo-remoting-http12
|
||||
dubbo-remoting-netty
|
||||
dubbo-remoting-netty4
|
||||
dubbo-remoting-zookeeper-api
|
||||
dubbo-remoting-zookeeper
|
||||
dubbo-remoting-zookeeper-curator5
|
||||
dubbo-rpc
|
||||
|
|
@ -102,16 +109,36 @@ dubbo-spring-boot-actuator-compatible
|
|||
dubbo-spring-boot-autoconfigure
|
||||
dubbo-spring-boot-autoconfigure-compatible
|
||||
dubbo-spring-boot-compatible
|
||||
dubbo-spring-boot-observability-starters
|
||||
dubbo-spring-boot-observability-autoconfigure
|
||||
dubbo-spring-boot-tracing-brave-zipkin-starter
|
||||
dubbo-spring-boot-tracing-otel-zipkin-starter
|
||||
dubbo-spring-boot-tracing-otel-otlp-starter
|
||||
dubbo-spring-boot-observability-starter
|
||||
dubbo-observability-spring-boot-starters
|
||||
dubbo-observability-spring-boot-autoconfigure
|
||||
dubbo-tracing-brave-zipkin-spring-boot-starter
|
||||
dubbo-tracing-otel-zipkin-spring-boot-starter
|
||||
dubbo-tracing-otel-otlp-spring-boot-starter
|
||||
dubbo-observability-spring-boot-starter
|
||||
dubbo-spring-boot-starter
|
||||
dubbo-spring-boot-starters
|
||||
dubbo-spring-boot-interceptor
|
||||
dubbo-nacos-spring-boot-starter
|
||||
dubbo-zookeeper-spring-boot-starter
|
||||
dubbo-zookeeper-curator5-spring-boot-starter
|
||||
dubbo-sentinel-spring-boot-starter
|
||||
dubbo-seata-spring-boot-starter
|
||||
dubbo-spring-security
|
||||
dubbo-tracing
|
||||
dubbo-xds
|
||||
dubbo-plugin-cluster-mergeable
|
||||
dubbo-plugin-mock
|
||||
dubbo-plugin-router-script
|
||||
dubbo-plugin-router-mesh
|
||||
dubbo-plugin-router-condition
|
||||
dubbo-plugin-router-tag
|
||||
dubbo-plugin-loadbalance-adaptive
|
||||
dubbo-plugin-access-log
|
||||
dubbo-plugin-tps
|
||||
dubbo-plugin-token
|
||||
dubbo-plugin-generic-invoke
|
||||
dubbo-plugin-context
|
||||
dubbo-plugin-classloader-filter
|
||||
dubbo-plugin-proxy-bytebuddy
|
||||
dubbo-plugin-qos-trace
|
||||
dubbo-plugin-loom
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ jobs:
|
|||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'zulu'
|
||||
java-version: 8
|
||||
java-version: 17
|
||||
- uses: actions/cache@v3
|
||||
name: "Cache local Maven repository"
|
||||
with:
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ jobs:
|
|||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'zulu'
|
||||
java-version: 8
|
||||
java-version: 17
|
||||
- uses: actions/cache@v3
|
||||
name: "Cache local Maven repository"
|
||||
with:
|
||||
|
|
@ -132,7 +132,7 @@ jobs:
|
|||
fail-fast: false
|
||||
matrix:
|
||||
os: [ ubuntu-latest, windows-latest ]
|
||||
jdk: [ 8, 11, 17, 19 ]
|
||||
jdk: [ 17, 19 ]
|
||||
env:
|
||||
DISABLE_FILE_SYSTEM_TEST: true
|
||||
steps:
|
||||
|
|
@ -169,7 +169,7 @@ jobs:
|
|||
fail-fast: false
|
||||
matrix:
|
||||
os: [ ubuntu-latest, windows-latest ]
|
||||
jdk: [ 8, 11, 17, 19 ]
|
||||
jdk: [ 17, 19 ]
|
||||
env:
|
||||
DISABLE_FILE_SYSTEM_TEST: true
|
||||
DUBBO_DEFAULT_SERIALIZATION: fastjson2
|
||||
|
|
|
|||
|
|
@ -96,11 +96,13 @@ header:
|
|||
- 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/MatchingGroupIdFilter.java'
|
||||
- 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/RunArguments.java'
|
||||
- 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/RunProcess.java'
|
||||
- 'dubbo-native/src/main/java/org/apache/dubbo/aot/generate/BasicJsonWriter.java'
|
||||
- 'dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ExecutableMode.java'
|
||||
- 'dubbo-native/src/main/java/org/apache/dubbo/aot/generate/MemberCategory.java'
|
||||
- 'dubbo-plugin/dubbo-native/src/main/java/org/apache/dubbo/aot/generate/BasicJsonWriter.java'
|
||||
- 'dubbo-plugin/dubbo-native/src/main/java/org/apache/dubbo/aot/api/ExecutableMode.java'
|
||||
- 'dubbo-plugin/dubbo-native/src/main/java/org/apache/dubbo/aot/api/MemberCategory.java'
|
||||
- 'dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/DubboMergingDigest.java'
|
||||
- 'dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/DubboAbstractTDigest.java'
|
||||
- 'dubbo-common/src/main/java/org/apache/dubbo/common/logger/helpers/FormattingTuple.java'
|
||||
- 'dubbo-common/src/main/java/org/apache/dubbo/common/logger/helpers/MessageFormatter.java'
|
||||
|
||||
comment: on-failure
|
||||
|
||||
|
|
@ -199,10 +201,26 @@ dependency:
|
|||
license: Apache-2.0
|
||||
- name: org.sonatype.plexus:plexus-cipher
|
||||
license: Apache-2.0
|
||||
- name: com.alibaba.csp:sentinel-apache-dubbo3-adapter
|
||||
license: Apache-2.0
|
||||
- name: com.alibaba.csp:sentinel-transport-simple-http
|
||||
license: Apache-2.0
|
||||
- name: com.alibaba.csp:sentinel-transport-common
|
||||
license: Apache-2.0
|
||||
- name: com.alibaba.csp:sentinel-datasource-extension
|
||||
license: Apache-2.0
|
||||
- name: com.alibaba.csp:sentinel-core
|
||||
license: Apache-2.0
|
||||
- name: com.google.protobuf:protobuf-java
|
||||
license: BSD 3-clause
|
||||
- name: com.google.protobuf:protobuf-java-util
|
||||
license: BSD 3-clause
|
||||
- name: org.antlr:antlr4
|
||||
license: BSD 3-clause
|
||||
- name: org.antlr:antlr-runtime
|
||||
license: BSD 3-clause
|
||||
- name: org.antlr:ST4
|
||||
license: BSD 3-clause
|
||||
# multi license
|
||||
- name: org.javassist:javassist
|
||||
license: Apache-2.0
|
||||
|
|
|
|||
|
|
@ -1,21 +1,8 @@
|
|||
## What is the purpose of the change
|
||||
## What is the purpose of the change?
|
||||
|
||||
|
||||
|
||||
## Brief changelog
|
||||
|
||||
|
||||
## Verifying this change
|
||||
|
||||
|
||||
<!-- Follow this checklist to help us incorporate your contribution quickly and easily: -->
|
||||
|
||||
## Checklist
|
||||
- [x] Make sure there is a [GitHub_issue](https://github.com/apache/dubbo/issues) field for the change (usually before you start working on it). Trivial changes like typos do not require a GitHub issue. Your pull request should address just this issue, without pulling in other changes - one PR resolves one issue.
|
||||
- [ ] Each commit in the pull request should have a meaningful subject line and body.
|
||||
- [ ] Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
|
||||
- [ ] Check if is necessary to patch to Dubbo 3 if you are work on Dubbo 2.7
|
||||
- [ ] Write necessary unit-test to verify your logic correction, more mock a little better when cross module dependency exist. If the new feature or significant change is committed, please remember to add sample in [dubbo samples](https://github.com/apache/dubbo-samples) project.
|
||||
- [ ] Add some description to [dubbo-website](https://github.com/apache/dubbo-website) project if you are requesting to add a feature.
|
||||
- [ ] GitHub Actions works fine on your own branch.
|
||||
- [ ] If this contribution is large, please follow the [Software Donation Guide](https://github.com/apache/dubbo/wiki/Software-donation-guide).
|
||||
- [x] Make sure there is a [GitHub_issue](https://github.com/apache/dubbo/issues) field for the change.
|
||||
- [x] Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
|
||||
- [x] Write necessary unit-test to verify your logic correction. If the new feature or significant change is committed, please remember to add sample in [dubbo samples](https://github.com/apache/dubbo-samples) project.
|
||||
- [x] Make sure gitHub actions can pass. [Why the workflow is failing and how to fix it?](./CONTRIBUTING.md)
|
||||
|
|
|
|||
255
README.md
255
README.md
|
|
@ -10,236 +10,69 @@
|
|||
[](https://twitter.com/intent/follow?screen_name=ApacheDubbo)
|
||||
[](https://gitter.im/alibaba/dubbo?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
|
||||
Apache Dubbo is a high-performance, Java-based open-source RPC framework. Please visit the [official site](http://dubbo.apache.org) for the quick start guide and documentation, as well as the [wiki](https://github.com/apache/dubbo/wiki) for news, FAQ, and release notes.
|
||||
Apache Dubbo is an easy-to-use Web and RPC framework that provides multiple
|
||||
language implementations(Java, [Go](https://github.com/apache/dubbo-go), [Rust](https://github.com/apache/dubbo-rust), [Node.js](https://github.com/apache/dubbo-js), [Web](https://github.com/apache/dubbo-js)) for communication, service discovery, traffic management,
|
||||
observability, security, tools, and best practices for building enterprise-ready microservices.
|
||||
|
||||
We are now collecting Dubbo user info to help us to improve Dubbo further. Kindly support us by providing your usage information on [issue#9436: Wanted: who's using dubbo](https://github.com/apache/dubbo/issues/9436), thanks :)
|
||||
Visit [the official website](https://dubbo.apache.org/) for more information.
|
||||
|
||||
## Architecture
|
||||
|
||||

|
||||
|
||||
## Features
|
||||
|
||||
* Transparent interface based RPC
|
||||
* Intelligent load balancing
|
||||
* Automatic service registration and discovery
|
||||
* High extensibility
|
||||
* Runtime traffic routing
|
||||
* Visualized service governance
|
||||
* Consumer and provider communicate with each other using RPC protocol like triple, tcp, rest, etc.
|
||||
* Consumers automatically trace provider instances registered in registries(Zookeeper, Nacos) and distribute traffic among them by following traffic strategies.
|
||||
* Rich features for monitoring and managing the cluster with dynamic configuration, metrics, tracing, security, and visualized console.
|
||||
|
||||
## Getting started
|
||||
Follow the instructions below to learn how to:
|
||||
|
||||
The following code snippet comes from [Dubbo Samples](https://github.com/apache/dubbo-samples.git). You may clone the sample project and step into the `dubbo-samples-api` subdirectory before proceeding.
|
||||
### Programming with lightweight RPC API
|
||||
[5 minutes step-by-step guide](https://dubbo.apache.org/zh-cn/overview/quickstart/rpc/java)
|
||||
|
||||
```bash
|
||||
git clone https://github.com/apache/dubbo-samples.git
|
||||
cd dubbo-samples/1-basic/dubbo-samples-api
|
||||
```
|
||||
|
||||
There's a [README](https://github.com/apache/dubbo-samples/blob/389cd612f1ea57ee6e575005b32f195c442c35a2/1-basic/dubbo-samples-api/README.md) file under `dubbo-samples-api` directory. We recommend referencing the samples in that directory by following the below-mentioned instructions:
|
||||
|
||||
### Maven dependency
|
||||
|
||||
```xml
|
||||
<properties>
|
||||
<dubbo.version>3.2.5</dubbo.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo</artifactId>
|
||||
<version>${dubbo.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-dependencies-zookeeper</artifactId>
|
||||
<version>${dubbo.version}</version>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
```
|
||||
|
||||
### Define service interfaces
|
||||
|
||||
```java
|
||||
package org.apache.dubbo.samples.api;
|
||||
|
||||
public interface GreetingsService {
|
||||
String sayHi(String name);
|
||||
}
|
||||
```
|
||||
|
||||
*See [api/GreetingsService.java](https://github.com/apache/dubbo-samples/blob/389cd612f1ea57ee6e575005b32f195c442c35a2/1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/api/GreetingsService.java) on GitHub.*
|
||||
|
||||
### Implement service interface for the provider
|
||||
|
||||
```java
|
||||
package org.apache.dubbo.samples.provider;
|
||||
|
||||
import org.apache.dubbo.samples.api.GreetingsService;
|
||||
|
||||
public class GreetingsServiceImpl implements GreetingsService {
|
||||
@Override
|
||||
public String sayHi(String name) {
|
||||
return "hi, " + name;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
*See [provider/GreetingsServiceImpl.java](https://github.com/apache/dubbo-samples/blob/389cd612f1ea57ee6e575005b32f195c442c35a2/1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/GreetingsServiceImpl.java) on GitHub.*
|
||||
|
||||
### Start service provider
|
||||
|
||||
```java
|
||||
package org.apache.dubbo.samples.provider;
|
||||
Dubbo supports building RPC services with only a few lines of code while depending only on a lightweight SDK (<10MB). The protocol on the wire can be [Triple](https://dubbo.apache.org/zh-cn/overview/reference/protocols/triple/)(fully gRPC compatible and HTTP-friendly), Dubbo2(TCP), REST, or any protocol of your choice.
|
||||
|
||||
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.config.ServiceConfig;
|
||||
import org.apache.dubbo.samples.api.GreetingsService;
|
||||
### Building a microservice application with Spring Boot
|
||||
[5 minutes step-by-step guide](https://dubbo.apache.org/zh-cn/overview/quickstart/microservice)
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
It's highly recommended to start your microservice application with the Spring Boot Starter `dubbo-spring-boot-starter` provided by Dubbo. With only a single dependency and yaml file, and optionally a bunch of other useful spring boot starters, you can enable all of the Dubo features like service discovery, observability, tracing, etc.
|
||||
|
||||
public class Application {
|
||||
private static String zookeeperHost = System.getProperty("zookeeper.address", "127.0.0.1");
|
||||
Next, learn how to [deploy](https://dubbo.apache.org/zh-cn/overview/tasks/deploy/), [monitor](https://dubbo.apache.org/zh-cn/overview/tasks/observability/), and [manage the traffic](https://dubbo.apache.org/zh-cn/overview/tasks/traffic-management/) of your Dubbo application and cluster.
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
ServiceConfig<GreetingsService> service = new ServiceConfig<>();
|
||||
service.setApplication(new ApplicationConfig("first-dubbo-provider"));
|
||||
service.setRegistry(new RegistryConfig("zookeeper://" + zookeeperHost + ":2181"));
|
||||
service.setInterface(GreetingsService.class);
|
||||
service.setRef(new GreetingsServiceImpl());
|
||||
service.export();
|
||||
## More Features
|
||||
Get more details by visiting the links below to get your hands dirty with some well-designed tasks on our website.
|
||||
|
||||
System.out.println("dubbo service started");
|
||||
new CountDownLatch(1).await();
|
||||
}
|
||||
}
|
||||
```
|
||||
* [Launch a Dubbo project](https://dubbo.apache.org/zh-cn/overview/tasks/develop/template/)
|
||||
* [RPC protocols](https://dubbo.apache.org/zh-cn/overview/core-features/protocols/)
|
||||
* [Traffic management](https://dubbo.apache.org/zh-cn/overview/core-features/traffic/)
|
||||
* [Service discovery](https://dubbo.apache.org/zh-cn/overview/core-features/service-discovery/)
|
||||
* [Observability](https://dubbo.apache.org/zh-cn/overview/core-features/observability/)
|
||||
* [Extensibility](https://dubbo.apache.org/zh-cn/overview/core-features/extensibility/)
|
||||
* [Security](https://dubbo.apache.org/zh-cn/overview/core-features/security/)
|
||||
* [Visualized console and control plane](https://dubbo.apache.org/zh-cn/overview/reference/admin/)
|
||||
* [Kubernetes and Service mesh](https://dubbo.apache.org/zh-cn/overview/core-features/service-mesh/)
|
||||
|
||||
*See [provider/Application.java](https://github.com/apache/dubbo-samples/blob/389cd612f1ea57ee6e575005b32f195c442c35a2/1-basic/dubbo-samples-spring-xml/src/main/java/org/apache/dubbo/samples/provider/Application.java) on GitHub.*
|
||||
## Which Dubbo version should I use?
|
||||
| **Dubbo3** | **JDK** | **Dependencies** | **Description** |
|
||||
| --- | --- | --- | --- |
|
||||
| 3.3.0-beta| 1.8 ~ 17 | [dependency list](https://github.com/apache/dubbo/blob/3.3/dubbo-dependencies-bom/pom.xml#L94) | **- Unstable version** <br/> **- Features** <br/> - Triple - gRPC and cURL compatible.<br/> - Rest-style programming support.<br/> - Spring Boot Starters. |
|
||||
| 3.2.5 | 1.8 ~ 17 | [dependency list](https://github.com/apache/dubbo/blob/dubbo-3.2.5/dubbo-dependencies-bom/pom.xml#L94) | **- Stable version (active)** <br/> **- Features** <br/> - Out-of-box metrics and tracing support.<br/> - Threadpool Isolation<br/> - 30% performance<br/> - Native Image|
|
||||
| 3.1.11 | 1.8 ~ 11 | [dependency list](https://github.com/apache/dubbo/blob/dubbo-3.2.11/dubbo-dependencies-bom/pom.xml#L94) | **Stable version (not active)** |
|
||||
|
||||
### Build and run the provider
|
||||
|
||||
```bash
|
||||
mvn clean package
|
||||
mvn -Djava.net.preferIPv4Stack=true -Dexec.mainClass=org.apache.dubbo.samples.provider.Application exec:java
|
||||
```
|
||||
|
||||
### Call remote service in the consumer
|
||||
|
||||
```java
|
||||
package org.apache.dubbo.samples.client;
|
||||
|
||||
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.ReferenceConfig;
|
||||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.samples.api.GreetingsService;
|
||||
|
||||
public class Application {
|
||||
private static String zookeeperHost = System.getProperty("zookeeper.address", "127.0.0.1");
|
||||
|
||||
public static void main(String[] args) {
|
||||
ReferenceConfig<GreetingsService> reference = new ReferenceConfig<>();
|
||||
reference.setApplication(new ApplicationConfig("first-dubbo-consumer"));
|
||||
reference.setRegistry(new RegistryConfig("zookeeper://" + zookeeperHost + ":2181"));
|
||||
reference.setInterface(GreetingsService.class);
|
||||
GreetingsService service = reference.get();
|
||||
String message = service.sayHi("dubbo");
|
||||
System.out.println(message);
|
||||
}
|
||||
}
|
||||
```
|
||||
*See [client/Application.java](https://github.com/apache/dubbo-samples/blob/389cd612f1ea57ee6e575005b32f195c442c35a2/1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/client/Application.java) on GitHub.*
|
||||
|
||||
### Build and run the consumer
|
||||
|
||||
```bash
|
||||
mvn clean package
|
||||
mvn -Djava.net.preferIPv4Stack=true -Dexec.mainClass=org.apache.dubbo.samples.client.Application exec:java
|
||||
```
|
||||
|
||||
The consumer will print out `hi, dubbo` on the screen.
|
||||
|
||||
|
||||
### Next steps
|
||||
|
||||
* [Your first Dubbo application](https://dubbo.apache.org/en/blog/2018/08/07/dubbo-101/) - A 101 tutorial to reveal more details, with the same code above.
|
||||
* [Dubbo user manual](https://dubbo.apache.org/en/overview/what/) - How to use Dubbo and all its features.
|
||||
* [Dubbo developer guide](https://dubbo.apache.org/en/docs3-v2/java-sdk/) - How to involve in Dubbo development.
|
||||
* [Dubbo admin manual](https://dubbo.apache.org/en/docs/v2.7/admin/ops/) - How to admin and manage Dubbo services.
|
||||
|
||||
## Building
|
||||
|
||||
If you want to try out the cutting-edge features, you can build with the following commands. (Java 1.8 is needed to build the master branch)
|
||||
|
||||
```
|
||||
mvn clean install
|
||||
```
|
||||
|
||||
## Recommended Test Environment
|
||||
To avoid intermittent test failures (i.e., flaky tests), it is recommended to have a machine or virtual machine with the following specifications:
|
||||
|
||||
* Minimum of 2CPUs.
|
||||
* Minimum of 2Gb of RAM.
|
||||
|
||||
## Contact
|
||||
|
||||
* Mailing list:
|
||||
* dev list: for dev/user discussion. [subscribe](mailto:dev-subscribe@dubbo.apache.org), [unsubscribe](mailto:dev-unsubscribe@dubbo.apache.org), [archive](https://lists.apache.org/list.html?dev@dubbo.apache.org), [guide](https://github.com/apache/dubbo/wiki/Mailing-list-subscription-guide)
|
||||
|
||||
* Bugs: [Issues](https://github.com/apache/dubbo/issues/new?template=dubbo-issue-report-template.md)
|
||||
* Gitter: [Gitter channel](https://gitter.im/alibaba/dubbo)
|
||||
* Twitter: [@ApacheDubbo](https://twitter.com/ApacheDubbo)
|
||||
| **Dubbo2** | **JDK** | **Dependencies** | **Description** |
|
||||
| --- | --- | --- | --- |
|
||||
| 2.7.23 | 1.8 | [dependency list](https://github.com/apache/dubbo/blob/dubbo-2.7.23/dubbo-dependencies-bom/pom.xml#L92) | EOL |
|
||||
| 2.6.x, 2.5.x | 1.6 ~ 1.7 | | EOL |
|
||||
|
||||
## Contributing
|
||||
See [CONTRIBUTING](https://github.com/apache/dubbo/blob/master/CONTRIBUTING.md) for details on submitting patches and the contribution workflow.
|
||||
|
||||
See [CONTRIBUTING](https://github.com/apache/dubbo/blob/master/CONTRIBUTING.md) for details on submitting patches and the contribution workflow.
|
||||
|
||||
### How can I contribute?
|
||||
|
||||
* Take a look at issues with tags marked [`Good first issue`](https://github.com/apache/dubbo/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) or [`Help wanted`](https://github.com/apache/dubbo/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22).
|
||||
* Join the discussion on the mailing list, subscription [guide](https://github.com/apache/dubbo/wiki/Mailing-list-subscription-guide).
|
||||
* Answer questions on [issues](https://github.com/apache/dubbo/issues).
|
||||
* Fix bugs reported on [issues](https://github.com/apache/dubbo/issues), and send us a pull request.
|
||||
* Review the existing [pull request](https://github.com/apache/dubbo/pulls).
|
||||
* Improve the [website](https://github.com/apache/dubbo-website), typically we need
|
||||
* blog post
|
||||
* translation on documentation
|
||||
* use cases around the integration of Dubbo in enterprise systems.
|
||||
* Improve the [dubbo-admin/dubbo-monitor](https://github.com/apache/dubbo-admin).
|
||||
* Contribute to the projects listed in [ecosystem](https://github.com/dubbo).
|
||||
* Other forms of contribution not explicitly enumerated above.
|
||||
* If you would like to contribute, please send an email to dev@dubbo.apache.org to let us know!
|
||||
|
||||
## Reporting bugs
|
||||
|
||||
Please follow the [template](https://github.com/apache/dubbo/issues/new?template=dubbo-issue-report-template.md) for reporting any issues.
|
||||
|
||||
## Reporting a security vulnerability
|
||||
|
||||
Please report security vulnerabilities to [us](mailto:security@dubbo.apache.org) privately.
|
||||
|
||||
## Dubbo ecosystem
|
||||
|
||||
* [Dubbo Ecosystem Entry](https://github.com/apache?utf8=%E2%9C%93&q=dubbo&type=&language=) - A GitHub group `dubbo` to gather all Dubbo relevant projects not appropriate in [apache](https://github.com/apache) group yet
|
||||
* [Dubbo Website](https://github.com/apache/dubbo-website) - Apache Dubbo official website
|
||||
* [Dubbo Samples](https://github.com/apache/dubbo-samples) - samples for Apache Dubbo
|
||||
* [Dubbo Spring Boot](https://github.com/apache/dubbo-spring-boot-project) - Spring Boot Project for Dubbo
|
||||
* [Dubbo Admin](https://github.com/apache/dubbo-admin) - The reference implementation for Dubbo admin
|
||||
* [Dubbo Awesome](https://github.com/apache/dubbo-awesome) - Dubbo's slides and video links in Meetup
|
||||
|
||||
#### Language
|
||||
|
||||
* [Go](https://github.com/dubbo/dubbo-go) (recommended)
|
||||
* [Node.js](https://github.com/apache/dubbo-js)
|
||||
* [Python](https://github.com/dubbo/py-client-for-apache-dubbo)
|
||||
* [PHP](https://github.com/apache/dubbo-php-framework)
|
||||
* [Erlang](https://github.com/apache/dubbo-erlang)
|
||||
## Contact
|
||||
* WeChat: apachedubbo
|
||||
* DingTalk group: 37290003945
|
||||
* Mailing list: [guide](https://dubbo.apache.org/zh-cn/contact/)
|
||||
* Twitter: [@ApacheDubbo](https://twitter.com/ApacheDubbo)
|
||||
* Security issues: please mail to [us](mailto:security@dubbo.apache.org) privately.
|
||||
|
||||
## License
|
||||
|
||||
Apache Dubbo software is licensed under the Apache License Version 2.0. See the [LICENSE](https://github.com/apache/dubbo/blob/master/LICENSE) file for details.
|
||||
Apache Dubbo is licensed under the Apache License Version 2.0. See the [LICENSE](https://github.com/apache/dubbo/blob/master/LICENSE) file for details.
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ ignore:
|
|||
- "**/dubbo-test/**"
|
||||
- "**/dubbo-compatible/**"
|
||||
- "**/dubbo-native/**"
|
||||
- "**/dubbo-native-plugin/**"
|
||||
- "**/dubbo-common/src/main/java/org/apache/dubbo/common/json/*.java" # internal JSON impl is deprecate, ignore test coverage for them
|
||||
- "**/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/AnnotationBean.java" # Deprecated
|
||||
- "**/dubbo-rpc/dubbo-rpc-thrift/**"
|
||||
|
|
|
|||
|
|
@ -1,30 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-build-tools</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<maven.deploy.skip>true</maven.deploy.skip>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
|
|
@ -86,10 +86,5 @@
|
|||
<version>${project.parent.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-tracing-integration-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -17,10 +17,7 @@
|
|||
package org.apache.dubbo.rpc.cluster;
|
||||
|
||||
import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
|
||||
import org.apache.dubbo.rpc.AdaptiveMetrics;
|
||||
import org.apache.dubbo.rpc.cluster.merger.MergerFactory;
|
||||
import org.apache.dubbo.rpc.cluster.router.RouterSnapshotSwitcher;
|
||||
import org.apache.dubbo.rpc.cluster.router.mesh.route.MeshRuleManager;
|
||||
import org.apache.dubbo.rpc.cluster.support.ClusterUtils;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
|
|
@ -37,14 +34,10 @@ public class ClusterScopeModelInitializer implements ScopeModelInitializer {
|
|||
@Override
|
||||
public void initializeApplicationModel(ApplicationModel applicationModel) {
|
||||
ScopeBeanFactory beanFactory = applicationModel.getBeanFactory();
|
||||
beanFactory.registerBean(MergerFactory.class);
|
||||
beanFactory.registerBean(ClusterUtils.class);
|
||||
beanFactory.registerBean(AdaptiveMetrics.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeModuleModel(ModuleModel moduleModel) {
|
||||
ScopeBeanFactory beanFactory = moduleModel.getBeanFactory();
|
||||
beanFactory.registerBean(MeshRuleManager.class);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
mock=org.apache.dubbo.rpc.cluster.support.wrapper.MockClusterWrapper
|
||||
scope=org.apache.dubbo.rpc.cluster.support.wrapper.ScopeClusterWrapper
|
||||
failover=org.apache.dubbo.rpc.cluster.support.FailoverCluster
|
||||
failfast=org.apache.dubbo.rpc.cluster.support.FailfastCluster
|
||||
|
|
@ -6,6 +5,5 @@ failsafe=org.apache.dubbo.rpc.cluster.support.FailsafeCluster
|
|||
failback=org.apache.dubbo.rpc.cluster.support.FailbackCluster
|
||||
forking=org.apache.dubbo.rpc.cluster.support.ForkingCluster
|
||||
available=org.apache.dubbo.rpc.cluster.support.AvailableCluster
|
||||
mergeable=org.apache.dubbo.rpc.cluster.support.MergeableCluster
|
||||
broadcast=org.apache.dubbo.rpc.cluster.support.BroadcastCluster
|
||||
zone-aware=org.apache.dubbo.rpc.cluster.support.registry.ZoneAwareCluster
|
||||
zone-aware=org.apache.dubbo.rpc.cluster.support.registry.ZoneAwareCluster
|
||||
|
|
|
|||
|
|
@ -3,4 +3,3 @@ roundrobin=org.apache.dubbo.rpc.cluster.loadbalance.RoundRobinLoadBalance
|
|||
leastactive=org.apache.dubbo.rpc.cluster.loadbalance.LeastActiveLoadBalance
|
||||
consistenthash=org.apache.dubbo.rpc.cluster.loadbalance.ConsistentHashLoadBalance
|
||||
shortestresponse=org.apache.dubbo.rpc.cluster.loadbalance.ShortestResponseLoadBalance
|
||||
adaptive=org.apache.dubbo.rpc.cluster.loadbalance.AdaptiveLoadBalance
|
||||
|
|
|
|||
|
|
@ -1,6 +1,2 @@
|
|||
consumercontext=org.apache.dubbo.rpc.cluster.filter.support.ConsumerContextFilter
|
||||
consumer-classloader=org.apache.dubbo.rpc.cluster.filter.support.ConsumerClassLoaderFilter
|
||||
router-snapshot=org.apache.dubbo.rpc.cluster.router.RouterSnapshotFilter
|
||||
observationsender=org.apache.dubbo.rpc.cluster.filter.support.ObservationSenderFilter
|
||||
metricsClusterFilter=org.apache.dubbo.rpc.cluster.filter.support.MetricsClusterFilter
|
||||
metricsConsumerFilter=org.apache.dubbo.rpc.cluster.filter.support.MetricsConsumerFilter
|
||||
|
|
|
|||
|
|
@ -1,253 +1,253 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.rpc.cluster;
|
||||
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.config.configcenter.ConfigChangeType;
|
||||
import org.apache.dubbo.common.config.configcenter.ConfigChangedEvent;
|
||||
import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
|
||||
import org.apache.dubbo.common.url.component.ServiceConfigURL;
|
||||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.RpcContext;
|
||||
import org.apache.dubbo.rpc.RpcInvocation;
|
||||
import org.apache.dubbo.rpc.cluster.filter.DemoService;
|
||||
import org.apache.dubbo.rpc.cluster.router.RouterSnapshotSwitcher;
|
||||
import org.apache.dubbo.rpc.cluster.router.condition.config.AppStateRouter;
|
||||
import org.apache.dubbo.rpc.cluster.router.condition.config.ListenableStateRouter;
|
||||
import org.apache.dubbo.rpc.cluster.router.condition.config.ServiceStateRouter;
|
||||
import org.apache.dubbo.rpc.cluster.router.mesh.route.MeshAppRuleListener;
|
||||
import org.apache.dubbo.rpc.cluster.router.mesh.route.MeshRuleManager;
|
||||
import org.apache.dubbo.rpc.cluster.router.state.BitList;
|
||||
import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.TAG_KEY;
|
||||
import static org.apache.dubbo.rpc.cluster.router.mesh.route.MeshRuleConstants.MESH_RULE_DATA_ID_SUFFIX;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
class RouterChainTest {
|
||||
|
||||
/**
|
||||
* verify the router and state router loaded by default
|
||||
*/
|
||||
@Test
|
||||
void testBuildRouterChain() {
|
||||
RouterChain<DemoService> routerChain = createRouterChanin();
|
||||
Assertions.assertEquals(0, routerChain.getRouters().size());
|
||||
Assertions.assertEquals(7, routerChain.getStateRouters().size());
|
||||
}
|
||||
|
||||
private RouterChain<DemoService> createRouterChanin() {
|
||||
Map<String, String> parameters = new HashMap<>();
|
||||
parameters.put(INTERFACE_KEY, DemoService.class.getName());
|
||||
parameters.put("registry", "zookeeper");
|
||||
URL url = new ServiceConfigURL("dubbo",
|
||||
"127.0.0.1",
|
||||
20881,
|
||||
DemoService.class.getName(),
|
||||
parameters);
|
||||
|
||||
RouterChain<DemoService> routerChain = RouterChain.buildChain(DemoService.class, url);
|
||||
return routerChain;
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRoute() {
|
||||
RouterChain<DemoService> routerChain = createRouterChanin();
|
||||
|
||||
// mockInvoker will be filtered out by MockInvokersSelector
|
||||
Invoker<DemoService> mockInvoker = createMockInvoker();
|
||||
|
||||
// invoker1 will be filtered out by MeshStateRouter
|
||||
Map<String, String> map1 = new HashMap<>();
|
||||
map1.put("env-sign", "yyyyyyy");
|
||||
Invoker<DemoService> invoker1 = createNormalInvoker(map1);
|
||||
|
||||
// invoker2 will be filtered out by TagStateRouter
|
||||
Map<String, String> map2 = new HashMap<>();
|
||||
map2.put("env-sign", "xxx");
|
||||
map2.put("tag1", "hello");
|
||||
Invoker<DemoService> invoker2 = createNormalInvoker(map2);
|
||||
|
||||
// invoker3 will be filtered out by AppStateRouter
|
||||
Map<String, String> map3 = new HashMap<>();
|
||||
map3.put("env-sign", "xxx");
|
||||
map3.put("tag1", "hello");
|
||||
map3.put(TAG_KEY, "TAG_");
|
||||
Invoker<DemoService> invoker3 = createNormalInvoker(map3);
|
||||
|
||||
// invoker4 will be filtered out by ServiceStateRouter
|
||||
Map<String, String> map4 = new HashMap<>();
|
||||
map4.put("env-sign", "xxx");
|
||||
map4.put("tag1", "hello");
|
||||
map4.put(TAG_KEY, "TAG_");
|
||||
map4.put("timeout", "5000");
|
||||
Invoker<DemoService> invoker4 = createNormalInvoker(map4);
|
||||
|
||||
// invoker5 is the only one returned at the end that is not filtered out
|
||||
Map<String, String> map5 = new HashMap<>();
|
||||
map5.put("env-sign", "xxx");
|
||||
map5.put("tag1", "hello");
|
||||
map5.put(TAG_KEY, "TAG_");
|
||||
map5.put("timeout", "5000");
|
||||
map5.put("serialization", "hessian2");
|
||||
Invoker<DemoService> invoker5 = createNormalInvoker(map5);
|
||||
|
||||
BitList<Invoker<DemoService>> invokers = new BitList<>(Arrays.asList(mockInvoker, invoker1, invoker2, invoker3, invoker4, invoker5));
|
||||
routerChain.setInvokers(invokers, () -> {});
|
||||
|
||||
// mesh rule for MeshStateRouter
|
||||
MeshRuleManager meshRuleManager = mockInvoker.getUrl().getOrDefaultModuleModel().getBeanFactory().getBean(MeshRuleManager.class);
|
||||
ConcurrentHashMap<String, MeshAppRuleListener> appRuleListeners = meshRuleManager.getAppRuleListeners();
|
||||
MeshAppRuleListener meshAppRuleListener = appRuleListeners.get(invoker1.getUrl().getRemoteApplication());
|
||||
ConfigChangedEvent configChangedEvent = new ConfigChangedEvent("demo-route" + MESH_RULE_DATA_ID_SUFFIX, DynamicConfiguration.DEFAULT_GROUP,
|
||||
MESH_RULE1 + "---\n" + MESH_RULE2, ConfigChangeType.ADDED);
|
||||
meshAppRuleListener.process(configChangedEvent);
|
||||
|
||||
|
||||
// condition rule for AppStateRouter&ServiceStateRouter
|
||||
ListenableStateRouter serviceRouter = routerChain.getStateRouters().stream().filter(s -> s instanceof ServiceStateRouter).map(s -> (ListenableStateRouter) s).findAny().orElse(null);
|
||||
ConfigChangedEvent serviceConditionEvent = new ConfigChangedEvent(DynamicConfiguration.getRuleKey(mockInvoker.getUrl()) + ".condition-router", DynamicConfiguration.DEFAULT_GROUP,
|
||||
SERVICE_CONDITION_RULE, ConfigChangeType.ADDED);
|
||||
serviceRouter.process(serviceConditionEvent);
|
||||
|
||||
ListenableStateRouter appRouter = routerChain.getStateRouters().stream().filter(s -> s instanceof AppStateRouter).map(s -> (ListenableStateRouter) s).findAny().orElse(null);
|
||||
ConfigChangedEvent appConditionEvent = new ConfigChangedEvent("app.condition-router", DynamicConfiguration.DEFAULT_GROUP,
|
||||
APP_CONDITION_RULE, ConfigChangeType.ADDED);
|
||||
appRouter.process(appConditionEvent);
|
||||
|
||||
// prepare consumerUrl and RpcInvocation
|
||||
URL consumerUrl = URL.valueOf("consumer://localhost/DemoInterface?remote.application=app1");
|
||||
RpcInvocation rpcInvocation = new RpcInvocation();
|
||||
rpcInvocation.setServiceName("DemoService");
|
||||
rpcInvocation.setObjectAttachment("trafficLabel", "xxx");
|
||||
rpcInvocation.setObjectAttachment(TAG_KEY, "TAG_");
|
||||
|
||||
RpcContext.getServiceContext().setNeedPrintRouterSnapshot(true);
|
||||
RouterSnapshotSwitcher routerSnapshotSwitcher = FrameworkModel.defaultModel().getBeanFactory().getBean(RouterSnapshotSwitcher.class);
|
||||
routerSnapshotSwitcher.addEnabledService("org.apache.dubbo.demo.DemoService");
|
||||
// route
|
||||
List<Invoker<DemoService>> result = routerChain.getSingleChain(consumerUrl, invokers, rpcInvocation)
|
||||
.route(consumerUrl, invokers, rpcInvocation);
|
||||
Assertions.assertEquals(result.size(), 1);
|
||||
Assertions.assertTrue(result.contains(invoker5));
|
||||
|
||||
String snapshotLog =
|
||||
"[ Parent (Input: 6) (Current Node Output: 6) (Chain Node Output: 1) ] Input: localhost:9103,localhost:9103,localhost:9103,localhost:9103,localhost:9103 -> Chain Node Output: localhost:9103...\n" +
|
||||
" [ MockInvokersSelector (Input: 6) (Current Node Output: 5) (Chain Node Output: 1) Router message: invocation.need.mock not set. Return normal Invokers. ] Current Node Output: localhost:9103,localhost:9103,localhost:9103,localhost:9103,localhost:9103\n" +
|
||||
" [ StandardMeshRuleRouter (Input: 5) (Current Node Output: 4) (Chain Node Output: 1) Router message: Match App: app Subset: isolation ] Current Node Output: localhost:9103,localhost:9103,localhost:9103,localhost:9103\n" +
|
||||
" [ TagStateRouter (Input: 4) (Current Node Output: 3) (Chain Node Output: 1) Router message: Disable Tag Router. Reason: tagRouterRule is invalid or disabled ] Current Node Output: localhost:9103,localhost:9103,localhost:9103\n" +
|
||||
" [ ServiceStateRouter (Input: 3) (Current Node Output: 3) (Chain Node Output: 1) Router message: null ] Current Node Output: localhost:9103,localhost:9103,localhost:9103\n" +
|
||||
" [ ConditionStateRouter (Input: 3) (Current Node Output: 2) (Chain Node Output: 2) Router message: Match return. ] Current Node Output: localhost:9103,localhost:9103\n" +
|
||||
" [ ProviderAppStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 1) Router message: Directly return. Reason: Invokers from previous router is empty or conditionRouters is empty. ] Current Node Output: localhost:9103,localhost:9103\n" +
|
||||
" [ AppStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 1) Router message: null ] Current Node Output: localhost:9103,localhost:9103\n" +
|
||||
" [ ConditionStateRouter (Input: 2) (Current Node Output: 1) (Chain Node Output: 1) Router message: Match return. ] Current Node Output: localhost:9103\n" +
|
||||
" [ AppScriptStateRouter (Input: 1) (Current Node Output: 1) (Chain Node Output: 1) Router message: Directly return from script router. Reason: Invokers from previous router is empty or script is not enabled. Script rule is: null ] Current Node Output: localhost:9103";
|
||||
String[] snapshot = routerSnapshotSwitcher.cloneSnapshot();
|
||||
Assertions.assertTrue(snapshot[0].contains(snapshotLog));
|
||||
|
||||
RpcContext.getServiceContext().setNeedPrintRouterSnapshot(false);
|
||||
result = routerChain.getSingleChain(consumerUrl, invokers, rpcInvocation)
|
||||
.route(consumerUrl, invokers, rpcInvocation);
|
||||
Assertions.assertEquals(result.size(), 1);
|
||||
Assertions.assertTrue(result.contains(invoker5));
|
||||
|
||||
routerChain.destroy();
|
||||
Assertions.assertEquals(routerChain.getRouters().size(), 0);
|
||||
Assertions.assertEquals(routerChain.getStateRouters().size(), 0);
|
||||
|
||||
}
|
||||
|
||||
private Invoker<DemoService> createMockInvoker() {
|
||||
URL url = URL.valueOf("mock://localhost:9103/DemoInterface?remote.application=app");
|
||||
Invoker<DemoService> invoker = Mockito.mock(Invoker.class);
|
||||
when(invoker.getUrl()).thenReturn(url);
|
||||
return invoker;
|
||||
}
|
||||
|
||||
private Invoker<DemoService> createNormalInvoker(Map<String, String> parameters) {
|
||||
URL url = URL.valueOf("dubbo://localhost:9103/DemoInterface?remote.application=app");
|
||||
if (CollectionUtils.isNotEmptyMap(parameters)) {
|
||||
url = url.addParameters(parameters);
|
||||
}
|
||||
Invoker<DemoService> invoker = Mockito.mock(Invoker.class);
|
||||
when(invoker.getUrl()).thenReturn(url);
|
||||
return invoker;
|
||||
}
|
||||
|
||||
|
||||
private final static String MESH_RULE1 = "apiVersion: service.dubbo.apache.org/v1alpha1\n" +
|
||||
"kind: DestinationRule\n" +
|
||||
"metadata: { name: demo-route }\n" +
|
||||
"spec:\n" +
|
||||
" host: demo\n" +
|
||||
" subsets:\n" +
|
||||
" - labels: { env-sign: xxx, tag1: hello }\n" +
|
||||
" name: isolation\n" +
|
||||
" - labels: { env-sign: yyy }\n" +
|
||||
" name: testing-trunk\n" +
|
||||
" - labels: { env-sign: zzz }\n" +
|
||||
" name: testing\n" +
|
||||
" trafficPolicy:\n" +
|
||||
" loadBalancer: { simple: ROUND_ROBIN }\n" +
|
||||
"\n";
|
||||
|
||||
private final static String MESH_RULE2 = "apiVersion: service.dubbo.apache.org/v1alpha1\n" +
|
||||
"kind: VirtualService\n" +
|
||||
"metadata: { name: demo-route }\n" +
|
||||
"spec:\n" +
|
||||
" dubbo:\n" +
|
||||
" - routedetail:\n" +
|
||||
" - match:\n" +
|
||||
" - attachments: \n" +
|
||||
" dubboContext: {trafficLabel: {regex: xxx}}\n" +
|
||||
" name: xxx-project\n" +
|
||||
" route:\n" +
|
||||
" - destination: {host: demo, subset: isolation}\n" +
|
||||
" services:\n" +
|
||||
" - {regex: DemoService}\n" +
|
||||
" hosts: [demo]\n";
|
||||
|
||||
private static final String APP_CONDITION_RULE = "scope: application\n" +
|
||||
"force: true\n" +
|
||||
"runtime: false\n" +
|
||||
"enabled: true\n" +
|
||||
"priority: 1\n" +
|
||||
"key: demo-consumer\n" +
|
||||
"conditions:\n" +
|
||||
"- => serialization=hessian2";
|
||||
|
||||
private static final String SERVICE_CONDITION_RULE = "scope: service\n" +
|
||||
"force: true\n" +
|
||||
"runtime: false\n" +
|
||||
"enabled: true\n" +
|
||||
"priority: 1\n" +
|
||||
"key: org.apache.dubbo.demo.DemoService\n" +
|
||||
"conditions:\n" +
|
||||
"- => timeout=5000";
|
||||
}
|
||||
///*
|
||||
// * Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
// * contributor license agreements. See the NOTICE file distributed with
|
||||
// * this work for additional information regarding copyright ownership.
|
||||
// * The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
// * (the "License"); you may not use this file except in compliance with
|
||||
// * the License. You may obtain a copy of the License at
|
||||
// *
|
||||
// * http://www.apache.org/licenses/LICENSE-2.0
|
||||
// *
|
||||
// * Unless required by applicable law or agreed to in writing, software
|
||||
// * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// * See the License for the specific language governing permissions and
|
||||
// * limitations under the License.
|
||||
// */
|
||||
//package org.apache.dubbo.rpc.cluster;
|
||||
//
|
||||
//
|
||||
//import java.util.Arrays;
|
||||
//import java.util.HashMap;
|
||||
//import java.util.List;
|
||||
//import java.util.Map;
|
||||
//import java.util.concurrent.ConcurrentHashMap;
|
||||
//
|
||||
//import org.apache.dubbo.common.URL;
|
||||
//import org.apache.dubbo.common.config.configcenter.ConfigChangeType;
|
||||
//import org.apache.dubbo.common.config.configcenter.ConfigChangedEvent;
|
||||
//import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
|
||||
//import org.apache.dubbo.common.url.component.ServiceConfigURL;
|
||||
//import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
//import org.apache.dubbo.rpc.Invoker;
|
||||
//import org.apache.dubbo.rpc.RpcContext;
|
||||
//import org.apache.dubbo.rpc.RpcInvocation;
|
||||
//import org.apache.dubbo.rpc.cluster.filter.DemoService;
|
||||
//import org.apache.dubbo.rpc.cluster.router.RouterSnapshotSwitcher;
|
||||
//import org.apache.dubbo.rpc.cluster.router.condition.config.AppStateRouter;
|
||||
//import org.apache.dubbo.rpc.cluster.router.condition.config.ListenableStateRouter;
|
||||
//import org.apache.dubbo.rpc.cluster.router.condition.config.ServiceStateRouter;
|
||||
//import org.apache.dubbo.rpc.cluster.router.mesh.route.MeshAppRuleListener;
|
||||
//import org.apache.dubbo.rpc.cluster.router.mesh.route.MeshRuleManager;
|
||||
//import org.apache.dubbo.rpc.cluster.router.state.BitList;
|
||||
//import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
//import org.junit.jupiter.api.Assertions;
|
||||
//import org.junit.jupiter.api.Test;
|
||||
//import org.mockito.Mockito;
|
||||
//
|
||||
//import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
|
||||
//import static org.apache.dubbo.common.constants.CommonConstants.TAG_KEY;
|
||||
//import static org.apache.dubbo.rpc.cluster.router.mesh.route.MeshRuleConstants.MESH_RULE_DATA_ID_SUFFIX;
|
||||
//import static org.mockito.Mockito.when;
|
||||
//
|
||||
//class RouterChainTest {
|
||||
//
|
||||
// /**
|
||||
// * verify the router and state router loaded by default
|
||||
// */
|
||||
// @Test
|
||||
// void testBuildRouterChain() {
|
||||
// RouterChain<DemoService> routerChain = createRouterChanin();
|
||||
// Assertions.assertEquals(0, routerChain.getRouters().size());
|
||||
// Assertions.assertEquals(7, routerChain.getStateRouters().size());
|
||||
// }
|
||||
//
|
||||
// private RouterChain<DemoService> createRouterChanin() {
|
||||
// Map<String, String> parameters = new HashMap<>();
|
||||
// parameters.put(INTERFACE_KEY, DemoService.class.getName());
|
||||
// parameters.put("registry", "zookeeper");
|
||||
// URL url = new ServiceConfigURL("dubbo",
|
||||
// "127.0.0.1",
|
||||
// 20881,
|
||||
// DemoService.class.getName(),
|
||||
// parameters);
|
||||
//
|
||||
// RouterChain<DemoService> routerChain = RouterChain.buildChain(DemoService.class, url);
|
||||
// return routerChain;
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// void testRoute() {
|
||||
// RouterChain<DemoService> routerChain = createRouterChanin();
|
||||
//
|
||||
// // mockInvoker will be filtered out by MockInvokersSelector
|
||||
// Invoker<DemoService> mockInvoker = createMockInvoker();
|
||||
//
|
||||
// // invoker1 will be filtered out by MeshStateRouter
|
||||
// Map<String, String> map1 = new HashMap<>();
|
||||
// map1.put("env-sign", "yyyyyyy");
|
||||
// Invoker<DemoService> invoker1 = createNormalInvoker(map1);
|
||||
//
|
||||
// // invoker2 will be filtered out by TagStateRouter
|
||||
// Map<String, String> map2 = new HashMap<>();
|
||||
// map2.put("env-sign", "xxx");
|
||||
// map2.put("tag1", "hello");
|
||||
// Invoker<DemoService> invoker2 = createNormalInvoker(map2);
|
||||
//
|
||||
// // invoker3 will be filtered out by AppStateRouter
|
||||
// Map<String, String> map3 = new HashMap<>();
|
||||
// map3.put("env-sign", "xxx");
|
||||
// map3.put("tag1", "hello");
|
||||
// map3.put(TAG_KEY, "TAG_");
|
||||
// Invoker<DemoService> invoker3 = createNormalInvoker(map3);
|
||||
//
|
||||
// // invoker4 will be filtered out by ServiceStateRouter
|
||||
// Map<String, String> map4 = new HashMap<>();
|
||||
// map4.put("env-sign", "xxx");
|
||||
// map4.put("tag1", "hello");
|
||||
// map4.put(TAG_KEY, "TAG_");
|
||||
// map4.put("timeout", "5000");
|
||||
// Invoker<DemoService> invoker4 = createNormalInvoker(map4);
|
||||
//
|
||||
// // invoker5 is the only one returned at the end that is not filtered out
|
||||
// Map<String, String> map5 = new HashMap<>();
|
||||
// map5.put("env-sign", "xxx");
|
||||
// map5.put("tag1", "hello");
|
||||
// map5.put(TAG_KEY, "TAG_");
|
||||
// map5.put("timeout", "5000");
|
||||
// map5.put("serialization", "hessian2");
|
||||
// Invoker<DemoService> invoker5 = createNormalInvoker(map5);
|
||||
//
|
||||
// BitList<Invoker<DemoService>> invokers = new BitList<>(Arrays.asList(mockInvoker, invoker1, invoker2, invoker3, invoker4, invoker5));
|
||||
// routerChain.setInvokers(invokers, () -> {});
|
||||
//
|
||||
// // mesh rule for MeshStateRouter
|
||||
// MeshRuleManager meshRuleManager = mockInvoker.getUrl().getOrDefaultModuleModel().getBeanFactory().getBean(MeshRuleManager.class);
|
||||
// ConcurrentHashMap<String, MeshAppRuleListener> appRuleListeners = meshRuleManager.getAppRuleListeners();
|
||||
// MeshAppRuleListener meshAppRuleListener = appRuleListeners.get(invoker1.getUrl().getRemoteApplication());
|
||||
// ConfigChangedEvent configChangedEvent = new ConfigChangedEvent("demo-route" + MESH_RULE_DATA_ID_SUFFIX, DynamicConfiguration.DEFAULT_GROUP,
|
||||
// MESH_RULE1 + "---\n" + MESH_RULE2, ConfigChangeType.ADDED);
|
||||
// meshAppRuleListener.process(configChangedEvent);
|
||||
//
|
||||
//
|
||||
// // condition rule for AppStateRouter&ServiceStateRouter
|
||||
// ListenableStateRouter serviceRouter = routerChain.getStateRouters().stream().filter(s -> s instanceof ServiceStateRouter).map(s -> (ListenableStateRouter) s).findAny().orElse(null);
|
||||
// ConfigChangedEvent serviceConditionEvent = new ConfigChangedEvent(DynamicConfiguration.getRuleKey(mockInvoker.getUrl()) + ".condition-router", DynamicConfiguration.DEFAULT_GROUP,
|
||||
// SERVICE_CONDITION_RULE, ConfigChangeType.ADDED);
|
||||
// serviceRouter.process(serviceConditionEvent);
|
||||
//
|
||||
// ListenableStateRouter appRouter = routerChain.getStateRouters().stream().filter(s -> s instanceof AppStateRouter).map(s -> (ListenableStateRouter) s).findAny().orElse(null);
|
||||
// ConfigChangedEvent appConditionEvent = new ConfigChangedEvent("app.condition-router", DynamicConfiguration.DEFAULT_GROUP,
|
||||
// APP_CONDITION_RULE, ConfigChangeType.ADDED);
|
||||
// appRouter.process(appConditionEvent);
|
||||
//
|
||||
// // prepare consumerUrl and RpcInvocation
|
||||
// URL consumerUrl = URL.valueOf("consumer://localhost/DemoInterface?remote.application=app1");
|
||||
// RpcInvocation rpcInvocation = new RpcInvocation();
|
||||
// rpcInvocation.setServiceName("DemoService");
|
||||
// rpcInvocation.setObjectAttachment("trafficLabel", "xxx");
|
||||
// rpcInvocation.setObjectAttachment(TAG_KEY, "TAG_");
|
||||
//
|
||||
// RpcContext.getServiceContext().setNeedPrintRouterSnapshot(true);
|
||||
// RouterSnapshotSwitcher routerSnapshotSwitcher = FrameworkModel.defaultModel().getBeanFactory().getBean(RouterSnapshotSwitcher.class);
|
||||
// routerSnapshotSwitcher.addEnabledService("org.apache.dubbo.demo.DemoService");
|
||||
// // route
|
||||
// List<Invoker<DemoService>> result = routerChain.getSingleChain(consumerUrl, invokers, rpcInvocation)
|
||||
// .route(consumerUrl, invokers, rpcInvocation);
|
||||
// Assertions.assertEquals(result.size(), 1);
|
||||
// Assertions.assertTrue(result.contains(invoker5));
|
||||
//
|
||||
// String snapshotLog =
|
||||
// "[ Parent (Input: 6) (Current Node Output: 6) (Chain Node Output: 1) ] Input: localhost:9103,localhost:9103,localhost:9103,localhost:9103,localhost:9103 -> Chain Node Output: localhost:9103...\n" +
|
||||
// " [ MockInvokersSelector (Input: 6) (Current Node Output: 5) (Chain Node Output: 1) Router message: invocation.need.mock not set. Return normal Invokers. ] Current Node Output: localhost:9103,localhost:9103,localhost:9103,localhost:9103,localhost:9103\n" +
|
||||
// " [ StandardMeshRuleRouter (Input: 5) (Current Node Output: 4) (Chain Node Output: 1) Router message: Match App: app Subset: isolation ] Current Node Output: localhost:9103,localhost:9103,localhost:9103,localhost:9103\n" +
|
||||
// " [ TagStateRouter (Input: 4) (Current Node Output: 3) (Chain Node Output: 1) Router message: Disable Tag Router. Reason: tagRouterRule is invalid or disabled ] Current Node Output: localhost:9103,localhost:9103,localhost:9103\n" +
|
||||
// " [ ServiceStateRouter (Input: 3) (Current Node Output: 3) (Chain Node Output: 1) Router message: null ] Current Node Output: localhost:9103,localhost:9103,localhost:9103\n" +
|
||||
// " [ ConditionStateRouter (Input: 3) (Current Node Output: 2) (Chain Node Output: 2) Router message: Match return. ] Current Node Output: localhost:9103,localhost:9103\n" +
|
||||
// " [ ProviderAppStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 1) Router message: Directly return. Reason: Invokers from previous router is empty or conditionRouters is empty. ] Current Node Output: localhost:9103,localhost:9103\n" +
|
||||
// " [ AppStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 1) Router message: null ] Current Node Output: localhost:9103,localhost:9103\n" +
|
||||
// " [ ConditionStateRouter (Input: 2) (Current Node Output: 1) (Chain Node Output: 1) Router message: Match return. ] Current Node Output: localhost:9103\n" +
|
||||
// " [ AppScriptStateRouter (Input: 1) (Current Node Output: 1) (Chain Node Output: 1) Router message: Directly return from script router. Reason: Invokers from previous router is empty or script is not enabled. Script rule is: null ] Current Node Output: localhost:9103";
|
||||
// String[] snapshot = routerSnapshotSwitcher.cloneSnapshot();
|
||||
// Assertions.assertTrue(snapshot[0].contains(snapshotLog));
|
||||
//
|
||||
// RpcContext.getServiceContext().setNeedPrintRouterSnapshot(false);
|
||||
// result = routerChain.getSingleChain(consumerUrl, invokers, rpcInvocation)
|
||||
// .route(consumerUrl, invokers, rpcInvocation);
|
||||
// Assertions.assertEquals(result.size(), 1);
|
||||
// Assertions.assertTrue(result.contains(invoker5));
|
||||
//
|
||||
// routerChain.destroy();
|
||||
// Assertions.assertEquals(routerChain.getRouters().size(), 0);
|
||||
// Assertions.assertEquals(routerChain.getStateRouters().size(), 0);
|
||||
//
|
||||
// }
|
||||
//
|
||||
// private Invoker<DemoService> createMockInvoker() {
|
||||
// URL url = URL.valueOf("mock://localhost:9103/DemoInterface?remote.application=app");
|
||||
// Invoker<DemoService> invoker = Mockito.mock(Invoker.class);
|
||||
// when(invoker.getUrl()).thenReturn(url);
|
||||
// return invoker;
|
||||
// }
|
||||
//
|
||||
// private Invoker<DemoService> createNormalInvoker(Map<String, String> parameters) {
|
||||
// URL url = URL.valueOf("dubbo://localhost:9103/DemoInterface?remote.application=app");
|
||||
// if (CollectionUtils.isNotEmptyMap(parameters)) {
|
||||
// url = url.addParameters(parameters);
|
||||
// }
|
||||
// Invoker<DemoService> invoker = Mockito.mock(Invoker.class);
|
||||
// when(invoker.getUrl()).thenReturn(url);
|
||||
// return invoker;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// private final static String MESH_RULE1 = "apiVersion: service.dubbo.apache.org/v1alpha1\n" +
|
||||
// "kind: DestinationRule\n" +
|
||||
// "metadata: { name: demo-route }\n" +
|
||||
// "spec:\n" +
|
||||
// " host: demo\n" +
|
||||
// " subsets:\n" +
|
||||
// " - labels: { env-sign: xxx, tag1: hello }\n" +
|
||||
// " name: isolation\n" +
|
||||
// " - labels: { env-sign: yyy }\n" +
|
||||
// " name: testing-trunk\n" +
|
||||
// " - labels: { env-sign: zzz }\n" +
|
||||
// " name: testing\n" +
|
||||
// " trafficPolicy:\n" +
|
||||
// " loadBalancer: { simple: ROUND_ROBIN }\n" +
|
||||
// "\n";
|
||||
//
|
||||
// private final static String MESH_RULE2 = "apiVersion: service.dubbo.apache.org/v1alpha1\n" +
|
||||
// "kind: VirtualService\n" +
|
||||
// "metadata: { name: demo-route }\n" +
|
||||
// "spec:\n" +
|
||||
// " dubbo:\n" +
|
||||
// " - routedetail:\n" +
|
||||
// " - match:\n" +
|
||||
// " - attachments: \n" +
|
||||
// " dubboContext: {trafficLabel: {regex: xxx}}\n" +
|
||||
// " name: xxx-project\n" +
|
||||
// " route:\n" +
|
||||
// " - destination: {host: demo, subset: isolation}\n" +
|
||||
// " services:\n" +
|
||||
// " - {regex: DemoService}\n" +
|
||||
// " hosts: [demo]\n";
|
||||
//
|
||||
// private static final String APP_CONDITION_RULE = "scope: application\n" +
|
||||
// "force: true\n" +
|
||||
// "runtime: false\n" +
|
||||
// "enabled: true\n" +
|
||||
// "priority: 1\n" +
|
||||
// "key: demo-consumer\n" +
|
||||
// "conditions:\n" +
|
||||
// "- => serialization=hessian2";
|
||||
//
|
||||
// private static final String SERVICE_CONDITION_RULE = "scope: service\n" +
|
||||
// "force: true\n" +
|
||||
// "runtime: false\n" +
|
||||
// "enabled: true\n" +
|
||||
// "priority: 1\n" +
|
||||
// "key: org.apache.dubbo.demo.DemoService\n" +
|
||||
// "conditions:\n" +
|
||||
// "- => timeout=5000";
|
||||
//}
|
||||
|
|
|
|||
|
|
@ -1,84 +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.rpc.cluster.filter;
|
||||
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.TracingConfig;
|
||||
import org.apache.dubbo.rpc.AppResponse;
|
||||
import org.apache.dubbo.rpc.BaseFilter;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.RpcInvocation;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import io.micrometer.tracing.test.SampleTestRunner;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
abstract class AbstractObservationFilterTest extends SampleTestRunner {
|
||||
|
||||
ApplicationModel applicationModel;
|
||||
RpcInvocation invocation;
|
||||
|
||||
BaseFilter filter;
|
||||
|
||||
Invoker<?> invoker = mock(Invoker.class);
|
||||
|
||||
static final String INTERFACE_NAME = "org.apache.dubbo.MockInterface";
|
||||
static final String METHOD_NAME = "mockMethod";
|
||||
static final String GROUP = "mockGroup";
|
||||
static final String VERSION = "1.0.0";
|
||||
|
||||
@AfterEach
|
||||
public void teardown() {
|
||||
if (applicationModel != null) {
|
||||
applicationModel.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
abstract BaseFilter createFilter(ApplicationModel applicationModel);
|
||||
|
||||
void setupConfig() {
|
||||
ApplicationConfig config = new ApplicationConfig();
|
||||
config.setName("MockObservations");
|
||||
|
||||
applicationModel = ApplicationModel.defaultModel();
|
||||
applicationModel.getApplicationConfigManager().setApplication(config);
|
||||
|
||||
invocation = new RpcInvocation(new MockInvocation());
|
||||
invocation.addInvokedInvoker(invoker);
|
||||
|
||||
applicationModel.getBeanFactory().registerBean(getObservationRegistry());
|
||||
TracingConfig tracingConfig = new TracingConfig();
|
||||
tracingConfig.setEnabled(true);
|
||||
applicationModel.getApplicationConfigManager().setTracing(tracingConfig);
|
||||
|
||||
filter = createFilter(applicationModel);
|
||||
|
||||
given(invoker.invoke(invocation)).willReturn(new AppResponse("success"));
|
||||
|
||||
initParam();
|
||||
}
|
||||
|
||||
private void initParam() {
|
||||
invocation.setTargetServiceUniqueName(GROUP + "/" + INTERFACE_NAME + ":" + VERSION);
|
||||
invocation.setMethodName(METHOD_NAME);
|
||||
invocation.setParameterTypes(new Class[] {String.class});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -60,7 +60,6 @@ import static org.apache.dubbo.common.constants.CommonConstants.MONITOR_KEY;
|
|||
import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
|
||||
import static org.apache.dubbo.rpc.cluster.Constants.CLUSTER_AVAILABLE_CHECK_KEY;
|
||||
import static org.apache.dubbo.rpc.cluster.Constants.INVOCATION_NEED_MOCK;
|
||||
import static org.apache.dubbo.rpc.cluster.Constants.REFER_KEY;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.same;
|
||||
|
|
@ -576,26 +575,6 @@ class AbstractClusterInvokerTest {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test mock invoker selector works as expected
|
||||
*/
|
||||
@Test
|
||||
void testMockedInvokerSelect() {
|
||||
initlistsize5();
|
||||
invokers.add(mockedInvoker1);
|
||||
|
||||
initDic();
|
||||
|
||||
RpcInvocation mockedInvocation = new RpcInvocation();
|
||||
mockedInvocation.setMethodName("sayHello");
|
||||
mockedInvocation.setAttachment(INVOCATION_NEED_MOCK, "true");
|
||||
List<Invoker<IHelloService>> mockedInvokers = dic.list(mockedInvocation);
|
||||
Assertions.assertEquals(1, mockedInvokers.size());
|
||||
|
||||
List<Invoker<IHelloService>> invokers = dic.list(invocation);
|
||||
Assertions.assertEquals(5, invokers.size());
|
||||
}
|
||||
|
||||
public static interface IHelloService {
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.common.aot;
|
||||
|
||||
|
||||
public abstract class NativeDetector {
|
||||
|
||||
/**
|
||||
* See https://github.com/oracle/graal/blob/master/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/ImageInfo.java
|
||||
*/
|
||||
private static final boolean IMAGE_CODE = (System.getProperty("org.graalvm.nativeimage.imagecode") != null);
|
||||
|
||||
/**
|
||||
* Returns {@code true} if invoked in the context of image building or during image runtime, else {@code false}.
|
||||
*/
|
||||
public static boolean inNativeImage() {
|
||||
return IMAGE_CODE;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -158,14 +158,6 @@ public class FileCacheStore {
|
|||
FileCacheStoreFactory.removeCache(cacheFilePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* for unit test only
|
||||
*/
|
||||
@Deprecated
|
||||
protected String getCacheFilePath() {
|
||||
return cacheFilePath;
|
||||
}
|
||||
|
||||
public static Builder newBuilder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ import java.nio.file.Files;
|
|||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
|
@ -197,14 +196,6 @@ public final class FileCacheStoreFactory {
|
|||
cacheMap.remove(cacheFileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* for unit test only
|
||||
*/
|
||||
@Deprecated
|
||||
static Map<String, FileCacheStore> getCacheMap() {
|
||||
return cacheMap;
|
||||
}
|
||||
|
||||
private static class PathNotExclusiveException extends Exception {
|
||||
public PathNotExclusiveException(String msg) {
|
||||
super(msg);
|
||||
|
|
|
|||
|
|
@ -277,7 +277,7 @@ public final class ConfigurationUtils {
|
|||
for (Map.Entry<String, V> entry : copy.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
V val = entry.getValue();
|
||||
if (StringUtils.startsWithIgnoreCase(key, prefix)
|
||||
if ((StringUtils.startsWithIgnoreCase(key, prefix) || StringUtils.startsWithIgnoreCase(key, StringUtils.toOSStyleKey(prefix)))
|
||||
&& key.length() > prefix.length()
|
||||
&& !ConfigurationUtils.isEmptyValue(val)) {
|
||||
|
||||
|
|
@ -317,7 +317,7 @@ public final class ConfigurationUtils {
|
|||
}
|
||||
for (Map.Entry<String, V> entry : copy.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
if (StringUtils.startsWithIgnoreCase(key, prefix)
|
||||
if ((StringUtils.startsWithIgnoreCase(key, prefix) || StringUtils.startsWithIgnoreCase(key, StringUtils.toOSStyleKey(prefix)))
|
||||
&& key.length() > prefix.length()
|
||||
&& !ConfigurationUtils.isEmptyValue(entry.getValue())) {
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
package org.apache.dubbo.common.config.configcenter;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.config.configcenter.file.FileSystemDynamicConfiguration;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
|
|
@ -30,7 +29,7 @@ import static org.apache.dubbo.common.utils.PathUtils.normalize;
|
|||
/**
|
||||
* An abstract implementation of {@link DynamicConfiguration} is like "tree-structure" path :
|
||||
* <ul>
|
||||
* <li>{@link FileSystemDynamicConfiguration "file"}</li>
|
||||
* <li>{@link org.apache.dubbo.common.config.configcenter.file.FileSystemDynamicConfiguration "file"}</li>
|
||||
* <li>{@link org.apache.dubbo.configcenter.support.zookeeper.ZookeeperDynamicConfiguration "zookeeper"}</li>
|
||||
* <li>{@link org.apache.dubbo.configcenter.consul.ConsulDynamicConfiguration "consul"}</li>
|
||||
* </ul>
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ public interface CommonConstants {
|
|||
String PROVIDER = "provider";
|
||||
|
||||
String CONSUMER = "consumer";
|
||||
|
||||
|
||||
String CALLBACK = "callback";
|
||||
|
||||
String APPLICATION_KEY = "application";
|
||||
|
|
@ -128,6 +128,8 @@ public interface CommonConstants {
|
|||
|
||||
String THREAD_POOL_EXHAUSTED_LISTENERS_KEY = "thread-pool-exhausted-listeners";
|
||||
|
||||
String JSON_CHECK_LEVEL_KEY = "jsonCheckLevel";
|
||||
|
||||
String THREADS_KEY = "threads";
|
||||
|
||||
String QUEUES_KEY = "queues";
|
||||
|
|
@ -285,6 +287,7 @@ public interface CommonConstants {
|
|||
String MONITOR_KEY = "monitor";
|
||||
String BACKGROUND_KEY = "background";
|
||||
String CLUSTER_KEY = "cluster";
|
||||
String MERGEABLE_CLUSTER_NAME = "mergeable";
|
||||
String USERNAME_KEY = "username";
|
||||
String PASSWORD_KEY = "password";
|
||||
String HOST_KEY = "host";
|
||||
|
|
@ -500,11 +503,6 @@ public interface CommonConstants {
|
|||
*/
|
||||
String URL_MERGE_PROCESSOR_KEY = "url-merge-processor";
|
||||
|
||||
/**
|
||||
* use native image to compile dubbo's identifier
|
||||
*/
|
||||
String NATIVE = "native";
|
||||
|
||||
String DUBBO_MONITOR_ADDRESS = "dubbo.monitor.address";
|
||||
|
||||
String SERVICE_NAME_MAPPING_KEY = "service-name-mapping";
|
||||
|
|
@ -618,9 +616,7 @@ public interface CommonConstants {
|
|||
|
||||
|
||||
/**
|
||||
*
|
||||
* used in JVMUtil.java ,Control stack print lines, default is 32 lines
|
||||
*
|
||||
*/
|
||||
String DUBBO_JSTACK_MAXLINE = "dubbo.jstack-dump.max-line";
|
||||
|
||||
|
|
@ -643,5 +639,17 @@ public interface CommonConstants {
|
|||
|
||||
String DUBBO_PACKABLE_METHOD_FACTORY = "dubbo.application.parameters." + PACKABLE_METHOD_FACTORY_KEY;
|
||||
|
||||
String DUBBO_TAG_HEADER = "dubbo-tag";
|
||||
|
||||
String REST_SERVICE_DEPLOYER_URL_ATTRIBUTE_KEY = "restServiceDeployerAttributeKey";
|
||||
|
||||
String SERVICE_DEPLOYER_ATTRIBUTE_KEY = "serviceDeployer";
|
||||
|
||||
|
||||
|
||||
String DUBBO_MANUAL_REGISTER_KEY = "dubbo.application.manual-register";
|
||||
|
||||
String EXT_PROTOCOL = "ext.protocol";
|
||||
|
||||
String IS_EXTRA = "isExtra";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ public interface LoggerCodeConstants {
|
|||
|
||||
String VULNERABILITY_WARNING = "0-28";
|
||||
|
||||
String COMMON_NOT_FOUND_TRACER_DEPENDENCY = "0-29";
|
||||
|
||||
// Registry module
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ public interface MetricsConstants {
|
|||
|
||||
String TAG_CHANGE_TYPE = "change.type";
|
||||
|
||||
String TAG_ERROR_CODE = "error";
|
||||
|
||||
String ENABLE_JVM_METRICS_KEY = "enable.jvm";
|
||||
|
||||
String ENABLE_COLLECTOR_SYNC_KEY = "enable.collector.sync";
|
||||
|
|
|
|||
|
|
@ -48,7 +48,9 @@ public interface ApplicationDeployer extends Deployer<ApplicationModel> {
|
|||
/**
|
||||
* Register application instance and start internal services
|
||||
*/
|
||||
void prepareApplicationInstance();
|
||||
void prepareApplicationInstance(ModuleModel moduleModel);
|
||||
|
||||
void exportMetadataService();
|
||||
|
||||
/**
|
||||
* Register application instance and start internal services
|
||||
|
|
|
|||
|
|
@ -50,4 +50,8 @@ public interface ModuleDeployer extends Deployer<ModuleModel> {
|
|||
* Whether start in background, do not await finish
|
||||
*/
|
||||
boolean isBackground();
|
||||
|
||||
boolean hasRegistryInteraction();
|
||||
|
||||
ApplicationDeployer getApplicationDeployer();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package org.apache.dubbo.common.extension;
|
|||
|
||||
import org.apache.dubbo.common.Extension;
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.aot.NativeDetector;
|
||||
import org.apache.dubbo.common.beans.support.InstantiationStrategy;
|
||||
import org.apache.dubbo.common.context.Lifecycle;
|
||||
import org.apache.dubbo.common.extension.support.ActivateComparator;
|
||||
|
|
@ -33,7 +34,6 @@ import org.apache.dubbo.common.utils.CollectionUtils;
|
|||
import org.apache.dubbo.common.utils.ConcurrentHashSet;
|
||||
import org.apache.dubbo.common.utils.ConfigUtils;
|
||||
import org.apache.dubbo.common.utils.Holder;
|
||||
import org.apache.dubbo.common.utils.NativeUtils;
|
||||
import org.apache.dubbo.common.utils.ReflectUtils;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
|
@ -108,8 +108,8 @@ public class ExtensionLoader<T> {
|
|||
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(
|
||||
ExtensionLoader.class);
|
||||
|
||||
private static final Pattern NAME_SEPARATOR = Pattern.compile("\\s*[,]+\\s*");
|
||||
private static final String SPECIAL_SPI_PROPERTIES = "special_spi.properties";
|
||||
private static final Pattern NAME_SEPARATOR = Pattern.compile("\\s*[,]+\\s*");
|
||||
private static final String SPECIAL_SPI_PROPERTIES = "special_spi.properties";
|
||||
|
||||
private final ConcurrentMap<Class<?>, Object> extensionInstances = new ConcurrentHashMap<>(64);
|
||||
|
||||
|
|
@ -121,17 +121,17 @@ public class ExtensionLoader<T> {
|
|||
|
||||
private final Holder<Map<String, Class<?>>> cachedClasses = new Holder<>();
|
||||
|
||||
private final Map<String, Object> cachedActivates = Collections.synchronizedMap(
|
||||
private final Map<String, Object> cachedActivates = Collections.synchronizedMap(
|
||||
new LinkedHashMap<>());
|
||||
private final Map<String, Set<String>> cachedActivateGroups = Collections.synchronizedMap(
|
||||
private final Map<String, Set<String>> cachedActivateGroups = Collections.synchronizedMap(
|
||||
new LinkedHashMap<>());
|
||||
private final Map<String, String[][]> cachedActivateValues = Collections.synchronizedMap(
|
||||
private final Map<String, String[][]> cachedActivateValues = Collections.synchronizedMap(
|
||||
new LinkedHashMap<>());
|
||||
private final ConcurrentMap<String, Holder<Object>> cachedInstances = new ConcurrentHashMap<>();
|
||||
private final Holder<Object> cachedAdaptiveInstance = new Holder<>();
|
||||
private volatile Class<?> cachedAdaptiveClass = null;
|
||||
private String cachedDefaultName;
|
||||
private volatile Throwable createAdaptiveInstanceError;
|
||||
private final ConcurrentMap<String, Holder<Object>> cachedInstances = new ConcurrentHashMap<>();
|
||||
private final Holder<Object> cachedAdaptiveInstance = new Holder<>();
|
||||
private volatile Class<?> cachedAdaptiveClass = null;
|
||||
private String cachedDefaultName;
|
||||
private volatile Throwable createAdaptiveInstanceError;
|
||||
|
||||
private Set<Class<?>> cachedWrapperClasses;
|
||||
|
||||
|
|
@ -149,13 +149,13 @@ public class ExtensionLoader<T> {
|
|||
/**
|
||||
* Record all unacceptable exceptions when using SPI
|
||||
*/
|
||||
private final Set<String> unacceptableExceptions = new ConcurrentHashSet<>();
|
||||
private final ExtensionDirector extensionDirector;
|
||||
private final Set<String> unacceptableExceptions = new ConcurrentHashSet<>();
|
||||
private final ExtensionDirector extensionDirector;
|
||||
private final List<ExtensionPostProcessor> extensionPostProcessors;
|
||||
private InstantiationStrategy instantiationStrategy;
|
||||
private final ActivateComparator activateComparator;
|
||||
private final ScopeModel scopeModel;
|
||||
private final AtomicBoolean destroyed = new AtomicBoolean();
|
||||
private InstantiationStrategy instantiationStrategy;
|
||||
private final ActivateComparator activateComparator;
|
||||
private final ScopeModel scopeModel;
|
||||
private final AtomicBoolean destroyed = new AtomicBoolean();
|
||||
|
||||
public static void setLoadingStrategies(LoadingStrategy... strategies) {
|
||||
if (ArrayUtils.isNotEmpty(strategies)) {
|
||||
|
|
@ -1412,7 +1412,7 @@ public class ExtensionLoader<T> {
|
|||
// Adaptive Classes' ClassLoader should be the same with Real SPI interface classes' ClassLoader
|
||||
ClassLoader classLoader = type.getClassLoader();
|
||||
try {
|
||||
if (NativeUtils.isNative()) {
|
||||
if (NativeDetector.inNativeImage()) {
|
||||
return classLoader.loadClass(type.getName() + "$Adaptive");
|
||||
}
|
||||
} catch (Throwable ignore) {
|
||||
|
|
|
|||
|
|
@ -60,6 +60,17 @@ public class GsonUtils {
|
|||
}
|
||||
}
|
||||
|
||||
public static String toJson(Object obj) throws RuntimeException {
|
||||
if (!isSupportGson()) {
|
||||
throw new RuntimeException("Gson is not supported. Please import Gson in JVM env.");
|
||||
}
|
||||
try {
|
||||
return getGson().toJson(obj);
|
||||
} catch (JsonSyntaxException ex) {
|
||||
throw new RuntimeException(String.format("Generic serialization [%s] Json syntax exception thrown when parsing (object:%s ) error:%s", GENERIC_SERIALIZATION_GSON, obj, ex.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
private static Gson getGson() {
|
||||
if (gsonCache == null || !(gsonCache instanceof Gson)) {
|
||||
synchronized (GsonUtils.class) {
|
||||
|
|
|
|||
|
|
@ -16,11 +16,14 @@
|
|||
*/
|
||||
package org.apache.dubbo.common.json;
|
||||
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface JSON {
|
||||
@SPI
|
||||
public interface JsonUtil {
|
||||
boolean isSupport();
|
||||
|
||||
<T> T toJavaObject(String json, Type type);
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
*/
|
||||
package org.apache.dubbo.common.json.impl;
|
||||
|
||||
import org.apache.dubbo.common.json.JSON;
|
||||
import org.apache.dubbo.common.json.JsonUtil;
|
||||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
|
@ -24,7 +24,7 @@ import java.util.LinkedList;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class AbstractJSONImpl implements JSON {
|
||||
public abstract class AbstractJsonUtilImpl implements JsonUtil {
|
||||
@Override
|
||||
public boolean isSupport() {
|
||||
try {
|
||||
|
|
@ -21,7 +21,7 @@ import com.alibaba.fastjson2.JSONWriter;
|
|||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
|
||||
public class FastJson2Impl extends AbstractJSONImpl {
|
||||
public class FastJson2Impl extends AbstractJsonUtilImpl {
|
||||
@Override
|
||||
public <T> T toJavaObject(String json, Type type) {
|
||||
return com.alibaba.fastjson2.JSON.parseObject(json, type);
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import com.alibaba.fastjson.serializer.SerializerFeature;
|
|||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
|
||||
public class FastJsonImpl extends AbstractJSONImpl {
|
||||
public class FastJsonImpl extends AbstractJsonUtilImpl {
|
||||
|
||||
@Override
|
||||
public <T> T toJavaObject(String json, Type type) {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import com.google.gson.reflect.TypeToken;
|
|||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
|
||||
public class GsonImpl extends AbstractJSONImpl {
|
||||
public class GsonImpl extends AbstractJsonUtilImpl {
|
||||
// weak reference of com.google.gson.Gson, prevent throw exception when init
|
||||
private volatile Object gsonCache = null;
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
|||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
|
||||
public class JacksonImpl extends AbstractJSONImpl {
|
||||
public class JacksonImpl extends AbstractJsonUtilImpl {
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
private volatile Object jacksonCache = null;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dubbo.common.logger;
|
||||
|
||||
/**
|
||||
* Loggers that can register to listen to log messages.
|
||||
*/
|
||||
public interface ListenableLogger extends ErrorTypeAwareLogger{
|
||||
|
||||
/**
|
||||
* Register a listener to this logger,and get notified when a log happens.
|
||||
*
|
||||
* @param listener log listener
|
||||
*/
|
||||
void registerListen(LogListener listener);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 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.common.logger;
|
||||
|
||||
/**
|
||||
* Log Listener, can registered to an {@link ListenableLogger}.
|
||||
*/
|
||||
public interface LogListener {
|
||||
|
||||
void onMessage(String code, String msg);
|
||||
|
||||
}
|
||||
|
|
@ -30,6 +30,14 @@ public interface Logger {
|
|||
*/
|
||||
void trace(String msg);
|
||||
|
||||
/**
|
||||
* Logs a message with trace log level.
|
||||
*
|
||||
* @param msg log this message
|
||||
* @param arguments a list of arguments
|
||||
*/
|
||||
void trace(String msg, Object... arguments);
|
||||
|
||||
/**
|
||||
* Logs an error with trace log level.
|
||||
*
|
||||
|
|
@ -52,6 +60,14 @@ public interface Logger {
|
|||
*/
|
||||
void debug(String msg);
|
||||
|
||||
/**
|
||||
* Logs a message with debug log level.
|
||||
*
|
||||
* @param msg log this message
|
||||
* @param arguments a list of arguments
|
||||
*/
|
||||
void debug(String msg, Object... arguments);
|
||||
|
||||
/**
|
||||
* Logs an error with debug log level.
|
||||
*
|
||||
|
|
@ -74,6 +90,14 @@ public interface Logger {
|
|||
*/
|
||||
void info(String msg);
|
||||
|
||||
/**
|
||||
* Logs a message with info log level.
|
||||
*
|
||||
* @param msg log this message
|
||||
* @param arguments a list of arguments
|
||||
*/
|
||||
void info(String msg, Object... arguments);
|
||||
|
||||
/**
|
||||
* Logs an error with info log level.
|
||||
*
|
||||
|
|
@ -96,6 +120,14 @@ public interface Logger {
|
|||
*/
|
||||
void warn(String msg);
|
||||
|
||||
/**
|
||||
* Logs a message with warn log level.
|
||||
*
|
||||
* @param msg log this message
|
||||
* @param arguments a list of arguments
|
||||
*/
|
||||
void warn(String msg, Object... arguments);
|
||||
|
||||
/**
|
||||
* Logs a message with warn log level.
|
||||
*
|
||||
|
|
@ -118,6 +150,14 @@ public interface Logger {
|
|||
*/
|
||||
void error(String msg);
|
||||
|
||||
/**
|
||||
* Logs a message with error log level.
|
||||
*
|
||||
* @param msg log this message
|
||||
* @param arguments a list of arguments
|
||||
*/
|
||||
void error(String msg, Object... arguments);
|
||||
|
||||
/**
|
||||
* Logs an error with error log level.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2011 QOS.ch
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
package org.apache.dubbo.common.logger.helpers;
|
||||
|
||||
/**
|
||||
* Holds the results of formatting done by {@link MessageFormatter}.
|
||||
* This is a copy of org.slf4j.helpers.FormattingTuple from slf4j-api.
|
||||
*
|
||||
* @author Joern Huxhorn
|
||||
*/
|
||||
public class FormattingTuple {
|
||||
|
||||
static public FormattingTuple NULL = new FormattingTuple(null);
|
||||
|
||||
private String message;
|
||||
private Throwable throwable;
|
||||
private Object[] argArray;
|
||||
|
||||
public FormattingTuple(String message) {
|
||||
this(message, null, null);
|
||||
}
|
||||
|
||||
public FormattingTuple(String message, Object[] argArray, Throwable throwable) {
|
||||
this.message = message;
|
||||
this.throwable = throwable;
|
||||
this.argArray = argArray;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public Object[] getArgArray() {
|
||||
return argArray;
|
||||
}
|
||||
|
||||
public Throwable getThrowable() {
|
||||
return throwable;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,437 @@
|
|||
/*
|
||||
* Copyright (c) 2004-2011 QOS.ch
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
package org.apache.dubbo.common.logger.helpers;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
// contributors: lizongbo: proposed special treatment of array parameter values
|
||||
// Joern Huxhorn: pointed out double[] omission, suggested deep array copy
|
||||
|
||||
/**
|
||||
* This is a copy of org.slf4j.helpers.MessageFormatter from slf4j-api.
|
||||
* Formats messages according to very simple substitution rules. Substitutions
|
||||
* can be made 1, 2 or more arguments.
|
||||
*
|
||||
* <p>
|
||||
* For example,
|
||||
*
|
||||
* <pre>
|
||||
* MessageFormatter.format("Hi {}.", "there")
|
||||
* </pre>
|
||||
* <p>
|
||||
* will return the string "Hi there.".
|
||||
* <p>
|
||||
* The {} pair is called the <em>formatting anchor</em>. It serves to designate
|
||||
* the location where arguments need to be substituted within the message
|
||||
* pattern.
|
||||
* <p>
|
||||
* In case your message contains the '{' or the '}' character, you do not have
|
||||
* to do anything special unless the '}' character immediately follows '{'. For
|
||||
* example,
|
||||
*
|
||||
* <pre>
|
||||
* MessageFormatter.format("Set {1,2,3} is not equal to {}.", "1,2");
|
||||
* </pre>
|
||||
* <p>
|
||||
* will return the string "Set {1,2,3} is not equal to 1,2.".
|
||||
*
|
||||
* <p>
|
||||
* If for whatever reason you need to place the string "{}" in the message
|
||||
* without its <em>formatting anchor</em> meaning, then you need to escape the
|
||||
* '{' character with '\', that is the backslash character. Only the '{'
|
||||
* character should be escaped. There is no need to escape the '}' character.
|
||||
* For example,
|
||||
*
|
||||
* <pre>
|
||||
* MessageFormatter.format("Set \\{} is not equal to {}.", "1,2");
|
||||
* </pre>
|
||||
* <p>
|
||||
* will return the string "Set {} is not equal to 1,2.".
|
||||
*
|
||||
* <p>
|
||||
* The escaping behavior just described can be overridden by escaping the escape
|
||||
* character '\'. Calling
|
||||
*
|
||||
* <pre>
|
||||
* MessageFormatter.format("File name is C:\\\\{}.", "file.zip");
|
||||
* </pre>
|
||||
* <p>
|
||||
* will return the string "File name is C:\file.zip".
|
||||
*
|
||||
* <p>
|
||||
* The formatting conventions are different than those of {@link MessageFormat}
|
||||
* which ships with the Java platform. This is justified by the fact that
|
||||
* SLF4J's implementation is 10 times faster than that of {@link MessageFormat}.
|
||||
* This local performance difference is both measurable and significant in the
|
||||
* larger context of the complete logging processing chain.
|
||||
*
|
||||
* <p>
|
||||
* See also {@link #format(String, Object)},
|
||||
* {@link #format(String, Object, Object)} and
|
||||
* {@link #arrayFormat(String, Object[])} methods for more details.
|
||||
*
|
||||
* @author Ceki Gülcü
|
||||
* @author Joern Huxhorn
|
||||
*/
|
||||
final public class MessageFormatter {
|
||||
static final char DELIM_START = '{';
|
||||
static final char DELIM_STOP = '}';
|
||||
static final String DELIM_STR = "{}";
|
||||
private static final char ESCAPE_CHAR = '\\';
|
||||
|
||||
/**
|
||||
* Performs single argument substitution for the 'messagePattern' passed as
|
||||
* parameter.
|
||||
* <p>
|
||||
* For example,
|
||||
*
|
||||
* <pre>
|
||||
* MessageFormatter.format("Hi {}.", "there");
|
||||
* </pre>
|
||||
* <p>
|
||||
* will return the string "Hi there.".
|
||||
* <p>
|
||||
*
|
||||
* @param messagePattern The message pattern which will be parsed and formatted
|
||||
* @param arg The argument to be substituted in place of the formatting anchor
|
||||
* @return The formatted message
|
||||
*/
|
||||
final public static FormattingTuple format(String messagePattern, Object arg) {
|
||||
return arrayFormat(messagePattern, new Object[]{arg});
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a two argument substitution for the 'messagePattern' passed as
|
||||
* parameter.
|
||||
* <p>
|
||||
* For example,
|
||||
*
|
||||
* <pre>
|
||||
* MessageFormatter.format("Hi {}. My name is {}.", "Alice", "Bob");
|
||||
* </pre>
|
||||
* <p>
|
||||
* will return the string "Hi Alice. My name is Bob.".
|
||||
*
|
||||
* @param messagePattern The message pattern which will be parsed and formatted
|
||||
* @param arg1 The argument to be substituted in place of the first formatting
|
||||
* anchor
|
||||
* @param arg2 The argument to be substituted in place of the second formatting
|
||||
* anchor
|
||||
* @return The formatted message
|
||||
*/
|
||||
final public static FormattingTuple format(final String messagePattern, Object arg1, Object arg2) {
|
||||
return arrayFormat(messagePattern, new Object[]{arg1, arg2});
|
||||
}
|
||||
|
||||
|
||||
final public static FormattingTuple arrayFormat(final String messagePattern, final Object[] argArray) {
|
||||
Throwable throwableCandidate = MessageFormatter.getThrowableCandidate(argArray);
|
||||
Object[] args = argArray;
|
||||
if (throwableCandidate != null) {
|
||||
args = MessageFormatter.trimmedCopy(argArray);
|
||||
}
|
||||
return arrayFormat(messagePattern, args, throwableCandidate);
|
||||
}
|
||||
|
||||
final public static FormattingTuple arrayFormat(final String messagePattern, final Object[] argArray, Throwable throwable) {
|
||||
|
||||
if (messagePattern == null) {
|
||||
return new FormattingTuple(null, argArray, throwable);
|
||||
}
|
||||
|
||||
if (argArray == null) {
|
||||
return new FormattingTuple(messagePattern);
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
int j;
|
||||
// use string builder for better multicore performance
|
||||
StringBuilder sbuf = new StringBuilder(messagePattern.length() + 50);
|
||||
|
||||
int L;
|
||||
for (L = 0; L < argArray.length; L++) {
|
||||
|
||||
j = messagePattern.indexOf(DELIM_STR, i);
|
||||
|
||||
if (j == -1) {
|
||||
// no more variables
|
||||
if (i == 0) { // this is a simple string
|
||||
return new FormattingTuple(messagePattern, argArray, throwable);
|
||||
} else { // add the tail string which contains no variables and return
|
||||
// the result.
|
||||
sbuf.append(messagePattern, i, messagePattern.length());
|
||||
return new FormattingTuple(sbuf.toString(), argArray, throwable);
|
||||
}
|
||||
} else {
|
||||
if (isEscapedDelimeter(messagePattern, j)) {
|
||||
if (!isDoubleEscaped(messagePattern, j)) {
|
||||
L--; // DELIM_START was escaped, thus should not be incremented
|
||||
sbuf.append(messagePattern, i, j - 1);
|
||||
sbuf.append(DELIM_START);
|
||||
i = j + 1;
|
||||
} else {
|
||||
// The escape character preceding the delimiter start is
|
||||
// itself escaped: "abc x:\\{}"
|
||||
// we have to consume one backward slash
|
||||
sbuf.append(messagePattern, i, j - 1);
|
||||
deeplyAppendParameter(sbuf, argArray[L], new HashMap<Object[], Object>());
|
||||
i = j + 2;
|
||||
}
|
||||
} else {
|
||||
// normal case
|
||||
sbuf.append(messagePattern, i, j);
|
||||
deeplyAppendParameter(sbuf, argArray[L], new HashMap<Object[], Object>());
|
||||
i = j + 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
// append the characters following the last {} pair.
|
||||
sbuf.append(messagePattern, i, messagePattern.length());
|
||||
return new FormattingTuple(sbuf.toString(), argArray, throwable);
|
||||
}
|
||||
|
||||
final static boolean isEscapedDelimeter(String messagePattern, int delimeterStartIndex) {
|
||||
|
||||
if (delimeterStartIndex == 0) {
|
||||
return false;
|
||||
}
|
||||
char potentialEscape = messagePattern.charAt(delimeterStartIndex - 1);
|
||||
if (potentialEscape == ESCAPE_CHAR) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
final static boolean isDoubleEscaped(String messagePattern, int delimeterStartIndex) {
|
||||
if (delimeterStartIndex >= 2 && messagePattern.charAt(delimeterStartIndex - 2) == ESCAPE_CHAR) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// special treatment of array values was suggested by 'lizongbo'
|
||||
private static void deeplyAppendParameter(StringBuilder sbuf, Object o, Map<Object[], Object> seenMap) {
|
||||
if (o == null) {
|
||||
sbuf.append("null");
|
||||
return;
|
||||
}
|
||||
if (!o.getClass().isArray()) {
|
||||
safeObjectAppend(sbuf, o);
|
||||
} else {
|
||||
// check for primitive array types because they
|
||||
// unfortunately cannot be cast to Object[]
|
||||
if (o instanceof boolean[]) {
|
||||
booleanArrayAppend(sbuf, (boolean[]) o);
|
||||
} else if (o instanceof byte[]) {
|
||||
byteArrayAppend(sbuf, (byte[]) o);
|
||||
} else if (o instanceof char[]) {
|
||||
charArrayAppend(sbuf, (char[]) o);
|
||||
} else if (o instanceof short[]) {
|
||||
shortArrayAppend(sbuf, (short[]) o);
|
||||
} else if (o instanceof int[]) {
|
||||
intArrayAppend(sbuf, (int[]) o);
|
||||
} else if (o instanceof long[]) {
|
||||
longArrayAppend(sbuf, (long[]) o);
|
||||
} else if (o instanceof float[]) {
|
||||
floatArrayAppend(sbuf, (float[]) o);
|
||||
} else if (o instanceof double[]) {
|
||||
doubleArrayAppend(sbuf, (double[]) o);
|
||||
} else {
|
||||
objectArrayAppend(sbuf, (Object[]) o, seenMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void safeObjectAppend(StringBuilder sbuf, Object o) {
|
||||
try {
|
||||
String oAsString = o.toString();
|
||||
sbuf.append(oAsString);
|
||||
} catch (Throwable t) {
|
||||
System.err.println("SLF4J: Failed toString() invocation on an object of type [" + o.getClass().getName() + "]");
|
||||
System.err.println("Reported exception:");
|
||||
StackTraceElement[] stackTrace = t.getStackTrace();
|
||||
StringBuilder stackBuilder = new StringBuilder();
|
||||
for (StackTraceElement traceElement : stackTrace) {
|
||||
stackBuilder.append("\tat ").append(traceElement).append("\n");
|
||||
}
|
||||
System.err.println(stackBuilder);
|
||||
sbuf.append("[FAILED toString()]");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void objectArrayAppend(StringBuilder sbuf, Object[] a, Map<Object[], Object> seenMap) {
|
||||
sbuf.append('[');
|
||||
if (!seenMap.containsKey(a)) {
|
||||
seenMap.put(a, null);
|
||||
final int len = a.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
deeplyAppendParameter(sbuf, a[i], seenMap);
|
||||
if (i != len - 1)
|
||||
sbuf.append(", ");
|
||||
}
|
||||
// allow repeats in siblings
|
||||
seenMap.remove(a);
|
||||
} else {
|
||||
sbuf.append("...");
|
||||
}
|
||||
sbuf.append(']');
|
||||
}
|
||||
|
||||
private static void booleanArrayAppend(StringBuilder sbuf, boolean[] a) {
|
||||
sbuf.append('[');
|
||||
final int len = a.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
sbuf.append(a[i]);
|
||||
if (i != len - 1)
|
||||
sbuf.append(", ");
|
||||
}
|
||||
sbuf.append(']');
|
||||
}
|
||||
|
||||
private static void byteArrayAppend(StringBuilder sbuf, byte[] a) {
|
||||
sbuf.append('[');
|
||||
final int len = a.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
sbuf.append(a[i]);
|
||||
if (i != len - 1)
|
||||
sbuf.append(", ");
|
||||
}
|
||||
sbuf.append(']');
|
||||
}
|
||||
|
||||
private static void charArrayAppend(StringBuilder sbuf, char[] a) {
|
||||
sbuf.append('[');
|
||||
final int len = a.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
sbuf.append(a[i]);
|
||||
if (i != len - 1)
|
||||
sbuf.append(", ");
|
||||
}
|
||||
sbuf.append(']');
|
||||
}
|
||||
|
||||
private static void shortArrayAppend(StringBuilder sbuf, short[] a) {
|
||||
sbuf.append('[');
|
||||
final int len = a.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
sbuf.append(a[i]);
|
||||
if (i != len - 1)
|
||||
sbuf.append(", ");
|
||||
}
|
||||
sbuf.append(']');
|
||||
}
|
||||
|
||||
private static void intArrayAppend(StringBuilder sbuf, int[] a) {
|
||||
sbuf.append('[');
|
||||
final int len = a.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
sbuf.append(a[i]);
|
||||
if (i != len - 1)
|
||||
sbuf.append(", ");
|
||||
}
|
||||
sbuf.append(']');
|
||||
}
|
||||
|
||||
private static void longArrayAppend(StringBuilder sbuf, long[] a) {
|
||||
sbuf.append('[');
|
||||
final int len = a.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
sbuf.append(a[i]);
|
||||
if (i != len - 1)
|
||||
sbuf.append(", ");
|
||||
}
|
||||
sbuf.append(']');
|
||||
}
|
||||
|
||||
private static void floatArrayAppend(StringBuilder sbuf, float[] a) {
|
||||
sbuf.append('[');
|
||||
final int len = a.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
sbuf.append(a[i]);
|
||||
if (i != len - 1)
|
||||
sbuf.append(", ");
|
||||
}
|
||||
sbuf.append(']');
|
||||
}
|
||||
|
||||
private static void doubleArrayAppend(StringBuilder sbuf, double[] a) {
|
||||
sbuf.append('[');
|
||||
final int len = a.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
sbuf.append(a[i]);
|
||||
if (i != len - 1)
|
||||
sbuf.append(", ");
|
||||
}
|
||||
sbuf.append(']');
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to determine if an {@link Object} array contains a {@link Throwable} as last element
|
||||
*
|
||||
* @param argArray The arguments off which we want to know if it contains a {@link Throwable} as last element
|
||||
* @return if the last {@link Object} in argArray is a {@link Throwable} this method will return it,
|
||||
* otherwise it returns null
|
||||
*/
|
||||
public static Throwable getThrowableCandidate(final Object[] argArray) {
|
||||
if (argArray == null || argArray.length == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final Object lastEntry = argArray[argArray.length - 1];
|
||||
if (lastEntry instanceof Throwable) {
|
||||
return (Throwable) lastEntry;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to get all but the last element of an array
|
||||
*
|
||||
* @param argArray The arguments from which we want to remove the last element
|
||||
* @return a copy of the array without the last element
|
||||
*/
|
||||
public static Object[] trimmedCopy(final Object[] argArray) {
|
||||
if (argArray == null || argArray.length == 0) {
|
||||
throw new IllegalStateException("non-sensical empty or null argument array");
|
||||
}
|
||||
|
||||
final int trimmedLen = argArray.length - 1;
|
||||
|
||||
Object[] trimmed = new Object[trimmedLen];
|
||||
|
||||
if (trimmedLen > 0) {
|
||||
System.arraycopy(argArray, 0, trimmed, 0, trimmedLen);
|
||||
}
|
||||
|
||||
return trimmed;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -19,6 +19,8 @@ package org.apache.dubbo.common.logger.jcl;
|
|||
import org.apache.dubbo.common.logger.Logger;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.slf4j.helpers.FormattingTuple;
|
||||
import org.slf4j.helpers.MessageFormatter;
|
||||
|
||||
/**
|
||||
* Adaptor to commons logging, depends on commons-logging.jar. For more information about commons logging, pls. refer to
|
||||
|
|
@ -37,6 +39,12 @@ public class JclLogger implements Logger {
|
|||
logger.trace(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trace(String msg, Object... arguments) {
|
||||
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
|
||||
logger.trace(ft.getMessage(), ft.getThrowable());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trace(Throwable e) {
|
||||
logger.trace(e);
|
||||
|
|
@ -52,6 +60,12 @@ public class JclLogger implements Logger {
|
|||
logger.debug(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(String msg, Object... arguments) {
|
||||
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
|
||||
logger.debug(ft.getMessage(), ft.getThrowable());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(Throwable e) {
|
||||
logger.debug(e);
|
||||
|
|
@ -67,6 +81,12 @@ public class JclLogger implements Logger {
|
|||
logger.info(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(String msg, Object... arguments) {
|
||||
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
|
||||
logger.info(ft.getMessage(), ft.getThrowable());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(Throwable e) {
|
||||
logger.info(e);
|
||||
|
|
@ -82,6 +102,12 @@ public class JclLogger implements Logger {
|
|||
logger.warn(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String msg, Object... arguments) {
|
||||
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
|
||||
logger.warn(ft.getMessage(), ft.getThrowable());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(Throwable e) {
|
||||
logger.warn(e);
|
||||
|
|
@ -97,6 +123,12 @@ public class JclLogger implements Logger {
|
|||
logger.error(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(String msg, Object... arguments) {
|
||||
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
|
||||
logger.error(ft.getMessage(), ft.getThrowable());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(Throwable e) {
|
||||
logger.error(e);
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
package org.apache.dubbo.common.logger.jdk;
|
||||
|
||||
import org.apache.dubbo.common.logger.Logger;
|
||||
import org.slf4j.helpers.FormattingTuple;
|
||||
import org.slf4j.helpers.MessageFormatter;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
|
|
@ -33,6 +35,12 @@ public class JdkLogger implements Logger {
|
|||
logger.log(Level.FINER, msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trace(String msg, Object... arguments) {
|
||||
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
|
||||
logger.log(Level.FINER, ft.getMessage(), ft.getThrowable());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trace(Throwable e) {
|
||||
logger.log(Level.FINER, e.getMessage(), e);
|
||||
|
|
@ -48,6 +56,12 @@ public class JdkLogger implements Logger {
|
|||
logger.log(Level.FINE, msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(String msg, Object... arguments) {
|
||||
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
|
||||
logger.log(Level.FINE, ft.getMessage(), ft.getThrowable());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(Throwable e) {
|
||||
logger.log(Level.FINE, e.getMessage(), e);
|
||||
|
|
@ -63,6 +77,12 @@ public class JdkLogger implements Logger {
|
|||
logger.log(Level.INFO, msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(String msg, Object... arguments) {
|
||||
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
|
||||
logger.log(Level.INFO, ft.getMessage(), ft.getThrowable());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(String msg, Throwable e) {
|
||||
logger.log(Level.INFO, msg, e);
|
||||
|
|
@ -73,6 +93,12 @@ public class JdkLogger implements Logger {
|
|||
logger.log(Level.WARNING, msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String msg, Object... arguments) {
|
||||
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
|
||||
logger.log(Level.WARNING, ft.getMessage(), ft.getThrowable());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String msg, Throwable e) {
|
||||
logger.log(Level.WARNING, msg, e);
|
||||
|
|
@ -83,6 +109,12 @@ public class JdkLogger implements Logger {
|
|||
logger.log(Level.SEVERE, msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(String msg, Object... arguments) {
|
||||
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
|
||||
logger.log(Level.SEVERE, ft.getMessage(), ft.getThrowable());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(String msg, Throwable e) {
|
||||
logger.log(Level.SEVERE, msg, e);
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ import org.apache.dubbo.common.logger.Logger;
|
|||
import org.apache.dubbo.common.logger.support.FailsafeLogger;
|
||||
|
||||
import org.apache.log4j.Level;
|
||||
import org.slf4j.helpers.FormattingTuple;
|
||||
import org.slf4j.helpers.MessageFormatter;
|
||||
|
||||
public class Log4jLogger implements Logger {
|
||||
|
||||
|
|
@ -36,6 +38,12 @@ public class Log4jLogger implements Logger {
|
|||
logger.log(FQCN, Level.TRACE, msg, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trace(String msg, Object... arguments) {
|
||||
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
|
||||
logger.log(FQCN, Level.TRACE, ft.getMessage(), ft.getThrowable());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trace(Throwable e) {
|
||||
logger.log(FQCN, Level.TRACE, e == null ? null : e.getMessage(), e);
|
||||
|
|
@ -51,6 +59,12 @@ public class Log4jLogger implements Logger {
|
|||
logger.log(FQCN, Level.DEBUG, msg, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(String msg, Object... arguments) {
|
||||
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
|
||||
logger.log(FQCN, Level.DEBUG, ft.getMessage(), ft.getThrowable());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(Throwable e) {
|
||||
logger.log(FQCN, Level.DEBUG, e == null ? null : e.getMessage(), e);
|
||||
|
|
@ -66,6 +80,12 @@ public class Log4jLogger implements Logger {
|
|||
logger.log(FQCN, Level.INFO, msg, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(String msg, Object... arguments) {
|
||||
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
|
||||
logger.log(FQCN, Level.INFO, ft.getMessage(), ft.getThrowable());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(Throwable e) {
|
||||
logger.log(FQCN, Level.INFO, e == null ? null : e.getMessage(), e);
|
||||
|
|
@ -81,6 +101,12 @@ public class Log4jLogger implements Logger {
|
|||
logger.log(FQCN, Level.WARN, msg, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String msg, Object... arguments) {
|
||||
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
|
||||
logger.log(FQCN, Level.WARN, ft.getMessage(), ft.getThrowable());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(Throwable e) {
|
||||
logger.log(FQCN, Level.WARN, e == null ? null : e.getMessage(), e);
|
||||
|
|
@ -96,6 +122,12 @@ public class Log4jLogger implements Logger {
|
|||
logger.log(FQCN, Level.ERROR, msg, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(String msg, Object... arguments) {
|
||||
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
|
||||
logger.log(FQCN, Level.ERROR, ft.getMessage(), ft.getThrowable());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(Throwable e) {
|
||||
logger.log(FQCN, Level.ERROR, e == null ? null : e.getMessage(), e);
|
||||
|
|
|
|||
|
|
@ -31,6 +31,11 @@ public class Log4j2Logger implements Logger {
|
|||
logger.trace(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trace(String msg, Object... arguments) {
|
||||
logger.trace(msg, arguments);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trace(Throwable e) {
|
||||
logger.trace(e == null ? null : e.getMessage(), e);
|
||||
|
|
@ -46,6 +51,11 @@ public class Log4j2Logger implements Logger {
|
|||
logger.debug(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(String msg, Object... arguments) {
|
||||
logger.debug(msg, arguments);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(Throwable e) {
|
||||
logger.debug(e == null ? null : e.getMessage(), e);
|
||||
|
|
@ -61,6 +71,11 @@ public class Log4j2Logger implements Logger {
|
|||
logger.info(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(String msg, Object... arguments) {
|
||||
logger.info(msg, arguments);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(Throwable e) {
|
||||
logger.info(e == null ? null : e.getMessage(), e);
|
||||
|
|
@ -76,6 +91,11 @@ public class Log4j2Logger implements Logger {
|
|||
logger.warn(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String msg, Object... arguments) {
|
||||
logger.warn(msg, arguments);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(Throwable e) {
|
||||
logger.warn(e == null ? null : e.getMessage(), e);
|
||||
|
|
@ -91,6 +111,11 @@ public class Log4j2Logger implements Logger {
|
|||
logger.error(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(String msg, Object... arguments) {
|
||||
logger.error(msg, arguments);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(Throwable e) {
|
||||
logger.error(e == null ? null : e.getMessage(), e);
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ import org.apache.dubbo.common.logger.Level;
|
|||
import org.apache.dubbo.common.logger.Logger;
|
||||
import org.apache.dubbo.common.logger.support.FailsafeLogger;
|
||||
|
||||
import org.slf4j.helpers.FormattingTuple;
|
||||
import org.slf4j.helpers.MessageFormatter;
|
||||
import org.slf4j.spi.LocationAwareLogger;
|
||||
|
||||
public class Slf4jLogger implements Logger {
|
||||
|
|
@ -48,6 +50,16 @@ public class Slf4jLogger implements Logger {
|
|||
logger.trace(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trace(String msg, Object... arguments) {
|
||||
if (locationAwareLogger != null) {
|
||||
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
|
||||
locationAwareLogger.log(null, FQCN, LocationAwareLogger.TRACE_INT, msg, ft.getArgArray(), ft.getThrowable());
|
||||
return;
|
||||
}
|
||||
logger.trace(msg, arguments);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trace(Throwable e) {
|
||||
if (locationAwareLogger != null) {
|
||||
|
|
@ -75,6 +87,16 @@ public class Slf4jLogger implements Logger {
|
|||
logger.debug(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(String msg, Object... arguments) {
|
||||
if (locationAwareLogger != null) {
|
||||
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
|
||||
locationAwareLogger.log(null, FQCN, LocationAwareLogger.DEBUG_INT, msg, ft.getArgArray(), ft.getThrowable());
|
||||
return;
|
||||
}
|
||||
logger.debug(msg, arguments);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(Throwable e) {
|
||||
if (locationAwareLogger != null) {
|
||||
|
|
@ -102,6 +124,16 @@ public class Slf4jLogger implements Logger {
|
|||
logger.info(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(String msg, Object... arguments) {
|
||||
if (locationAwareLogger != null) {
|
||||
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
|
||||
locationAwareLogger.log(null, FQCN, LocationAwareLogger.INFO_INT, msg, ft.getArgArray(), ft.getThrowable());
|
||||
return;
|
||||
}
|
||||
logger.info(msg, arguments);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(Throwable e) {
|
||||
if (locationAwareLogger != null) {
|
||||
|
|
@ -129,6 +161,16 @@ public class Slf4jLogger implements Logger {
|
|||
logger.warn(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String msg, Object... arguments) {
|
||||
if (locationAwareLogger != null) {
|
||||
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
|
||||
locationAwareLogger.log(null, FQCN, LocationAwareLogger.WARN_INT, msg, ft.getArgArray(), ft.getThrowable());
|
||||
return;
|
||||
}
|
||||
logger.warn(msg, arguments);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(Throwable e) {
|
||||
if (locationAwareLogger != null) {
|
||||
|
|
@ -156,6 +198,16 @@ public class Slf4jLogger implements Logger {
|
|||
logger.error(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(String msg, Object... arguments) {
|
||||
if (locationAwareLogger != null) {
|
||||
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
|
||||
locationAwareLogger.log(null, FQCN, LocationAwareLogger.ERROR_INT, msg, ft.getArgArray(), ft.getThrowable());
|
||||
return;
|
||||
}
|
||||
logger.error(msg, arguments);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(Throwable e) {
|
||||
if (locationAwareLogger != null) {
|
||||
|
|
|
|||
|
|
@ -18,16 +18,22 @@
|
|||
package org.apache.dubbo.common.logger.support;
|
||||
|
||||
import org.apache.dubbo.common.Version;
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
import org.apache.dubbo.common.logger.ListenableLogger;
|
||||
import org.apache.dubbo.common.logger.LogListener;
|
||||
import org.apache.dubbo.common.logger.Logger;
|
||||
import org.apache.dubbo.common.utils.NetUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* A fail-safe (ignoring exception thrown by logger) wrapper of error type aware logger.
|
||||
*/
|
||||
public class FailsafeErrorTypeAwareLogger extends FailsafeLogger implements ErrorTypeAwareLogger {
|
||||
public class FailsafeErrorTypeAwareLogger extends FailsafeLogger implements ListenableLogger {
|
||||
|
||||
/**
|
||||
* Template address for formatting.
|
||||
|
|
@ -36,6 +42,16 @@ public class FailsafeErrorTypeAwareLogger extends FailsafeLogger implements Erro
|
|||
|
||||
private static final Pattern ERROR_CODE_PATTERN = Pattern.compile("\\d+-\\d+");
|
||||
|
||||
/**
|
||||
* Listeners that listened to all Loggers.
|
||||
*/
|
||||
private static final List<LogListener> GLOBAL_LISTENERS = Collections.synchronizedList(new ArrayList<>());
|
||||
|
||||
/**
|
||||
* Listeners that listened to this listener.
|
||||
*/
|
||||
private final AtomicReference<List<LogListener>> listeners = new AtomicReference<>();
|
||||
|
||||
public FailsafeErrorTypeAwareLogger(Logger logger) {
|
||||
super(logger);
|
||||
}
|
||||
|
|
@ -80,6 +96,7 @@ public class FailsafeErrorTypeAwareLogger extends FailsafeLogger implements Erro
|
|||
}
|
||||
|
||||
try {
|
||||
onEvent(code, msg);
|
||||
getLogger().warn(appendContextMessageWithInstructions(code, cause, extendedInformation, msg));
|
||||
} catch (Throwable t) {
|
||||
// ignored.
|
||||
|
|
@ -93,6 +110,7 @@ public class FailsafeErrorTypeAwareLogger extends FailsafeLogger implements Erro
|
|||
}
|
||||
|
||||
try {
|
||||
onEvent(code, msg);
|
||||
getLogger().warn(appendContextMessageWithInstructions(code, cause, extendedInformation, msg), e);
|
||||
} catch (Throwable t) {
|
||||
// ignored.
|
||||
|
|
@ -106,6 +124,7 @@ public class FailsafeErrorTypeAwareLogger extends FailsafeLogger implements Erro
|
|||
}
|
||||
|
||||
try {
|
||||
onEvent(code, msg);
|
||||
getLogger().error(appendContextMessageWithInstructions(code, cause, extendedInformation, msg));
|
||||
} catch (Throwable t) {
|
||||
// ignored.
|
||||
|
|
@ -119,9 +138,45 @@ public class FailsafeErrorTypeAwareLogger extends FailsafeLogger implements Erro
|
|||
}
|
||||
|
||||
try {
|
||||
onEvent(code, msg);
|
||||
getLogger().error(appendContextMessageWithInstructions(code, cause, extendedInformation, msg), e);
|
||||
} catch (Throwable t) {
|
||||
// ignored.
|
||||
}
|
||||
}
|
||||
|
||||
public static void registerGlobalListen(LogListener listener) {
|
||||
GLOBAL_LISTENERS.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerListen(LogListener listener) {
|
||||
listeners.getAndUpdate(logListeners -> {
|
||||
if (logListeners == null) {
|
||||
logListeners = Collections.synchronizedList(new ArrayList<>());
|
||||
}
|
||||
logListeners.add(listener);
|
||||
return logListeners;
|
||||
});
|
||||
}
|
||||
|
||||
private void onEvent(String code, String msg) {
|
||||
Optional.ofNullable(listeners.get()).ifPresent(
|
||||
logListeners -> logListeners.forEach(logListener -> {
|
||||
try {
|
||||
logListener.onMessage(code, msg);
|
||||
} catch (Exception e) {
|
||||
// ignored.
|
||||
}
|
||||
}));
|
||||
|
||||
GLOBAL_LISTENERS.forEach(logListener -> {
|
||||
try {
|
||||
logListener.onMessage(code, msg);
|
||||
} catch (Exception e) {
|
||||
// ignored.
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,6 +83,17 @@ public class FailsafeLogger implements Logger {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trace(String msg, Object... arguments) {
|
||||
if (disabled) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
logger.trace(appendContextMessage(msg), arguments);
|
||||
} catch (Throwable t) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(String msg, Throwable e) {
|
||||
if (disabled) {
|
||||
|
|
@ -116,6 +127,17 @@ public class FailsafeLogger implements Logger {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(String msg, Object... arguments) {
|
||||
if (disabled) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
logger.debug(appendContextMessage(msg), arguments);
|
||||
} catch (Throwable t) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(String msg, Throwable e) {
|
||||
if (disabled) {
|
||||
|
|
@ -138,6 +160,17 @@ public class FailsafeLogger implements Logger {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(String msg, Object... arguments) {
|
||||
if (disabled) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
logger.info(appendContextMessage(msg), arguments);
|
||||
} catch (Throwable t) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String msg, Throwable e) {
|
||||
if (disabled) {
|
||||
|
|
@ -160,6 +193,17 @@ public class FailsafeLogger implements Logger {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String msg, Object... arguments) {
|
||||
if (disabled) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
logger.warn(appendContextMessage(msg), arguments);
|
||||
} catch (Throwable t) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(String msg, Throwable e) {
|
||||
if (disabled) {
|
||||
|
|
@ -182,6 +226,17 @@ public class FailsafeLogger implements Logger {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(String msg, Object... arguments) {
|
||||
if (disabled) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
logger.error(appendContextMessage(msg), arguments);
|
||||
} catch (Throwable t) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(Throwable e) {
|
||||
if (disabled) {
|
||||
|
|
|
|||
|
|
@ -132,6 +132,39 @@ public interface AnnotationUtils {
|
|||
return getAttribute(annotation, "value");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute from the specified {@link Annotation annotation}
|
||||
*
|
||||
* @param annotation the specified {@link Annotation annotation}
|
||||
* @param attributeNames the multiply attribute name arrays
|
||||
* @param <T> the type of attribute
|
||||
* @return the attribute value
|
||||
* @throws IllegalArgumentException If the attribute name can't be found
|
||||
*/
|
||||
static <T> T getAttribute(Annotation annotation, String... attributeNames) throws IllegalArgumentException {
|
||||
if (attributeNames == null || attributeNames.length == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (String attributeName : attributeNames) {
|
||||
T attribute = getAttribute(annotation, attributeName);
|
||||
|
||||
if (attribute == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// exclude string attribute default is empty
|
||||
if ((attribute instanceof String) && ((String) attribute).length() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return attribute;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link Annotation} from the specified {@link AnnotatedElement the annotated element} and
|
||||
* {@link Annotation annotation} class name
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
package org.apache.dubbo.common.utils;
|
||||
|
||||
import org.apache.dubbo.common.aot.NativeDetector;
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.resource.GlobalResourcesRepository;
|
||||
|
|
@ -78,7 +79,7 @@ public class ClassLoaderResourceLoader {
|
|||
Enumeration<URL> urls;
|
||||
try {
|
||||
urls = currentClassLoader.getResources(fileName);
|
||||
boolean isNative = NativeUtils.isNative();
|
||||
boolean isNative = NativeDetector.inNativeImage();
|
||||
if (urls != null) {
|
||||
while (urls.hasMoreElements()) {
|
||||
URL url = urls.nextElement();
|
||||
|
|
|
|||
|
|
@ -212,6 +212,20 @@ public class ClassUtils {
|
|||
return forName(name, getClassLoader());
|
||||
}
|
||||
|
||||
/**
|
||||
* find class and don`t expect to throw exception
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
public static Class<?> forNameAndTryCatch(String name) {
|
||||
try {
|
||||
return forName(name, getClassLoader());
|
||||
} catch (Throwable e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Replacement for <code>Class.forName()</code> that also returns Class
|
||||
* instances for primitives (like "int") and array class names (like
|
||||
|
|
|
|||
|
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
* 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.common.utils;
|
||||
|
||||
import org.apache.dubbo.common.logger.Logger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.GenericArrayType;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.TypeVariable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
public class JsonCompatibilityUtil {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(JsonCompatibilityUtil.class);
|
||||
|
||||
private static final Set<String> unsupportedClasses = new HashSet<>(Arrays.asList("java.util.Optional", "java.util.Calendar", "java.util.Iterator", "java.io.InputStream", "java.io.OutputStream"));
|
||||
|
||||
|
||||
/**
|
||||
* Determine whether a Class can be serialized by JSON.
|
||||
* @param clazz Incoming Class.
|
||||
* @return If a Class can be serialized by JSON, return true;
|
||||
* else return false.
|
||||
*/
|
||||
public static boolean checkClassCompatibility(Class<?> clazz) {
|
||||
Method[] methods = clazz.getDeclaredMethods();
|
||||
|
||||
boolean result;
|
||||
|
||||
for (Method method : methods) {
|
||||
result = checkMethodCompatibility(method);
|
||||
if (!result) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determine whether a Method can be serialized by JSON.
|
||||
* @param method Incoming Method.
|
||||
* @return If a Method can be serialized by JSON, return true;
|
||||
* else return false.
|
||||
*/
|
||||
public static boolean checkMethodCompatibility(Method method) {
|
||||
|
||||
boolean result;
|
||||
|
||||
Type[] types = method.getGenericParameterTypes();
|
||||
List<Type> typeList = new ArrayList<>(Arrays.asList(types));
|
||||
Type returnType = method.getGenericReturnType();
|
||||
typeList.add(returnType);
|
||||
for (Type type : typeList) {
|
||||
result = checkType(type);
|
||||
if (!result) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get unsupported methods.
|
||||
* @param clazz
|
||||
* @return If there are unsupported methods, return them by List;
|
||||
* else return null.
|
||||
*/
|
||||
public static List<String> getUnsupportedMethods(Class<?> clazz) {
|
||||
ArrayList<String> unsupportedMethods = new ArrayList<>();
|
||||
|
||||
Method[] methods = clazz.getDeclaredMethods();
|
||||
|
||||
for (Method method : methods) {
|
||||
if (!checkMethodCompatibility(method)) {
|
||||
unsupportedMethods.add(method.getName());
|
||||
}
|
||||
}
|
||||
|
||||
return unsupportedMethods.size() > 0 ? unsupportedMethods : null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determine whether a Type can be serialized by JSON.
|
||||
* @param classType Incoming Type.
|
||||
* @return If a Type can be serialized by JSON, return true;
|
||||
* else return false.
|
||||
*/
|
||||
private static boolean checkType(Type classType) {
|
||||
|
||||
boolean result;
|
||||
|
||||
if (classType instanceof TypeVariable) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (classType instanceof ParameterizedType) {
|
||||
|
||||
Type[] types = ((ParameterizedType) classType).getActualTypeArguments();
|
||||
List<Type> typeList = new ArrayList<>(Arrays.asList(types));
|
||||
classType = ((ParameterizedType) classType).getRawType();
|
||||
typeList.add(classType);
|
||||
for (Type type : typeList) {
|
||||
result = checkType(type);
|
||||
if (!result) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else if (classType instanceof GenericArrayType) {
|
||||
Type componentType = ((GenericArrayType) classType).getGenericComponentType();
|
||||
result = checkType(componentType);
|
||||
return result;
|
||||
} else if (classType instanceof Class<?> ) {
|
||||
Class<?> clazz = (Class<?>) classType;
|
||||
|
||||
String className = clazz.getName();
|
||||
|
||||
if (clazz.isArray()) {
|
||||
Type componentType = clazz.getComponentType();
|
||||
result = checkType(componentType);
|
||||
return result;
|
||||
} else if (clazz.isPrimitive()) {
|
||||
// deal with case of basic byte
|
||||
return !unsupportedClasses.contains(className);
|
||||
} else if (className.startsWith("java") || className.startsWith("javax")) {
|
||||
return !unsupportedClasses.contains(className);
|
||||
} else {
|
||||
// deal with case of interface
|
||||
if (clazz.isInterface()) {
|
||||
return false;
|
||||
}
|
||||
// deal with case of abstract
|
||||
if (Modifier.isAbstract(clazz.getModifiers())) {
|
||||
return false;
|
||||
}
|
||||
if (clazz.isEnum()) {
|
||||
return true;
|
||||
}
|
||||
// deal with case of record
|
||||
// if (clazz.isRecord()) {
|
||||
// return false;
|
||||
// }
|
||||
// deal with field one by one
|
||||
for (Field field : clazz.getDeclaredFields()) {
|
||||
Type type = field.getGenericType();
|
||||
Class<?> fieldClass = field.getType();
|
||||
result = checkType(type);
|
||||
if (!result) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
package org.apache.dubbo.common.utils;
|
||||
|
||||
import org.apache.dubbo.common.constants.CommonConstants;
|
||||
import org.apache.dubbo.common.json.JSON;
|
||||
import org.apache.dubbo.common.json.JsonUtil;
|
||||
import org.apache.dubbo.common.json.impl.FastJson2Impl;
|
||||
import org.apache.dubbo.common.json.impl.FastJsonImpl;
|
||||
import org.apache.dubbo.common.json.impl.GsonImpl;
|
||||
|
|
@ -29,17 +29,16 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
public class JsonUtils {
|
||||
private static volatile JsonUtil jsonUtil;
|
||||
|
||||
private static volatile JSON json;
|
||||
|
||||
protected static JSON getJson() {
|
||||
if (json == null) {
|
||||
protected static JsonUtil getJson() {
|
||||
if (jsonUtil == null) {
|
||||
synchronized (JsonUtils.class) {
|
||||
if (json == null) {
|
||||
if (jsonUtil == null) {
|
||||
String preferJsonFrameworkName = System.getProperty(CommonConstants.PREFER_JSON_FRAMEWORK_NAME);
|
||||
if (StringUtils.isNotEmpty(preferJsonFrameworkName)) {
|
||||
try {
|
||||
JSON instance = null;
|
||||
JsonUtil instance = null;
|
||||
switch (preferJsonFrameworkName) {
|
||||
case "fastjson2":
|
||||
instance = new FastJson2Impl();
|
||||
|
|
@ -55,23 +54,23 @@ public class JsonUtils {
|
|||
break;
|
||||
}
|
||||
if (instance != null && instance.isSupport()) {
|
||||
json = instance;
|
||||
jsonUtil = instance;
|
||||
}
|
||||
} catch (Throwable ignore) {
|
||||
|
||||
}
|
||||
}
|
||||
if (json == null) {
|
||||
List<Class<? extends JSON>> jsonClasses = Arrays.asList(
|
||||
if (jsonUtil == null) {
|
||||
List<Class<? extends JsonUtil>> jsonClasses = Arrays.asList(
|
||||
FastJson2Impl.class,
|
||||
FastJsonImpl.class,
|
||||
GsonImpl.class,
|
||||
JacksonImpl.class);
|
||||
for (Class<? extends JSON> jsonClass : jsonClasses) {
|
||||
for (Class<? extends JsonUtil> jsonClass : jsonClasses) {
|
||||
try {
|
||||
JSON instance = jsonClass.getConstructor().newInstance();
|
||||
JsonUtil instance = jsonClass.getConstructor().newInstance();
|
||||
if (instance.isSupport()) {
|
||||
json = instance;
|
||||
jsonUtil = instance;
|
||||
break;
|
||||
}
|
||||
} catch (Throwable ignore) {
|
||||
|
|
@ -79,22 +78,22 @@ public class JsonUtils {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (json == null) {
|
||||
if (jsonUtil == null) {
|
||||
throw new IllegalStateException("Dubbo unable to find out any json framework (e.g. fastjson2, fastjson, gson, jackson) from jvm env. " +
|
||||
"Please import at least one json framework.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return json;
|
||||
return jsonUtil;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated for uts only
|
||||
*/
|
||||
@Deprecated
|
||||
protected static void setJson(JSON json) {
|
||||
JsonUtils.json = json;
|
||||
protected static void setJson(JsonUtil json) {
|
||||
JsonUtils.jsonUtil = json;
|
||||
}
|
||||
|
||||
public static <T> T toJavaObject(String json, Type type) {
|
||||
|
|
|
|||
|
|
@ -856,6 +856,23 @@ public final class StringUtils {
|
|||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String join(final Object[] array, final char delimiter, final int startIndex, final int endIndex) {
|
||||
if (ArrayUtils.isEmpty(array)) {
|
||||
return EMPTY_STRING;
|
||||
}
|
||||
if (endIndex - startIndex <= 0) {
|
||||
return EMPTY_STRING;
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = startIndex; i < endIndex; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(delimiter);
|
||||
}
|
||||
sb.append(array[i]);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* parse key-value pair.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ package org.apache.dubbo.config;
|
|||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.Version;
|
||||
import org.apache.dubbo.common.aot.NativeDetector;
|
||||
import org.apache.dubbo.common.compiler.support.AdaptiveCompiler;
|
||||
import org.apache.dubbo.common.config.ConfigurationUtils;
|
||||
import org.apache.dubbo.common.config.Environment;
|
||||
import org.apache.dubbo.common.config.InmemoryConfiguration;
|
||||
|
|
@ -47,7 +49,6 @@ import java.util.stream.Collectors;
|
|||
import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SPLIT_PATTERN;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_VERSION_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.INVOKER_LISTENER_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.NATIVE;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.PID_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.REFERENCE_FILTER_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.RELEASE_KEY;
|
||||
|
|
@ -55,6 +56,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.TAG_KEY;
|
|||
import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_NO_METHOD_FOUND;
|
||||
import static org.apache.dubbo.common.constants.MetricsConstants.PROTOCOL_PROMETHEUS;
|
||||
import static org.apache.dubbo.config.Constants.DEFAULT_NATIVE_PROXY;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -255,7 +257,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
for (RegistryConfig registryConfig : registries) {
|
||||
if (!registryConfig.isValid()) {
|
||||
throw new IllegalStateException("No registry config found or it's not a valid config! " +
|
||||
"The registry config is: " + registryConfig);
|
||||
"The registry config is: " + registryConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -293,8 +295,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
* @return
|
||||
*/
|
||||
protected String[] methods(Class<?> interfaceClass) {
|
||||
boolean isNative = getEnvironment().getConfiguration().getBoolean(NATIVE, false);
|
||||
if (isNative) {
|
||||
if (NativeDetector.inNativeImage()) {
|
||||
return Arrays.stream(interfaceClass.getMethods()).map(Method::getName).toArray(String[]::new);
|
||||
} else {
|
||||
return ClassUtils.getMethodNames(interfaceClass);
|
||||
|
|
@ -344,7 +345,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
java.lang.reflect.Parameter[] arguments = method.getParameters();
|
||||
for (int i = 0; i < arguments.length; i++) {
|
||||
if (getArgumentByIndex(methodConfig, i) == null &&
|
||||
hasArgumentConfigProps(configProperties, methodConfig.getName(), i)) {
|
||||
hasArgumentConfigProps(configProperties, methodConfig.getName(), i)) {
|
||||
|
||||
ArgumentConfig argumentConfig = new ArgumentConfig();
|
||||
argumentConfig.setIndex(i);
|
||||
|
|
@ -359,7 +360,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
if (methodConfigs != null && methodConfigs.size() > 0) {
|
||||
// whether ignore invalid method config
|
||||
Object ignoreInvalidMethodConfigVal = getEnvironment().getConfiguration()
|
||||
.getProperty(ConfigKeys.DUBBO_CONFIG_IGNORE_INVALID_METHOD_CONFIG, "false");
|
||||
.getProperty(ConfigKeys.DUBBO_CONFIG_IGNORE_INVALID_METHOD_CONFIG, "false");
|
||||
boolean ignoreInvalidMethodConfig = Boolean.parseBoolean(ignoreInvalidMethodConfigVal.toString());
|
||||
|
||||
Class<?> finalInterfaceClass = interfaceClass;
|
||||
|
|
@ -390,8 +391,8 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
String methodName = methodConfig.getName();
|
||||
if (StringUtils.isEmpty(methodName)) {
|
||||
String msg = "<dubbo:method> name attribute is required! Please check: " +
|
||||
"<dubbo:service interface=\"" + interfaceName + "\" ... >" +
|
||||
"<dubbo:method name=\"\" ... /></<dubbo:reference>";
|
||||
"<dubbo:service interface=\"" + interfaceName + "\" ... >" +
|
||||
"<dubbo:method name=\"\" ... /></<dubbo:reference>";
|
||||
if (ignoreInvalidMethodConfig) {
|
||||
logger.warn(CONFIG_NO_METHOD_FOUND, "", "", msg);
|
||||
return false;
|
||||
|
|
@ -403,7 +404,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
boolean hasMethod = Arrays.stream(interfaceClass.getMethods()).anyMatch(method -> method.getName().equals(methodName));
|
||||
if (!hasMethod) {
|
||||
String msg = "Found invalid method config, the interface " + interfaceClass.getName() + " not found method \""
|
||||
+ methodName + "\" : [" + methodConfig + "]";
|
||||
+ methodName + "\" : [" + methodConfig + "]";
|
||||
if (ignoreInvalidMethodConfig) {
|
||||
logger.warn(CONFIG_NO_METHOD_FOUND, "", "", msg);
|
||||
return false;
|
||||
|
|
@ -465,7 +466,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
private void verifyStubAndLocal(String className, String label, Class<?> interfaceClass) {
|
||||
if (ConfigUtils.isNotEmpty(className)) {
|
||||
Class<?> localClass = ConfigUtils.isDefault(className) ?
|
||||
ReflectUtils.forName(interfaceClass.getName() + label) : ReflectUtils.forName(className);
|
||||
ReflectUtils.forName(interfaceClass.getName() + label) : ReflectUtils.forName(className);
|
||||
verify(interfaceClass, localClass);
|
||||
}
|
||||
}
|
||||
|
|
@ -473,7 +474,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
private void verify(Class<?> interfaceClass, Class<?> localClass) {
|
||||
if (!interfaceClass.isAssignableFrom(localClass)) {
|
||||
throw new IllegalStateException("The local implementation class " + localClass.getName() +
|
||||
" not implement interface " + interfaceClass.getName());
|
||||
" not implement interface " + interfaceClass.getName());
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
@ -481,7 +482,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
ReflectUtils.findConstructor(localClass, interfaceClass);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new IllegalStateException("No such constructor \"public " + localClass.getSimpleName() +
|
||||
"(" + interfaceClass.getName() + ")\" in local implementation class " + localClass.getName());
|
||||
"(" + interfaceClass.getName() + ")\" in local implementation class " + localClass.getName());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -613,11 +614,20 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
|
|||
}
|
||||
|
||||
public String getProxy() {
|
||||
return proxy;
|
||||
if (NativeDetector.inNativeImage()) {
|
||||
return DEFAULT_NATIVE_PROXY;
|
||||
} else {
|
||||
return this.proxy;
|
||||
}
|
||||
}
|
||||
|
||||
public void setProxy(String proxy) {
|
||||
this.proxy = proxy;
|
||||
if (NativeDetector.inNativeImage()) {
|
||||
this.proxy = DEFAULT_NATIVE_PROXY;
|
||||
AdaptiveCompiler.setDefaultCompiler(DEFAULT_NATIVE_PROXY);
|
||||
} else {
|
||||
this.proxy = proxy;
|
||||
}
|
||||
}
|
||||
|
||||
public Integer getConnections() {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
package org.apache.dubbo.config;
|
||||
|
||||
import org.apache.dubbo.common.aot.NativeDetector;
|
||||
import org.apache.dubbo.common.compiler.support.AdaptiveCompiler;
|
||||
import org.apache.dubbo.common.infra.InfraAdapter;
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
|
|
@ -32,6 +33,7 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_PROTOCOL_KEY;
|
||||
|
|
@ -67,6 +69,7 @@ import static org.apache.dubbo.common.constants.QosConstants.QOS_PORT;
|
|||
import static org.apache.dubbo.common.constants.QosConstants.QOS_PORT_COMPATIBLE;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.ENABLE_EMPTY_PROTECTION_KEY;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTER_MODE_KEY;
|
||||
import static org.apache.dubbo.config.Constants.DEFAULT_NATIVE_COMPILER;
|
||||
import static org.apache.dubbo.config.Constants.DEVELOPMENT_ENVIRONMENT;
|
||||
import static org.apache.dubbo.config.Constants.PRODUCTION_ENVIRONMENT;
|
||||
import static org.apache.dubbo.config.Constants.TEST_ENVIRONMENT;
|
||||
|
|
@ -81,6 +84,8 @@ public class ApplicationConfig extends AbstractConfig {
|
|||
|
||||
private static final long serialVersionUID = 5508512956753757169L;
|
||||
|
||||
private static final String DEFAULT_NAME_PREFIX = "DUBBO_APP_";
|
||||
|
||||
/**
|
||||
* Application name
|
||||
*/
|
||||
|
|
@ -281,7 +286,7 @@ public class ApplicationConfig extends AbstractConfig {
|
|||
try {
|
||||
hostname = InetAddress.getLocalHost().getHostName();
|
||||
} catch (UnknownHostException e) {
|
||||
LOGGER.warn(COMMON_UNEXPECTED_EXCEPTION,"","","Failed to get the hostname of current instance.", e);
|
||||
LOGGER.warn(COMMON_UNEXPECTED_EXCEPTION, "", "", "Failed to get the hostname of current instance.", e);
|
||||
hostname = "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
|
@ -341,15 +346,15 @@ public class ApplicationConfig extends AbstractConfig {
|
|||
|
||||
public void setEnvironment(String environment) {
|
||||
if (environment != null && !(DEVELOPMENT_ENVIRONMENT.equals(environment)
|
||||
|| TEST_ENVIRONMENT.equals(environment)
|
||||
|| PRODUCTION_ENVIRONMENT.equals(environment))) {
|
||||
|| TEST_ENVIRONMENT.equals(environment)
|
||||
|| PRODUCTION_ENVIRONMENT.equals(environment))) {
|
||||
|
||||
throw new IllegalStateException(String.format("Unsupported environment: %s, only support %s/%s/%s, default is %s.",
|
||||
environment,
|
||||
DEVELOPMENT_ENVIRONMENT,
|
||||
TEST_ENVIRONMENT,
|
||||
PRODUCTION_ENVIRONMENT,
|
||||
PRODUCTION_ENVIRONMENT));
|
||||
environment,
|
||||
DEVELOPMENT_ENVIRONMENT,
|
||||
TEST_ENVIRONMENT,
|
||||
PRODUCTION_ENVIRONMENT,
|
||||
PRODUCTION_ENVIRONMENT));
|
||||
}
|
||||
this.environment = environment;
|
||||
}
|
||||
|
|
@ -395,12 +400,22 @@ public class ApplicationConfig extends AbstractConfig {
|
|||
}
|
||||
|
||||
public String getCompiler() {
|
||||
return compiler;
|
||||
if (NativeDetector.inNativeImage()) {
|
||||
return DEFAULT_NATIVE_COMPILER;
|
||||
} else {
|
||||
return compiler;
|
||||
}
|
||||
}
|
||||
|
||||
public void setCompiler(String compiler) {
|
||||
this.compiler = compiler;
|
||||
AdaptiveCompiler.setDefaultCompiler(compiler);
|
||||
|
||||
if (NativeDetector.inNativeImage()) {
|
||||
this.compiler = DEFAULT_NATIVE_COMPILER;
|
||||
AdaptiveCompiler.setDefaultCompiler(DEFAULT_NATIVE_COMPILER);
|
||||
} else {
|
||||
this.compiler = compiler;
|
||||
AdaptiveCompiler.setDefaultCompiler(compiler);
|
||||
}
|
||||
}
|
||||
|
||||
public String getLogger() {
|
||||
|
|
@ -750,6 +765,12 @@ public class ApplicationConfig extends AbstractConfig {
|
|||
public void refresh() {
|
||||
super.refresh();
|
||||
appendEnvironmentProperties();
|
||||
if (StringUtils.isEmpty(getName())) {
|
||||
String defaultName = DEFAULT_NAME_PREFIX + UUID.randomUUID();
|
||||
this.setName(defaultName);
|
||||
LOGGER.info("No application name was set, '" + defaultName + "' will be used as the default application name," +
|
||||
" it's highly recommended to set a unique and customized name for it can be critical for some service governance features.");
|
||||
}
|
||||
}
|
||||
|
||||
private void appendEnvironmentProperties() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import org.apache.dubbo.common.extension.ExtensionScope;
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
|
||||
/**
|
||||
* it will be call when reference or service config refresh
|
||||
*/
|
||||
|
||||
@SPI(scope = ExtensionScope.MODULE)
|
||||
public interface CommonConfigPostProcessor {
|
||||
|
||||
default void postProcessReferConfig(ReferenceConfigBase referenceConfig) {
|
||||
|
||||
}
|
||||
|
||||
default void postProcessServiceConfig(ServiceConfigBase serviceConfig) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -152,4 +152,8 @@ public interface Constants {
|
|||
String CLIENT_THREAD_POOL_NAME = "DubboClientHandler";
|
||||
|
||||
String REST_PROTOCOL="rest";
|
||||
|
||||
String DEFAULT_NATIVE_COMPILER="jdk";
|
||||
|
||||
String DEFAULT_NATIVE_PROXY="jdk";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,6 +61,11 @@ public class MetricsConfig extends AbstractConfig {
|
|||
*/
|
||||
private Boolean exportMetricsService;
|
||||
|
||||
/**
|
||||
* Enable netty metrics.
|
||||
*/
|
||||
private Boolean enableNetty;
|
||||
|
||||
/**
|
||||
* Enable metrics init.
|
||||
*/
|
||||
|
|
@ -263,4 +268,12 @@ public class MetricsConfig extends AbstractConfig {
|
|||
public void setEnableRpc(Boolean enableRpc) {
|
||||
this.enableRpc = enableRpc;
|
||||
}
|
||||
|
||||
public Boolean getEnableNetty() {
|
||||
return enableNetty;
|
||||
}
|
||||
|
||||
public void setEnableNetty(Boolean enableNetty) {
|
||||
this.enableNetty = enableNetty;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import java.util.Map;
|
|||
import java.util.Optional;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_PROTOCOL;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.JSON_CHECK_LEVEL_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.SSL_ENABLED_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.THREAD_POOL_EXHAUSTED_LISTENERS_KEY;
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_UNEXPECTED_EXCEPTION;
|
||||
|
|
@ -229,6 +230,8 @@ public class ProtocolConfig extends AbstractConfig {
|
|||
*/
|
||||
private String extProtocol;
|
||||
|
||||
private String jsonCheckLevel;
|
||||
|
||||
public ProtocolConfig() {
|
||||
}
|
||||
|
||||
|
|
@ -331,6 +334,15 @@ public class ProtocolConfig extends AbstractConfig {
|
|||
this.threadname = threadname;
|
||||
}
|
||||
|
||||
@Parameter(key = JSON_CHECK_LEVEL_KEY)
|
||||
public String getJsonCheckLevel() {
|
||||
return jsonCheckLevel;
|
||||
}
|
||||
|
||||
public void setJsonCheckLevel(String jsonCheckLevel) {
|
||||
this.jsonCheckLevel = jsonCheckLevel;
|
||||
}
|
||||
|
||||
@Parameter(key = THREAD_POOL_EXHAUSTED_LISTENERS_KEY)
|
||||
public String getThreadPoolExhaustedListeners() {
|
||||
return threadPoolExhaustedListeners;
|
||||
|
|
|
|||
|
|
@ -39,6 +39,19 @@ public class BaggageConfig implements Serializable {
|
|||
*/
|
||||
private List<String> remoteFields = new ArrayList<>();
|
||||
|
||||
public BaggageConfig() {
|
||||
}
|
||||
|
||||
public BaggageConfig(Boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public BaggageConfig(Boolean enabled, Correlation correlation, List<String> remoteFields) {
|
||||
this.enabled = enabled;
|
||||
this.correlation = correlation;
|
||||
this.remoteFields = remoteFields;
|
||||
}
|
||||
|
||||
public Boolean getEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
|
@ -76,6 +89,18 @@ public class BaggageConfig implements Serializable {
|
|||
*/
|
||||
private List<String> fields = new ArrayList<>();
|
||||
|
||||
public Correlation() {
|
||||
}
|
||||
|
||||
public Correlation(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public Correlation(boolean enabled, List<String> fields) {
|
||||
this.enabled = enabled;
|
||||
this.fields = fields;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,15 +56,28 @@ public class ExporterConfig implements Serializable {
|
|||
private String endpoint;
|
||||
|
||||
/**
|
||||
* Connection timeout for requests to Zipkin.
|
||||
* Connection timeout for requests to Zipkin. (seconds)
|
||||
*/
|
||||
private Duration connectTimeout = Duration.ofSeconds(1);
|
||||
|
||||
/**
|
||||
* Read timeout for requests to Zipkin.
|
||||
* Read timeout for requests to Zipkin. (seconds)
|
||||
*/
|
||||
private Duration readTimeout = Duration.ofSeconds(10);
|
||||
|
||||
public ZipkinConfig() {
|
||||
}
|
||||
|
||||
public ZipkinConfig(String endpoint) {
|
||||
this.endpoint = endpoint;
|
||||
}
|
||||
|
||||
public ZipkinConfig(String endpoint, Duration connectTimeout, Duration readTimeout) {
|
||||
this.endpoint = endpoint;
|
||||
this.connectTimeout = connectTimeout;
|
||||
this.readTimeout = readTimeout;
|
||||
}
|
||||
|
||||
public String getEndpoint() {
|
||||
return endpoint;
|
||||
}
|
||||
|
|
@ -98,7 +111,7 @@ public class ExporterConfig implements Serializable {
|
|||
private String endpoint;
|
||||
|
||||
/**
|
||||
* The maximum time to wait for the collector to process an exported batch of spans.
|
||||
* The maximum time to wait for the collector to process an exported batch of spans. (seconds)
|
||||
*/
|
||||
private Duration timeout = Duration.ofSeconds(10);
|
||||
|
||||
|
|
@ -110,6 +123,24 @@ public class ExporterConfig implements Serializable {
|
|||
|
||||
private Map<String, String> headers = new HashMap<>();
|
||||
|
||||
public OtlpConfig() {
|
||||
}
|
||||
|
||||
public OtlpConfig(String endpoint) {
|
||||
this.endpoint = endpoint;
|
||||
}
|
||||
|
||||
public OtlpConfig(String endpoint, Duration timeout) {
|
||||
this.endpoint = endpoint;
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
public OtlpConfig(String endpoint, Duration timeout, String compressionMethod) {
|
||||
this.endpoint = endpoint;
|
||||
this.timeout = timeout;
|
||||
this.compressionMethod = compressionMethod;
|
||||
}
|
||||
|
||||
public String getEndpoint() {
|
||||
return endpoint;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,13 @@ public class PropagationConfig implements Serializable {
|
|||
*/
|
||||
private String type = W3C;
|
||||
|
||||
public PropagationConfig() {
|
||||
}
|
||||
|
||||
public PropagationConfig(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,13 @@ public class SamplingConfig implements Serializable {
|
|||
*/
|
||||
private float probability = 0.10f;
|
||||
|
||||
public SamplingConfig() {
|
||||
}
|
||||
|
||||
public SamplingConfig(float probability) {
|
||||
this.probability = probability;
|
||||
}
|
||||
|
||||
public float getProbability() {
|
||||
return this.probability;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,2 +1 @@
|
|||
nop=org.apache.dubbo.common.config.configcenter.nop.NopDynamicConfigurationFactory
|
||||
file=org.apache.dubbo.common.config.configcenter.file.FileSystemDynamicConfigurationFactory
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
fastjson2=org.apache.dubbo.common.json.impl.FastJson2Impl
|
||||
fastjson=org.apache.dubbo.common.json.impl.FastJsonImpl
|
||||
gson=org.apache.dubbo.common.json.impl.GsonImpl
|
||||
jackson=org.apache.dubbo.common.json.impl.JacksonImpl
|
||||
|
|
@ -21,20 +21,22 @@ import org.junit.jupiter.api.Test;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Map;
|
||||
|
||||
class FileCacheStoreFactoryTest {
|
||||
|
||||
@Test
|
||||
void testSafeName() throws URISyntaxException {
|
||||
FileCacheStore store1 = FileCacheStoreFactory.getInstance(getDirectoryOfClassPath(), "../../../dubbo");
|
||||
Assertions.assertEquals(getDirectoryOfClassPath() + "..%002f..%002f..%002fdubbo.dubbo.cache", store1.getCacheFilePath());
|
||||
Assertions.assertEquals(getDirectoryOfClassPath() + "..%002f..%002f..%002fdubbo.dubbo.cache", getCacheFilePath(store1));
|
||||
store1.destroy();
|
||||
|
||||
FileCacheStore store2 = FileCacheStoreFactory.getInstance(getDirectoryOfClassPath(), "../../../中文");
|
||||
Assertions.assertEquals(getDirectoryOfClassPath() + "..%002f..%002f..%002f%4e2d%6587.dubbo.cache", store2.getCacheFilePath());
|
||||
Assertions.assertEquals(getDirectoryOfClassPath() + "..%002f..%002f..%002f%4e2d%6587.dubbo.cache", getCacheFilePath(store2));
|
||||
store2.destroy();
|
||||
}
|
||||
|
||||
|
|
@ -49,18 +51,20 @@ class FileCacheStoreFactoryTest {
|
|||
|
||||
@Test
|
||||
void testCacheContains() throws URISyntaxException {
|
||||
FileCacheStore store1 = FileCacheStoreFactory.getInstance(getDirectoryOfClassPath(), "testCacheContains");
|
||||
Assertions.assertNotNull(store1.getCacheFilePath());
|
||||
String classPath = getDirectoryOfClassPath();
|
||||
|
||||
FileCacheStoreFactory.getCacheMap().remove(store1.getCacheFilePath());
|
||||
FileCacheStore store2 = FileCacheStoreFactory.getInstance(getDirectoryOfClassPath(), "testCacheContains");
|
||||
FileCacheStore store1 = FileCacheStoreFactory.getInstance(classPath, "testCacheContains");
|
||||
Assertions.assertNotNull(getCacheFilePath(store1));
|
||||
|
||||
getCacheMap().remove(getCacheFilePath(store1));
|
||||
FileCacheStore store2 = FileCacheStoreFactory.getInstance(classPath, "testCacheContains");
|
||||
Assertions.assertEquals(FileCacheStore.Empty.class, store2.getClass());
|
||||
|
||||
store1.destroy();
|
||||
store2.destroy();
|
||||
|
||||
FileCacheStore store3 = FileCacheStoreFactory.getInstance(getDirectoryOfClassPath(), "testCacheContains");
|
||||
Assertions.assertNotNull(store3.getCacheFilePath());
|
||||
FileCacheStore store3 = FileCacheStoreFactory.getInstance(classPath, "testCacheContains");
|
||||
Assertions.assertNotNull(getCacheFilePath(store3));
|
||||
store3.destroy();
|
||||
}
|
||||
|
||||
|
|
@ -71,4 +75,39 @@ class FileCacheStoreFactoryTest {
|
|||
String directoryPath = path.substring(0, index);
|
||||
return directoryPath;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ReflectFieldCache {
|
||||
Field cacheMapField;
|
||||
|
||||
Field cacheFilePathField;
|
||||
}
|
||||
|
||||
private static final ReflectFieldCache REFLECT_FIELD_CACHE = new ReflectFieldCache();
|
||||
|
||||
private Map<String, FileCacheStore> getCacheMap() {
|
||||
|
||||
try {
|
||||
if (REFLECT_FIELD_CACHE.cacheMapField == null) {
|
||||
REFLECT_FIELD_CACHE.cacheMapField = FileCacheStoreFactory.class.getDeclaredField("cacheMap");
|
||||
REFLECT_FIELD_CACHE.cacheMapField.setAccessible(true);
|
||||
}
|
||||
|
||||
return (Map<String, FileCacheStore>) REFLECT_FIELD_CACHE.cacheMapField.get(null);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private String getCacheFilePath(FileCacheStore cacheStore) {
|
||||
try {
|
||||
if (REFLECT_FIELD_CACHE.cacheFilePathField == null) {
|
||||
REFLECT_FIELD_CACHE.cacheFilePathField = FileCacheStore.class.getDeclaredField("cacheFilePath");
|
||||
REFLECT_FIELD_CACHE.cacheFilePathField.setAccessible(true);
|
||||
}
|
||||
|
||||
return (String) REFLECT_FIELD_CACHE.cacheFilePathField.get(cacheStore);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,13 @@ class LoggerTest {
|
|||
logger.warn("warn");
|
||||
logger.info("info");
|
||||
logger.debug("debug");
|
||||
logger.trace("info");
|
||||
logger.trace("trace");
|
||||
|
||||
logger.error("error:{}", "arg1");
|
||||
logger.warn("warn:{}", "arg1");
|
||||
logger.info("info:{}", "arg1");
|
||||
logger.debug("debug:{}", "arg1");
|
||||
logger.trace("trace:{}", "arg1");
|
||||
|
||||
logger.error(new Exception("error"));
|
||||
logger.warn(new Exception("warn"));
|
||||
|
|
@ -69,6 +75,12 @@ class LoggerTest {
|
|||
logger.info("info", new Exception("info"));
|
||||
logger.debug("debug", new Exception("debug"));
|
||||
logger.trace("trace", new Exception("trace"));
|
||||
|
||||
logger.error("error:{}","arg1", new Exception("error"));
|
||||
logger.warn("warn:{}", "arg1", new Exception("warn"));
|
||||
logger.info("info:{}", "arg1", new Exception("info"));
|
||||
logger.debug("debug:{}", "arg1", new Exception("debug"));
|
||||
logger.trace("trace:{}", "arg1", new Exception("trace"));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
|
|
|
|||
|
|
@ -19,10 +19,7 @@ package org.apache.dubbo.common.logger.slf4j;
|
|||
import org.junit.jupiter.api.Test;
|
||||
import org.slf4j.spi.LocationAwareLogger;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.isNull;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.internal.verification.VerificationModeFactory.times;
|
||||
|
|
@ -34,14 +31,22 @@ class Slf4jLoggerTest {
|
|||
Slf4jLogger logger = new Slf4jLogger(locationAwareLogger);
|
||||
|
||||
logger.error("error");
|
||||
|
||||
logger.warn("warn");
|
||||
logger.info("info");
|
||||
logger.debug("debug");
|
||||
logger.trace("info");
|
||||
|
||||
verify(locationAwareLogger, times(5)).log(isNull(), anyString(),
|
||||
anyInt(), anyString(), isNull(), isNull());
|
||||
anyInt(), anyString(), isNull(), isNull());
|
||||
|
||||
logger.error("error:{}", "arg1");
|
||||
logger.warn("warn:{}", "arg1");
|
||||
logger.info("info:{}", "arg1");
|
||||
logger.debug("debug:{}", "arg1");
|
||||
logger.trace("info:{}", "arg1");
|
||||
|
||||
verify(locationAwareLogger, times(5)).log(isNull(), anyString(),
|
||||
anyInt(), anyString(), eq(new String[]{"arg1"}), isNull());
|
||||
|
||||
logger.error(new Exception("error"));
|
||||
logger.warn(new Exception("warn"));
|
||||
|
|
@ -56,6 +61,15 @@ class Slf4jLoggerTest {
|
|||
logger.trace("trace", new Exception("trace"));
|
||||
|
||||
verify(locationAwareLogger, times(10)).log(isNull(), anyString(),
|
||||
anyInt(), anyString(), isNull(), any(Throwable.class));
|
||||
anyInt(), anyString(), isNull(), any(Throwable.class));
|
||||
|
||||
logger.error("error:{}","arg1", new Exception("error"));
|
||||
logger.warn("warn:{}", "arg1", new Exception("warn"));
|
||||
logger.info("info:{}", "arg1", new Exception("info"));
|
||||
logger.debug("debug:{}", "arg1", new Exception("debug"));
|
||||
logger.trace("trace:{}", "arg1", new Exception("trace"));
|
||||
|
||||
verify(locationAwareLogger, times(5)).log(isNull(), anyString(),
|
||||
anyInt(), anyString(), eq(new String[]{"arg1"}), any(Throwable.class));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,384 @@
|
|||
/*
|
||||
* 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.common.utils;
|
||||
|
||||
import org.apache.dubbo.common.utils.json.Service;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class JsonCompatibilityUtilTest {
|
||||
|
||||
private static Class<?> service = Service.class;
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(JsonCompatibilityUtil.class);
|
||||
|
||||
@Test
|
||||
public void testCheckClassCompatibility() {
|
||||
boolean res = JsonCompatibilityUtil.checkClassCompatibility(service);
|
||||
assertFalse(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUnsupportedMethods() {
|
||||
List<String> res = JsonCompatibilityUtil.getUnsupportedMethods(service);
|
||||
assert res != null;
|
||||
logger.info(res.toString());
|
||||
assert (res.size() != 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInt() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testInt"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntArr() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testIntArr"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInteger() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testInteger"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntegerArr() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testIntegerArr"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntegerList() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testIntegerList"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShort() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testShort"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShortArr() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testShortArr"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSShort() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testSShort"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSShortArr() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testSShortArr"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShortList() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testShortList"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testByte() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testByte"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testByteArr() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testByteArr"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testBByte() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testBByte"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBByteArr() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testBByteArr"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testByteList() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testByteList"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testFloat() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testFloat"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFloatArr() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testFloatArr"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFFloat() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testFFloat"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testFloatArray() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testFloatArray"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testFloatList() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testFloatList"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBoolean() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testBoolean"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBooleanArr() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testBooleanArr"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBBoolean() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testBBoolean"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBooleanArray() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testBooleanArray"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBooleanList() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testBooleanList"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChar() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testChar"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCharArr() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testCharArr"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCharacter() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testCharacter"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCharacterArr() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testCharacterArr"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCharacterList() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testCharacterList"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCharacterListArr() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testCharacterListArr"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testString() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testString"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringArr() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testStringArr"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringList() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testStringList"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringListArr() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testStringListArr"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDate() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testDate"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCalendar() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testCalendar"));
|
||||
assertFalse(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalTime() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testLocalTime"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalDate() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testLocalDate"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalDateTime() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testLocalDateTime"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testZoneDateTime() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testZoneDateTime"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMap() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testMap"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSet() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testSet"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOptionalEmpty() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testOptionalEmpty"));
|
||||
assertFalse(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOptionalInteger() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testOptionalInteger"));
|
||||
assertFalse(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOptionalString() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testOptionalString"));
|
||||
assertFalse(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnum() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testEnum"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRecord() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testRecord"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInterface() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testInterface"));
|
||||
assertFalse(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testObject() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testObject"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testObjectList() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testObjectList"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTemplate() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testTemplate"));
|
||||
assertTrue(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStream() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testStream"));
|
||||
assertFalse(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIterator() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testIterator"));
|
||||
assertFalse(res);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAbstract() throws NoSuchMethodException {
|
||||
boolean res = JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testAbstract"));
|
||||
assertFalse(res);
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
package org.apache.dubbo.common.utils;
|
||||
|
||||
import org.apache.dubbo.common.json.JsonUtil;
|
||||
import org.apache.dubbo.common.json.impl.FastJson2Impl;
|
||||
import org.apache.dubbo.common.json.impl.FastJsonImpl;
|
||||
import org.apache.dubbo.common.json.impl.GsonImpl;
|
||||
|
|
@ -30,6 +31,7 @@ import org.junit.jupiter.api.Test;
|
|||
import org.mockito.MockedConstruction;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
|
|
@ -75,7 +77,7 @@ class JsonUtilsTest {
|
|||
Assertions.assertEquals(Collections.singletonList(map), JsonUtils.getJson().toJavaList("[{\"a\":\"a\"}]", Map.class));
|
||||
|
||||
// prefer use fastjson2
|
||||
JsonUtils.setJson(null);
|
||||
setJson(null);
|
||||
System.setProperty("dubbo.json-framework.prefer", "fastjson2");
|
||||
Assertions.assertEquals("{\"a\":\"a\"}", JsonUtils.getJson().toJson(map));
|
||||
Assertions.assertEquals(map, JsonUtils.getJson().toJavaObject("{\"a\":\"a\"}", Map.class));
|
||||
|
|
@ -83,7 +85,7 @@ class JsonUtilsTest {
|
|||
System.clearProperty("dubbo.json-framework.prefer");
|
||||
|
||||
// prefer use fastjson
|
||||
JsonUtils.setJson(null);
|
||||
setJson(null);
|
||||
System.setProperty("dubbo.json-framework.prefer", "fastjson");
|
||||
Assertions.assertEquals("{\"a\":\"a\"}", JsonUtils.getJson().toJson(map));
|
||||
Assertions.assertEquals(map, JsonUtils.getJson().toJavaObject("{\"a\":\"a\"}", Map.class));
|
||||
|
|
@ -91,7 +93,7 @@ class JsonUtilsTest {
|
|||
System.clearProperty("dubbo.json-framework.prefer");
|
||||
|
||||
// prefer use gson
|
||||
JsonUtils.setJson(null);
|
||||
setJson(null);
|
||||
System.setProperty("dubbo.json-framework.prefer", "gson");
|
||||
Assertions.assertEquals("{\"a\":\"a\"}", JsonUtils.getJson().toJson(map));
|
||||
Assertions.assertEquals(map, JsonUtils.getJson().toJavaObject("{\"a\":\"a\"}", Map.class));
|
||||
|
|
@ -99,14 +101,14 @@ class JsonUtilsTest {
|
|||
System.clearProperty("dubbo.json-framework.prefer");
|
||||
|
||||
// prefer use jackson
|
||||
JsonUtils.setJson(null);
|
||||
setJson(null);
|
||||
System.setProperty("dubbo.json-framework.prefer", "jackson");
|
||||
Assertions.assertEquals("{\"a\":\"a\"}", JsonUtils.getJson().toJson(map));
|
||||
Assertions.assertEquals(map, JsonUtils.getJson().toJavaObject("{\"a\":\"a\"}", Map.class));
|
||||
Assertions.assertEquals(Collections.singletonList(map), JsonUtils.getJson().toJavaList("[{\"a\":\"a\"}]", Map.class));
|
||||
System.clearProperty("dubbo.json-framework.prefer");
|
||||
|
||||
JsonUtils.setJson(null);
|
||||
setJson(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -169,34 +171,34 @@ class JsonUtilsTest {
|
|||
for (Object obj : objs) {
|
||||
|
||||
// prefer use fastjson2
|
||||
JsonUtils.setJson(null);
|
||||
setJson(null);
|
||||
System.setProperty("dubbo.json-framework.prefer", "fastjson2");
|
||||
Assertions.assertInstanceOf(FastJson2Impl.class, JsonUtils.getJson());
|
||||
String fromFastjson2 = JsonUtils.getJson().toJson(obj);
|
||||
System.clearProperty("dubbo.json-framework.prefer");
|
||||
|
||||
// prefer use fastjson
|
||||
JsonUtils.setJson(null);
|
||||
setJson(null);
|
||||
System.setProperty("dubbo.json-framework.prefer", "fastjson");
|
||||
Assertions.assertInstanceOf(FastJsonImpl.class, JsonUtils.getJson());
|
||||
String fromFastjson1 = JsonUtils.getJson().toJson(obj);
|
||||
System.clearProperty("dubbo.json-framework.prefer");
|
||||
|
||||
// prefer use gson
|
||||
JsonUtils.setJson(null);
|
||||
setJson(null);
|
||||
System.setProperty("dubbo.json-framework.prefer", "gson");
|
||||
Assertions.assertInstanceOf(GsonImpl.class, JsonUtils.getJson());
|
||||
String fromGson = JsonUtils.getJson().toJson(obj);
|
||||
System.clearProperty("dubbo.json-framework.prefer");
|
||||
|
||||
// prefer use jackson
|
||||
JsonUtils.setJson(null);
|
||||
setJson(null);
|
||||
System.setProperty("dubbo.json-framework.prefer", "jackson");
|
||||
Assertions.assertInstanceOf(JacksonImpl.class, JsonUtils.getJson());
|
||||
String fromJackson = JsonUtils.getJson().toJson(obj);
|
||||
System.clearProperty("dubbo.json-framework.prefer");
|
||||
|
||||
JsonUtils.setJson(null);
|
||||
setJson(null);
|
||||
|
||||
Assertions.assertEquals(fromFastjson1, fromFastjson2);
|
||||
Assertions.assertEquals(fromFastjson1, fromGson);
|
||||
|
|
@ -218,39 +220,39 @@ class JsonUtilsTest {
|
|||
(mock, context) -> Mockito.when(mock.isSupport()).thenAnswer(invocation -> allowJackson.get()));
|
||||
|
||||
// default use fastjson2
|
||||
JsonUtils.setJson(null);
|
||||
setJson(null);
|
||||
Assertions.assertInstanceOf(FastJson2Impl.class, JsonUtils.getJson());
|
||||
|
||||
// prefer use fastjson2
|
||||
JsonUtils.setJson(null);
|
||||
setJson(null);
|
||||
System.setProperty("dubbo.json-framework.prefer", "fastjson2");
|
||||
Assertions.assertInstanceOf(FastJson2Impl.class, JsonUtils.getJson());
|
||||
|
||||
// prefer use fastjson
|
||||
JsonUtils.setJson(null);
|
||||
setJson(null);
|
||||
System.setProperty("dubbo.json-framework.prefer", "fastjson");
|
||||
Assertions.assertInstanceOf(FastJsonImpl.class, JsonUtils.getJson());
|
||||
System.clearProperty("dubbo.json-framework.prefer");
|
||||
|
||||
// prefer use gson
|
||||
JsonUtils.setJson(null);
|
||||
setJson(null);
|
||||
System.setProperty("dubbo.json-framework.prefer", "gson");
|
||||
Assertions.assertInstanceOf(GsonImpl.class, JsonUtils.getJson());
|
||||
System.clearProperty("dubbo.json-framework.prefer");
|
||||
|
||||
// prefer use not found
|
||||
JsonUtils.setJson(null);
|
||||
setJson(null);
|
||||
System.setProperty("dubbo.json-framework.prefer", "notfound");
|
||||
Assertions.assertInstanceOf(FastJson2Impl.class, JsonUtils.getJson());
|
||||
System.clearProperty("dubbo.json-framework.prefer");
|
||||
|
||||
JsonUtils.setJson(null);
|
||||
setJson(null);
|
||||
// TCCL not found fastjson2
|
||||
allowFastjson2.set(false);
|
||||
Assertions.assertInstanceOf(FastJsonImpl.class, JsonUtils.getJson());
|
||||
allowFastjson2.set(true);
|
||||
|
||||
JsonUtils.setJson(null);
|
||||
setJson(null);
|
||||
// TCCL not found fastjson2, fastjson
|
||||
allowFastjson2.set(false);
|
||||
allowFastjson.set(false);
|
||||
|
|
@ -258,7 +260,7 @@ class JsonUtilsTest {
|
|||
allowFastjson.set(true);
|
||||
allowFastjson2.set(true);
|
||||
|
||||
JsonUtils.setJson(null);
|
||||
setJson(null);
|
||||
// TCCL not found fastjson2, fastjson, gson
|
||||
allowFastjson2.set(false);
|
||||
allowFastjson.set(false);
|
||||
|
|
@ -268,7 +270,7 @@ class JsonUtilsTest {
|
|||
allowFastjson.set(true);
|
||||
allowFastjson2.set(true);
|
||||
|
||||
JsonUtils.setJson(null);
|
||||
setJson(null);
|
||||
// TCCL not found fastjson2, prefer use fastjson2
|
||||
allowFastjson2.set(false);
|
||||
System.setProperty("dubbo.json-framework.prefer", "fastjson2");
|
||||
|
|
@ -276,7 +278,7 @@ class JsonUtilsTest {
|
|||
System.clearProperty("dubbo.json-framework.prefer");
|
||||
allowFastjson2.set(true);
|
||||
|
||||
JsonUtils.setJson(null);
|
||||
setJson(null);
|
||||
// TCCL not found fastjson, prefer use fastjson
|
||||
allowFastjson.set(false);
|
||||
System.setProperty("dubbo.json-framework.prefer", "fastjson");
|
||||
|
|
@ -284,7 +286,7 @@ class JsonUtilsTest {
|
|||
System.clearProperty("dubbo.json-framework.prefer");
|
||||
allowFastjson.set(true);
|
||||
|
||||
JsonUtils.setJson(null);
|
||||
setJson(null);
|
||||
// TCCL not found gson, prefer use gson
|
||||
allowGson.set(false);
|
||||
System.setProperty("dubbo.json-framework.prefer", "gson");
|
||||
|
|
@ -292,7 +294,7 @@ class JsonUtilsTest {
|
|||
System.clearProperty("dubbo.json-framework.prefer");
|
||||
allowGson.set(true);
|
||||
|
||||
JsonUtils.setJson(null);
|
||||
setJson(null);
|
||||
// TCCL not found jackson, prefer use jackson
|
||||
allowJackson.set(false);
|
||||
System.setProperty("dubbo.json-framework.prefer", "jackson");
|
||||
|
|
@ -300,7 +302,7 @@ class JsonUtilsTest {
|
|||
System.clearProperty("dubbo.json-framework.prefer");
|
||||
allowJackson.set(true);
|
||||
|
||||
JsonUtils.setJson(null);
|
||||
setJson(null);
|
||||
// TCCL not found fastjson, gson
|
||||
allowFastjson2.set(false);
|
||||
allowFastjson.set(false);
|
||||
|
|
@ -312,6 +314,22 @@ class JsonUtilsTest {
|
|||
allowFastjson2.set(true);
|
||||
allowJackson.set(true);
|
||||
|
||||
JsonUtils.setJson(null);
|
||||
setJson(null);
|
||||
}
|
||||
|
||||
private static Field jsonFieldCache;
|
||||
|
||||
private static void setJson(JsonUtil json) {
|
||||
try {
|
||||
if (jsonFieldCache == null) {
|
||||
jsonFieldCache = JsonUtils.class.getDeclaredField("jsonUtil");
|
||||
jsonFieldCache.setAccessible(true);
|
||||
}
|
||||
|
||||
jsonFieldCache.set(null, json);
|
||||
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -227,6 +227,10 @@ class StringUtilsTest {
|
|||
assertEquals(StringUtils.join(s), "123");
|
||||
assertEquals(StringUtils.join(s, ','), "1,2,3");
|
||||
assertEquals(StringUtils.join(s, ","), "1,2,3");
|
||||
assertEquals(StringUtils.join(s, ',', 0, 1), "1");
|
||||
assertEquals(StringUtils.join(s, ',', 0, 2), "1,2");
|
||||
assertEquals(StringUtils.join(s, ',', 0, 3), "1,2,3");
|
||||
assertEquals("", StringUtils.join(s, ',', 2, 0), "1,2");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -502,4 +506,4 @@ class StringUtilsTest {
|
|||
assertTrue(startsWithIgnoreCase("Dubbo.application.name", "dubbo.application."));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* 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.common.utils.json;
|
||||
|
||||
public abstract class AbstractObject {
|
||||
|
||||
public abstract String sayHello();
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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.common.utils.json;
|
||||
|
||||
public enum Color {
|
||||
RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
|
||||
|
||||
private String name;
|
||||
private int index;
|
||||
|
||||
private Color(String name, int index) {
|
||||
this.name = name;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public static String getName(int index) {
|
||||
for (Color c : Color.values()) {
|
||||
if (c.getIndex() == index) {
|
||||
return c.name;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
public void setIndex(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
}
|
||||
|
|
@ -13,4 +13,9 @@
|
|||
* 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.common.utils.json;
|
||||
|
||||
public interface Printer {
|
||||
String print();
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* 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.common.utils.json;
|
||||
|
||||
//public record Range(Integer left, Integer right) {
|
||||
// public Integer sum() {
|
||||
// return left + right;
|
||||
// }
|
||||
//}
|
||||
|
||||
public class Range {
|
||||
private Integer left;
|
||||
private Integer right;
|
||||
|
||||
public Range(Integer left, Integer right) {
|
||||
this.left = left;
|
||||
this.right =right;
|
||||
}
|
||||
public Integer sum() {
|
||||
return left + right;
|
||||
}
|
||||
}
|
||||
|
|
@ -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.
|
||||
*/
|
||||
package org.apache.dubbo.common.utils.json;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
public interface Service {
|
||||
String sayHi(String name);
|
||||
|
||||
List<String> testList();
|
||||
|
||||
int testInt();
|
||||
|
||||
int[] testIntArr();
|
||||
|
||||
Integer testInteger();
|
||||
|
||||
Integer[] testIntegerArr();
|
||||
|
||||
List<Integer> testIntegerList();
|
||||
|
||||
short testShort();
|
||||
|
||||
short[] testShortArr();
|
||||
|
||||
Short testSShort();
|
||||
|
||||
Short[] testSShortArr();
|
||||
|
||||
List<Short> testShortList();
|
||||
|
||||
byte testByte();
|
||||
|
||||
byte[] testByteArr();
|
||||
|
||||
Byte testBByte();
|
||||
|
||||
Byte[] testBByteArr();
|
||||
|
||||
ArrayList<Byte> testByteList();
|
||||
|
||||
float testFloat();
|
||||
|
||||
float[] testFloatArr();
|
||||
|
||||
Float testFFloat();
|
||||
|
||||
Float[] testFloatArray();
|
||||
|
||||
List<Float> testFloatList();
|
||||
|
||||
boolean testBoolean();
|
||||
|
||||
boolean[] testBooleanArr();
|
||||
|
||||
Boolean testBBoolean();
|
||||
|
||||
Boolean[] testBooleanArray();
|
||||
|
||||
List<Boolean> testBooleanList();
|
||||
|
||||
char testChar();
|
||||
|
||||
char[] testCharArr();
|
||||
|
||||
Character testCharacter();
|
||||
|
||||
Character[] testCharacterArr();
|
||||
|
||||
List<Character> testCharacterList();
|
||||
|
||||
List<Character[]> testCharacterListArr();
|
||||
|
||||
String testString();
|
||||
|
||||
String[] testStringArr();
|
||||
|
||||
List<String> testStringList();
|
||||
|
||||
List<String[]> testStringListArr();
|
||||
|
||||
String testNull();
|
||||
|
||||
Date testDate();
|
||||
|
||||
Calendar testCalendar();
|
||||
|
||||
LocalTime testLocalTime();
|
||||
|
||||
LocalDate testLocalDate();
|
||||
|
||||
LocalDateTime testLocalDateTime();
|
||||
|
||||
ZonedDateTime testZoneDateTime();
|
||||
|
||||
Map<Integer, String> testMap();
|
||||
|
||||
Set<Integer> testSet();
|
||||
|
||||
Optional<Integer> testOptionalEmpty();
|
||||
|
||||
Optional<Integer> testOptionalInteger();
|
||||
|
||||
Optional<String> testOptionalString();
|
||||
|
||||
Color testEnum();
|
||||
|
||||
Range testRecord();
|
||||
|
||||
Printer testInterface();
|
||||
|
||||
Teacher testObject();
|
||||
|
||||
List<Teacher> testObjectList();
|
||||
|
||||
Student<Integer> testTemplate();
|
||||
|
||||
InputStream testStream() throws FileNotFoundException;
|
||||
|
||||
Iterator<String> testIterator();
|
||||
|
||||
AbstractObject testAbstract();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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.common.utils.json;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
public class Student<W> implements Serializable {
|
||||
private Integer type;
|
||||
|
||||
private List<String> names;
|
||||
|
||||
private List<W> namesT;
|
||||
|
||||
private W age;
|
||||
|
||||
private String name;
|
||||
|
||||
public Student(Integer type, String name) {
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Student{" +
|
||||
"type=" + type +
|
||||
", name='" + name + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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.common.utils.json;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class Teacher implements Serializable {
|
||||
private String name;
|
||||
private Integer age;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Integer getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(Integer age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public Teacher(String name, Integer age) {
|
||||
this.name = name;
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Teacher{" +
|
||||
"name='" + name + '\'' +
|
||||
", age=" + age +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
|
@ -34,7 +34,7 @@
|
|||
</layout>
|
||||
</appender>
|
||||
<root>
|
||||
<level value="INFO"/>
|
||||
<level value="TRACE"/>
|
||||
<appender-ref ref="dubbo"/>
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
</root>
|
||||
|
|
|
|||
|
|
@ -94,6 +94,12 @@
|
|||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-plugin-generic-invoke</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
|
|
|
|||
|
|
@ -72,6 +72,12 @@
|
|||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-tracing</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-monitor-api</artifactId>
|
||||
|
|
@ -226,6 +232,20 @@
|
|||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-plugin-router-condition</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-plugin-router-tag</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>testcontainers</artifactId>
|
||||
|
|
@ -239,6 +259,5 @@
|
|||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -21,10 +21,11 @@ import org.apache.dubbo.common.extension.SPI;
|
|||
|
||||
/**
|
||||
* 2019/12/30
|
||||
* it will be instead of CommonConfigPostProcessor
|
||||
*/
|
||||
|
||||
@Deprecated
|
||||
@SPI(scope = ExtensionScope.MODULE)
|
||||
public interface ConfigPostProcessor {
|
||||
public interface ConfigPostProcessor extends CommonConfigPostProcessor {
|
||||
|
||||
default void postProcessReferConfig(ReferenceConfig referenceConfig) {
|
||||
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ import java.beans.Transient;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
|
@ -744,7 +745,6 @@ public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
|
|||
}
|
||||
|
||||
checkStubAndLocal(interfaceClass);
|
||||
ConfigValidationUtils.checkMock(interfaceClass, this);
|
||||
|
||||
if (StringUtils.isEmpty(url)) {
|
||||
checkRegistry();
|
||||
|
|
@ -798,7 +798,16 @@ public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
|
|||
private void postProcessConfig() {
|
||||
List<ConfigPostProcessor> configPostProcessors = this.getExtensionLoader(ConfigPostProcessor.class)
|
||||
.getActivateExtension(URL.valueOf("configPostProcessor://"), (String[]) null);
|
||||
configPostProcessors.forEach(component -> component.postProcessReferConfig(this));
|
||||
List<CommonConfigPostProcessor> commonConfigPostProcessors = this.getExtensionLoader(CommonConfigPostProcessor.class)
|
||||
.getActivateExtension(URL.valueOf("configPostProcessor://"), (String[]) null);
|
||||
|
||||
HashSet<CommonConfigPostProcessor> allConfigPostProcessor = new HashSet<>();
|
||||
|
||||
// merge common and old config
|
||||
allConfigPostProcessor.addAll(commonConfigPostProcessors);
|
||||
allConfigPostProcessor.addAll(configPostProcessors);
|
||||
|
||||
allConfigPostProcessor.forEach(component -> component.postProcessReferConfig(this));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
|
@ -80,6 +81,8 @@ import static org.apache.dubbo.common.constants.CommonConstants.DUBBO;
|
|||
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_IP_TO_BIND;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.EXECUTOR_MANAGEMENT_MODE_ISOLATION;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.EXPORTER_LISTENER_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.EXT_PROTOCOL;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.IS_EXTRA;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.LOCALHOST_VALUE;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.MONITOR_KEY;
|
||||
|
|
@ -375,7 +378,17 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
mapServiceName(url, serviceNameMapping, scheduledExecutor);
|
||||
}
|
||||
});
|
||||
|
||||
onExported();
|
||||
|
||||
if (hasRegistrySpecified()) {
|
||||
getScopeModel().getDeployer().getApplicationDeployer().exportMetadataService();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasRegistrySpecified() {
|
||||
return CollectionUtils.isNotEmpty(this.getRegistries())
|
||||
|| CollectionUtils.isNotEmpty(getScopeModel().getApplicationModel().getApplicationConfigManager().getRegistries());
|
||||
}
|
||||
|
||||
protected void mapServiceName(URL url, ServiceNameMapping serviceNameMapping, ScheduledExecutorService scheduledExecutor) {
|
||||
|
|
@ -473,7 +486,6 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
}
|
||||
}
|
||||
checkStubAndLocal(interfaceClass);
|
||||
ConfigValidationUtils.checkMock(interfaceClass, this);
|
||||
ConfigValidationUtils.validateServiceConfig(this);
|
||||
postProcessConfig();
|
||||
}
|
||||
|
|
@ -522,7 +534,8 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
providerModel.setDestroyRunner(getDestroyRunner());
|
||||
repository.registerProvider(providerModel);
|
||||
|
||||
List<URL> registryURLs = ConfigValidationUtils.loadRegistries(this, true);
|
||||
List<URL> registryURLs = !Boolean.FALSE.equals(isRegister()) ?
|
||||
ConfigValidationUtils.loadRegistries(this, true) : Collections.emptyList();
|
||||
|
||||
for (ProtocolConfig protocolConfig : protocols) {
|
||||
String pathKey = URL.buildKey(getContextPath(protocolConfig)
|
||||
|
|
@ -551,6 +564,9 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
|
||||
processServiceExecutor(url);
|
||||
|
||||
if (CollectionUtils.isEmpty(registryURLs)) {
|
||||
registerType = RegisterTypeEnum.NEVER_REGISTER;
|
||||
}
|
||||
exportUrl(url, registryURLs, registerType);
|
||||
|
||||
initServiceMethodMetrics(url);
|
||||
|
|
@ -757,14 +773,13 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
// export to remote if the config is not local (export to local only when config is local)
|
||||
if (!SCOPE_LOCAL.equalsIgnoreCase(scope)) {
|
||||
// export to extra protocol is used in remote export
|
||||
String extProtocol = url.getParameter("ext.protocol", "");
|
||||
String extProtocol = url.getParameter(EXT_PROTOCOL, "");
|
||||
List<String> protocols = new ArrayList<>();
|
||||
|
||||
if (StringUtils.isNotBlank(extProtocol)) {
|
||||
// export original url
|
||||
url = URLBuilder.from(url).
|
||||
addParameter(IS_PU_SERVER_KEY, Boolean.TRUE.toString()).
|
||||
removeParameter("ext.protocol").
|
||||
build();
|
||||
}
|
||||
|
||||
|
|
@ -782,6 +797,8 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
if (StringUtils.isNotBlank(protocol)) {
|
||||
URL localUrl = URLBuilder.from(url).
|
||||
setProtocol(protocol).
|
||||
addParameter(IS_EXTRA, Boolean.TRUE.toString()).
|
||||
removeParameter(EXT_PROTOCOL).
|
||||
build();
|
||||
localUrl = exportRemote(localUrl, registryURLs, registerType);
|
||||
if (!isGeneric(generic) && !getScopeModel().isInternal()) {
|
||||
|
|
@ -892,7 +909,16 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
|
|||
private void postProcessConfig() {
|
||||
List<ConfigPostProcessor> configPostProcessors = this.getExtensionLoader(ConfigPostProcessor.class)
|
||||
.getActivateExtension(URL.valueOf("configPostProcessor://", getScopeModel()), (String[]) null);
|
||||
configPostProcessors.forEach(component -> component.postProcessServiceConfig(this));
|
||||
List<CommonConfigPostProcessor> commonConfigPostProcessors = this.getExtensionLoader(CommonConfigPostProcessor.class)
|
||||
.getActivateExtension(URL.valueOf("configPostProcessor://"), (String[]) null);
|
||||
|
||||
HashSet<CommonConfigPostProcessor> allConfigPostProcessor = new HashSet<>();
|
||||
|
||||
// merge common and old config
|
||||
allConfigPostProcessor.addAll(commonConfigPostProcessors);
|
||||
allConfigPostProcessor.addAll(configPostProcessors);
|
||||
|
||||
allConfigPostProcessor.forEach(component -> component.postProcessServiceConfig(this));
|
||||
}
|
||||
|
||||
public void addServiceListener(ServiceListener listener) {
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ import static org.apache.dubbo.remoting.Constants.BIND_PORT_KEY;
|
|||
public class InternalServiceConfigBuilder<T> {
|
||||
|
||||
private final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(getClass());
|
||||
private static final Set<String> UNACCEPTABLE_PROTOCOL = Stream.of("rest", "grpc").collect(Collectors.toSet());
|
||||
private static final Set<String> ACCEPTABLE_PROTOCOL = Stream.of("dubbo", "tri", "injvm").collect(Collectors.toSet());
|
||||
|
||||
private final ApplicationModel applicationModel;
|
||||
private String protocol;
|
||||
|
|
@ -112,19 +112,20 @@ public class InternalServiceConfigBuilder<T> {
|
|||
*/
|
||||
private String getRelatedOrDefaultProtocol() {
|
||||
String protocol = "";
|
||||
// <dubbo:consumer/>
|
||||
List<ModuleModel> moduleModels = applicationModel.getPubModuleModels();
|
||||
protocol = moduleModels.stream()
|
||||
.map(ModuleModel::getConfigManager)
|
||||
.map(ModuleConfigManager::getConsumers)
|
||||
.filter(CollectionUtils::isNotEmpty)
|
||||
.flatMap(Collection::stream)
|
||||
.map(ConsumerConfig::getProtocol)
|
||||
.filter(StringUtils::isNotEmpty)
|
||||
.filter(p -> !UNACCEPTABLE_PROTOCOL.contains(p))
|
||||
.findFirst()
|
||||
.orElse("");
|
||||
// <dubbo:protocol/>
|
||||
if (StringUtils.isEmpty(protocol)) {
|
||||
Collection<ProtocolConfig> protocols = applicationModel.getApplicationConfigManager().getProtocols();
|
||||
if (CollectionUtils.isNotEmpty(protocols)) {
|
||||
protocol = protocols.stream()
|
||||
.map(ProtocolConfig::getName)
|
||||
.filter(StringUtils::isNotEmpty)
|
||||
.filter(p -> ACCEPTABLE_PROTOCOL.contains(p))
|
||||
.findFirst()
|
||||
.orElse("");
|
||||
}
|
||||
}
|
||||
// <dubbo:provider/>
|
||||
List<ModuleModel> moduleModels = applicationModel.getPubModuleModels();
|
||||
if (StringUtils.isEmpty(protocol)) {
|
||||
Stream<ProviderConfig> providerConfigStream = moduleModels.stream()
|
||||
.map(ModuleModel::getConfigManager)
|
||||
|
|
@ -145,22 +146,10 @@ public class InternalServiceConfigBuilder<T> {
|
|||
}
|
||||
})
|
||||
.filter(StringUtils::isNotEmpty)
|
||||
.filter(p -> !UNACCEPTABLE_PROTOCOL.contains(p))
|
||||
.filter(p -> ACCEPTABLE_PROTOCOL.contains(p))
|
||||
.findFirst()
|
||||
.orElse("");
|
||||
}
|
||||
// <dubbo:protocol/>
|
||||
if (StringUtils.isEmpty(protocol)) {
|
||||
Collection<ProtocolConfig> protocols = applicationModel.getApplicationConfigManager().getProtocols();
|
||||
if (CollectionUtils.isNotEmpty(protocols)) {
|
||||
protocol = protocols.stream()
|
||||
.map(ProtocolConfig::getName)
|
||||
.filter(StringUtils::isNotEmpty)
|
||||
.filter(p -> !UNACCEPTABLE_PROTOCOL.contains(p))
|
||||
.findFirst()
|
||||
.orElse("");
|
||||
}
|
||||
}
|
||||
// <dubbo:application/>
|
||||
if (StringUtils.isEmpty(protocol)) {
|
||||
protocol = getApplicationConfig().getProtocol();
|
||||
|
|
@ -171,7 +160,18 @@ public class InternalServiceConfigBuilder<T> {
|
|||
}
|
||||
}
|
||||
}
|
||||
return StringUtils.isNotEmpty(protocol) && !UNACCEPTABLE_PROTOCOL.contains(protocol) ? protocol : DUBBO_PROTOCOL;
|
||||
// <dubbo:consumer/>
|
||||
protocol = moduleModels.stream()
|
||||
.map(ModuleModel::getConfigManager)
|
||||
.map(ModuleConfigManager::getConsumers)
|
||||
.filter(CollectionUtils::isNotEmpty)
|
||||
.flatMap(Collection::stream)
|
||||
.map(ConsumerConfig::getProtocol)
|
||||
.filter(StringUtils::isNotEmpty)
|
||||
.filter(p -> ACCEPTABLE_PROTOCOL.contains(p))
|
||||
.findFirst()
|
||||
.orElse("");
|
||||
return StringUtils.isNotEmpty(protocol) && ACCEPTABLE_PROTOCOL.contains(protocol) ? protocol : DUBBO_PROTOCOL;
|
||||
}
|
||||
|
||||
public InternalServiceConfigBuilder<T> protocol(String protocol) {
|
||||
|
|
@ -254,7 +254,11 @@ public class InternalServiceConfigBuilder<T> {
|
|||
logger.info("Using " + this.protocol + " protocol to export "+interfaceClass.getName()+" service on port " + protocolConfig.getPort());
|
||||
|
||||
applicationModel.getApplicationConfigManager().getProtocol(this.protocol)
|
||||
.ifPresent(protocolConfig::mergeProtocol);
|
||||
.ifPresent(p -> {
|
||||
protocolConfig.mergeProtocol(p);
|
||||
// clear extra protocols possibly merged from global ProtocolConfig
|
||||
protocolConfig.setExtProtocol(null);
|
||||
});
|
||||
|
||||
ApplicationConfig applicationConfig = getApplicationConfig();
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ import org.apache.dubbo.common.logger.LoggerFactory;
|
|||
import org.apache.dubbo.common.threadpool.manager.ExecutorRepository;
|
||||
import org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository;
|
||||
import org.apache.dubbo.common.utils.ArrayUtils;
|
||||
import org.apache.dubbo.common.utils.ClassUtils;
|
||||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
|
|
@ -47,6 +46,7 @@ import org.apache.dubbo.config.DubboShutdownHook;
|
|||
import org.apache.dubbo.config.MetadataReportConfig;
|
||||
import org.apache.dubbo.config.MetricsConfig;
|
||||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.config.TracingConfig;
|
||||
import org.apache.dubbo.config.context.ConfigManager;
|
||||
import org.apache.dubbo.config.utils.CompositeReferenceCache;
|
||||
import org.apache.dubbo.config.utils.ConfigValidationUtils;
|
||||
|
|
@ -59,6 +59,7 @@ import org.apache.dubbo.metrics.report.DefaultMetricsReporterFactory;
|
|||
import org.apache.dubbo.metrics.report.MetricsReporter;
|
||||
import org.apache.dubbo.metrics.report.MetricsReporterFactory;
|
||||
import org.apache.dubbo.metrics.service.MetricsServiceExporter;
|
||||
import org.apache.dubbo.metrics.utils.MetricsSupportUtil;
|
||||
import org.apache.dubbo.registry.Registry;
|
||||
import org.apache.dubbo.registry.RegistryFactory;
|
||||
import org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils;
|
||||
|
|
@ -69,6 +70,8 @@ import org.apache.dubbo.rpc.model.ModuleServiceRepository;
|
|||
import org.apache.dubbo.rpc.model.ProviderModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModelUtil;
|
||||
import org.apache.dubbo.tracing.DubboObservationRegistry;
|
||||
import org.apache.dubbo.tracing.utils.ObservationSupportUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -151,7 +154,7 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
|
||||
// load spi listener
|
||||
Set<ApplicationDeployListener> deployListeners = applicationModel.getExtensionLoader(ApplicationDeployListener.class)
|
||||
.getSupportedExtensionInstances();
|
||||
.getSupportedExtensionInstances();
|
||||
for (ApplicationDeployListener listener : deployListeners) {
|
||||
this.addDeployListener(listener);
|
||||
}
|
||||
|
|
@ -180,13 +183,13 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
}
|
||||
|
||||
/**
|
||||
* Close registration of instance for pure Consumer process by setting registerConsumer to 'false'
|
||||
* by default is true.
|
||||
* Enable registration of instance for pure Consumer process by setting registerConsumer to 'true'
|
||||
* by default is false.
|
||||
*/
|
||||
private boolean isRegisterConsumerInstance() {
|
||||
Boolean registerConsumer = getApplication().getRegisterConsumer();
|
||||
Boolean registerConsumer = getApplicationOrElseThrow().getRegisterConsumer();
|
||||
if (registerConsumer == null) {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
return Boolean.TRUE.equals(registerConsumer);
|
||||
}
|
||||
|
|
@ -225,6 +228,9 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
|
||||
initMetricsService();
|
||||
|
||||
// @since 3.2.3
|
||||
initObservationRegistry();
|
||||
|
||||
// @since 2.7.8
|
||||
startMetadataCenter();
|
||||
|
||||
|
|
@ -304,7 +310,7 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
|
||||
useRegistryAsMetadataCenterIfNecessary();
|
||||
|
||||
ApplicationConfig applicationConfig = getApplication();
|
||||
ApplicationConfig applicationConfig = getApplicationOrElseThrow();
|
||||
|
||||
String metadataType = applicationConfig.getMetadataType();
|
||||
// FIXME, multiple metadata config support.
|
||||
|
|
@ -351,17 +357,17 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
List<RegistryConfig> defaultRegistries = configManager.getDefaultRegistries();
|
||||
if (defaultRegistries.size() > 0) {
|
||||
defaultRegistries
|
||||
.stream()
|
||||
.filter(this::isUsedRegistryAsConfigCenter)
|
||||
.map(this::registryAsConfigCenter)
|
||||
.forEach(configCenter -> {
|
||||
if (configManager.getConfigCenter(configCenter.getId()).isPresent()) {
|
||||
return;
|
||||
}
|
||||
configManager.addConfigCenter(configCenter);
|
||||
logger.info("use registry as config-center: " + configCenter);
|
||||
.stream()
|
||||
.filter(this::isUsedRegistryAsConfigCenter)
|
||||
.map(this::registryAsConfigCenter)
|
||||
.forEach(configCenter -> {
|
||||
if (configManager.getConfigCenter(configCenter.getId()).isPresent()) {
|
||||
return;
|
||||
}
|
||||
configManager.addConfigCenter(configCenter);
|
||||
logger.info("use registry as config-center: " + configCenter);
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -371,16 +377,16 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
}
|
||||
|
||||
private void initMetricsReporter() {
|
||||
if (!isSupportMetrics()) {
|
||||
if (!MetricsSupportUtil.isSupportMetrics()) {
|
||||
return;
|
||||
}
|
||||
DefaultMetricsCollector collector =
|
||||
applicationModel.getBeanFactory().getBean(DefaultMetricsCollector.class);
|
||||
applicationModel.getBeanFactory().getBean(DefaultMetricsCollector.class);
|
||||
Optional<MetricsConfig> configOptional = configManager.getMetrics();
|
||||
//If no specific metrics type is configured and there is no Prometheus dependency in the dependencies.
|
||||
MetricsConfig metricsConfig = configOptional.orElse(new MetricsConfig(applicationModel));
|
||||
if (StringUtils.isBlank(metricsConfig.getProtocol())) {
|
||||
metricsConfig.setProtocol(isSupportPrometheus() ? PROTOCOL_PROMETHEUS : PROTOCOL_DEFAULT);
|
||||
metricsConfig.setProtocol(MetricsSupportUtil.isSupportPrometheus() ? PROTOCOL_PROMETHEUS : PROTOCOL_DEFAULT);
|
||||
}
|
||||
collector.setCollectEnabled(true);
|
||||
collector.collectApplication();
|
||||
|
|
@ -409,26 +415,35 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
}
|
||||
}
|
||||
|
||||
public boolean isSupportMetrics() {
|
||||
return isClassPresent("io.micrometer.core.instrument.MeterRegistry");
|
||||
}
|
||||
/**
|
||||
* init ObservationRegistry(Micrometer)
|
||||
*/
|
||||
private void initObservationRegistry() {
|
||||
if (!ObservationSupportUtil.isSupportObservation()) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Not found micrometer-observation or plz check the version of micrometer-observation version if already introduced, need > 1.10.0");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!ObservationSupportUtil.isSupportTracing()) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Not found micrometer-tracing dependency, skip init ObservationRegistry.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
Optional<TracingConfig> configOptional = configManager.getTracing();
|
||||
if (!configOptional.isPresent() || !configOptional.get().getEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
public static boolean isSupportPrometheus() {
|
||||
return isClassPresent("io.micrometer.prometheus.PrometheusConfig")
|
||||
&& isClassPresent("io.prometheus.client.exporter.BasicAuthHttpConnectionFactory")
|
||||
&& isClassPresent("io.prometheus.client.exporter.HttpConnectionFactory")
|
||||
&& isClassPresent("io.prometheus.client.exporter.PushGateway");
|
||||
}
|
||||
|
||||
|
||||
private static boolean isClassPresent(String className) {
|
||||
return ClassUtils.isPresent(className, DefaultApplicationDeployer.class.getClassLoader());
|
||||
DubboObservationRegistry dubboObservationRegistry = new DubboObservationRegistry(applicationModel, configOptional.get());
|
||||
dubboObservationRegistry.initObservationRegistry();
|
||||
}
|
||||
|
||||
|
||||
private boolean isUsedRegistryAsConfigCenter(RegistryConfig registryConfig) {
|
||||
return isUsedRegistryAsCenter(registryConfig, registryConfig::getUseAsConfigCenter, "config",
|
||||
DynamicConfigurationFactory.class);
|
||||
DynamicConfigurationFactory.class);
|
||||
}
|
||||
|
||||
private ConfigCenterConfig registryAsConfigCenter(RegistryConfig registryConfig) {
|
||||
|
|
@ -470,9 +485,9 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
}
|
||||
|
||||
Collection<MetadataReportConfig> metadataConfigsToOverride = originMetadataConfigs
|
||||
.stream()
|
||||
.filter(m -> Objects.isNull(m.getAddress()))
|
||||
.collect(Collectors.toList());
|
||||
.stream()
|
||||
.filter(m -> Objects.isNull(m.getAddress()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (metadataConfigsToOverride.size() > 1) {
|
||||
return;
|
||||
|
|
@ -483,12 +498,12 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
List<RegistryConfig> defaultRegistries = configManager.getDefaultRegistries();
|
||||
if (!defaultRegistries.isEmpty()) {
|
||||
defaultRegistries
|
||||
.stream()
|
||||
.filter(this::isUsedRegistryAsMetadataCenter)
|
||||
.map(registryConfig -> registryAsMetadataCenter(registryConfig, metadataConfigToOverride))
|
||||
.forEach(metadataReportConfig -> {
|
||||
overrideMetadataReportConfig(metadataConfigToOverride, metadataReportConfig);
|
||||
});
|
||||
.stream()
|
||||
.filter(this::isUsedRegistryAsMetadataCenter)
|
||||
.map(registryConfig -> registryAsMetadataCenter(registryConfig, metadataConfigToOverride))
|
||||
.forEach(metadataReportConfig -> {
|
||||
overrideMetadataReportConfig(metadataConfigToOverride, metadataReportConfig);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -517,7 +532,7 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
|
||||
private boolean isUsedRegistryAsMetadataCenter(RegistryConfig registryConfig) {
|
||||
return isUsedRegistryAsCenter(registryConfig, registryConfig::getUseAsMetadataCenter, "metadata",
|
||||
MetadataReportFactory.class);
|
||||
MetadataReportFactory.class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -543,13 +558,13 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
supported = supportsExtension(extensionClass, protocol);
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info(format("No value is configured in the registry, the %s extension[name : %s] %s as the %s center"
|
||||
, extensionClass.getSimpleName(), protocol, supported ? "supports" : "does not support", centerType));
|
||||
, extensionClass.getSimpleName(), protocol, supported ? "supports" : "does not support", centerType));
|
||||
}
|
||||
}
|
||||
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info(format("The registry[%s] will be %s as the %s center", registryConfig,
|
||||
supported ? "used" : "not used", centerType));
|
||||
supported ? "used" : "not used", centerType));
|
||||
}
|
||||
return supported;
|
||||
}
|
||||
|
|
@ -572,7 +587,7 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
|
||||
private MetadataReportConfig registryAsMetadataCenter(RegistryConfig registryConfig, MetadataReportConfig originMetadataReportConfig) {
|
||||
MetadataReportConfig metadataReportConfig = originMetadataReportConfig == null ?
|
||||
new MetadataReportConfig(registryConfig.getApplicationModel()) : originMetadataReportConfig;
|
||||
new MetadataReportConfig(registryConfig.getApplicationModel()) : originMetadataReportConfig;
|
||||
if (metadataReportConfig.getId() == null) {
|
||||
metadataReportConfig.setId(registryConfig.getId());
|
||||
}
|
||||
|
|
@ -732,7 +747,7 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
}
|
||||
|
||||
@Override
|
||||
public void prepareApplicationInstance() {
|
||||
public void prepareApplicationInstance(ModuleModel moduleModel) {
|
||||
if (hasPreparedApplicationInstance.get()) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -740,8 +755,7 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
// export MetricsService
|
||||
exportMetricsService();
|
||||
|
||||
if (isRegisterConsumerInstance()) {
|
||||
exportMetadataService();
|
||||
if (isRegisterConsumerInstance() || moduleModel.getDeployer().hasRegistryInteraction()) {
|
||||
if (hasPreparedApplicationInstance.compareAndSet(false, true)) {
|
||||
// register the local ServiceInstance if required
|
||||
registerServiceInstance();
|
||||
|
|
@ -749,6 +763,11 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void exportMetadataService() {
|
||||
doExportMetadataService();
|
||||
}
|
||||
|
||||
public void prepareInternalModule() {
|
||||
if (hasPreparedInternalModule) {
|
||||
return;
|
||||
|
|
@ -775,13 +794,13 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
|
||||
private void exportMetricsService() {
|
||||
boolean exportMetrics = applicationModel.getApplicationConfigManager().getMetrics()
|
||||
.map(MetricsConfig::getExportMetricsService).orElse(true);
|
||||
.map(MetricsConfig::getExportMetricsService).orElse(true);
|
||||
if (exportMetrics) {
|
||||
try {
|
||||
metricsServiceExporter.export();
|
||||
} catch (Exception e) {
|
||||
logger.error(LoggerCodeConstants.COMMON_METRICS_COLLECTOR_EXCEPTION, "", "",
|
||||
"exportMetricsService an exception occurred when handle starting event", e);
|
||||
"exportMetricsService an exception occurred when handle starting event", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -840,14 +859,18 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
if (StringUtils.isNotEmpty(configContent)) {
|
||||
logger.info(String.format("Got global remote configuration from config center with key-%s and group-%s: \n %s", configCenter.getConfigFile(), configCenter.getGroup(), configContent));
|
||||
}
|
||||
String appGroup = getApplication().getName();
|
||||
String appGroup = "";
|
||||
String appConfigContent = null;
|
||||
String appConfigFile = null;
|
||||
if (isNotEmpty(appGroup)) {
|
||||
appConfigFile = isNotEmpty(configCenter.getAppConfigFile()) ? configCenter.getAppConfigFile() : configCenter.getConfigFile();
|
||||
appConfigContent = dynamicConfiguration.getProperties(appConfigFile, appGroup);
|
||||
if (StringUtils.isNotEmpty(appConfigContent)) {
|
||||
logger.info(String.format("Got application specific remote configuration from config center with key %s and group %s: \n %s", appConfigFile, appGroup, appConfigContent));
|
||||
Optional<ApplicationConfig> applicationOptional = getApplication();
|
||||
if (applicationOptional.isPresent()) {
|
||||
appGroup = applicationOptional.get().getName();
|
||||
if (isNotEmpty(appGroup)) {
|
||||
appConfigFile = isNotEmpty(configCenter.getAppConfigFile()) ? configCenter.getAppConfigFile() : configCenter.getConfigFile();
|
||||
appConfigContent = dynamicConfiguration.getProperties(appConfigFile, appGroup);
|
||||
if (StringUtils.isNotEmpty(appConfigContent)) {
|
||||
logger.info(String.format("Got application specific remote configuration from config center with key %s and group %s: \n %s", appConfigFile, appGroup, appConfigContent));
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
|
|
@ -859,10 +882,10 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
|
||||
// Add metrics
|
||||
MetricsEventBus.publish(ConfigCenterEvent.toChangeEvent(applicationModel, configCenter.getConfigFile(), configCenter.getGroup(),
|
||||
configCenter.getProtocol(), ConfigChangeType.ADDED.name(), configMap.size()));
|
||||
configCenter.getProtocol(), ConfigChangeType.ADDED.name(), configMap.size()));
|
||||
if (isNotEmpty(appGroup)) {
|
||||
MetricsEventBus.publish(ConfigCenterEvent.toChangeEvent(applicationModel, appConfigFile, appGroup,
|
||||
configCenter.getProtocol(), ConfigChangeType.ADDED.name(), appConfigMap.size()));
|
||||
configCenter.getProtocol(), ConfigChangeType.ADDED.name(), appConfigMap.size()));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Failed to parse configurations from Config Center.", e);
|
||||
|
|
@ -899,7 +922,9 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
private void registerServiceInstance() {
|
||||
try {
|
||||
registered = true;
|
||||
ServiceInstanceMetadataUtils.registerMetadataAndInstance(applicationModel);
|
||||
|
||||
ServiceInstanceMetadataUtils.registerMetadataAndInstance(applicationModel);
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error(CONFIG_REGISTER_INSTANCE_ERROR, "configuration server disconnected", "", "Register instance error.", e);
|
||||
}
|
||||
|
|
@ -1011,7 +1036,7 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
|
||||
private void doOffline(ProviderModel.RegisterStatedURL statedURL) {
|
||||
RegistryFactory registryFactory =
|
||||
statedURL.getRegistryUrl().getOrDefaultApplicationModel().getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
|
||||
statedURL.getRegistryUrl().getOrDefaultApplicationModel().getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
|
||||
Registry registry = registryFactory.getRegistry(statedURL.getRegistryUrl());
|
||||
registry.unregister(statedURL.getProviderUrl());
|
||||
statedURL.setRegistered(false);
|
||||
|
|
@ -1065,7 +1090,7 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
public void checkState(ModuleModel moduleModel, DeployState moduleState) {
|
||||
synchronized (stateLock) {
|
||||
if (!moduleModel.isInternal() && moduleState == DeployState.STARTED) {
|
||||
prepareApplicationInstance();
|
||||
prepareApplicationInstance(moduleModel);
|
||||
}
|
||||
DeployState newState = calculateState();
|
||||
switch (newState) {
|
||||
|
|
@ -1167,8 +1192,8 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
}
|
||||
}
|
||||
|
||||
private void exportMetadataService() {
|
||||
if (!isStarting()) {
|
||||
private void doExportMetadataService() {
|
||||
if (!isStarting() && !isStarted()) {
|
||||
return;
|
||||
}
|
||||
for (DeployListener<ApplicationModel> listener : listeners) {
|
||||
|
|
@ -1302,9 +1327,12 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
|
|||
}
|
||||
}
|
||||
|
||||
private ApplicationConfig getApplication() {
|
||||
private ApplicationConfig getApplicationOrElseThrow() {
|
||||
return configManager.getApplicationOrElseThrow();
|
||||
}
|
||||
|
||||
private Optional<ApplicationConfig> getApplication() {
|
||||
return configManager.getApplication();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,6 +87,9 @@ public class DefaultModuleDeployer extends AbstractDeployer<ModuleModel> impleme
|
|||
private Boolean background;
|
||||
private Boolean exportAsync;
|
||||
private Boolean referAsync;
|
||||
|
||||
private boolean registryInteracted;
|
||||
|
||||
private CompletableFuture<?> exportFuture;
|
||||
private CompletableFuture<?> referFuture;
|
||||
|
||||
|
|
@ -439,6 +442,10 @@ public class DefaultModuleDeployer extends AbstractDeployer<ModuleModel> impleme
|
|||
exportedServices.add(sc);
|
||||
}
|
||||
}
|
||||
|
||||
if (serviceConfig.hasRegistrySpecified()) {
|
||||
registryInteracted = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void registerServiceInternal(ServiceConfigBase sc) {
|
||||
|
|
@ -578,4 +585,13 @@ public class DefaultModuleDeployer extends AbstractDeployer<ModuleModel> impleme
|
|||
this.initialize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRegistryInteraction() {
|
||||
return registryInteracted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApplicationDeployer getApplicationDeployer() {
|
||||
return applicationDeployer;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,6 @@ import org.apache.dubbo.rpc.cluster.LoadBalance;
|
|||
import org.apache.dubbo.rpc.cluster.filter.ClusterFilter;
|
||||
import org.apache.dubbo.rpc.model.ScopeModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModelUtil;
|
||||
import org.apache.dubbo.rpc.support.MockInvoker;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
|
@ -101,7 +100,6 @@ import static org.apache.dubbo.common.constants.CommonConstants.SHUTDOWN_WAIT_SE
|
|||
import static org.apache.dubbo.common.constants.CommonConstants.THREADPOOL_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.USERNAME_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_CLASS_NOT_FOUND;
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_PARAMETER_FORMAT_ERROR;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.DEFAULT_REGISTER_MODE_ALL;
|
||||
import static org.apache.dubbo.common.constants.RegistryConstants.DEFAULT_REGISTER_MODE_INSTANCE;
|
||||
|
|
@ -124,6 +122,7 @@ import static org.apache.dubbo.config.Constants.LAYER_KEY;
|
|||
import static org.apache.dubbo.config.Constants.NAME;
|
||||
import static org.apache.dubbo.config.Constants.ORGANIZATION;
|
||||
import static org.apache.dubbo.config.Constants.OWNER;
|
||||
import static org.apache.dubbo.config.Constants.REGISTER_KEY;
|
||||
import static org.apache.dubbo.config.Constants.STATUS_KEY;
|
||||
import static org.apache.dubbo.monitor.Constants.LOGSTAT_PROTOCOL;
|
||||
import static org.apache.dubbo.registry.Constants.REGISTER_IP_KEY;
|
||||
|
|
@ -225,7 +224,10 @@ public class ConfigValidationUtils {
|
|||
.setScopeModel(interfaceConfig.getScopeModel())
|
||||
.build();
|
||||
// provider delay register state will be checked in RegistryProtocol#export
|
||||
if (provider || url.getParameter(SUBSCRIBE_KEY, true)) {
|
||||
if (provider && url.getParameter(REGISTER_KEY, true)) {
|
||||
registryList.add(url);
|
||||
}
|
||||
if (!provider && url.getParameter(SUBSCRIBE_KEY, true)) {
|
||||
registryList.add(url);
|
||||
}
|
||||
}
|
||||
|
|
@ -350,45 +352,6 @@ public class ConfigValidationUtils {
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Legitimacy check and setup of local simulated operations. The operations can be a string with Simple operation or
|
||||
* a classname whose {@link Class} implements a particular function
|
||||
*
|
||||
* @param interfaceClass for provider side, it is the {@link Class} of the service that will be exported; for consumer
|
||||
* side, it is the {@link Class} of the remote service interface that will be referenced
|
||||
*/
|
||||
public static void checkMock(Class<?> interfaceClass, AbstractInterfaceConfig config) {
|
||||
String mock = config.getMock();
|
||||
if (ConfigUtils.isEmpty(mock)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String normalizedMock = MockInvoker.normalizeMock(mock);
|
||||
if (normalizedMock.startsWith(RETURN_PREFIX)) {
|
||||
normalizedMock = normalizedMock.substring(RETURN_PREFIX.length()).trim();
|
||||
try {
|
||||
//Check whether the mock value is legal, if it is illegal, throw exception
|
||||
MockInvoker.parseMockValue(normalizedMock);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Illegal mock return in <dubbo:service/reference ... " +
|
||||
"mock=\"" + mock + "\" />");
|
||||
}
|
||||
} else if (normalizedMock.startsWith(THROW_PREFIX)) {
|
||||
normalizedMock = normalizedMock.substring(THROW_PREFIX.length()).trim();
|
||||
if (ConfigUtils.isNotEmpty(normalizedMock)) {
|
||||
try {
|
||||
//Check whether the mock value is legal
|
||||
MockInvoker.getThrowable(normalizedMock);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Illegal mock throw in <dubbo:service/reference ... " +
|
||||
"mock=\"" + mock + "\" />");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//Check whether the mock class is a implementation of the interfaceClass, and if it has a default constructor
|
||||
MockInvoker.getMockObject(config.getScopeModel().getExtensionDirector(), normalizedMock, interfaceClass);
|
||||
}
|
||||
}
|
||||
|
||||
public static void validateAbstractInterfaceConfig(AbstractInterfaceConfig config) {
|
||||
checkName(LOCAL_KEY, config.getLocal());
|
||||
|
|
@ -500,7 +463,7 @@ public class ConfigValidationUtils {
|
|||
try {
|
||||
ClassUtils.forName("org.apache.dubbo.qos.protocol.QosProtocolWrapper");
|
||||
} catch (ClassNotFoundException e) {
|
||||
logger.warn(COMMON_CLASS_NOT_FOUND, "", "", "No QosProtocolWrapper class was found. Please check the dependency of dubbo-qos whether was imported correctly.", e);
|
||||
logger.info("QosProtocolWrapper not found, qos will not be enabled, please check if 'dubbo-qos' dependency was imported correctly.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@ import org.apache.dubbo.rpc.Protocol;
|
|||
import org.apache.dubbo.rpc.ProxyFactory;
|
||||
import org.apache.dubbo.rpc.cluster.filter.FilterChainBuilder;
|
||||
import org.apache.dubbo.rpc.cluster.support.registry.ZoneAwareClusterInvoker;
|
||||
import org.apache.dubbo.rpc.cluster.support.wrapper.MockClusterInvoker;
|
||||
import org.apache.dubbo.rpc.cluster.support.wrapper.ScopeClusterInvoker;
|
||||
import org.apache.dubbo.rpc.listener.ListenerInvokerWrapper;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
|
@ -418,8 +417,9 @@ class ReferenceConfigTest {
|
|||
Assertions.assertTrue(referenceConfig.getInvoker() instanceof ScopeClusterInvoker);
|
||||
ScopeClusterInvoker<?> scopeClusterInvoker = (ScopeClusterInvoker<?>) referenceConfig.getInvoker();
|
||||
Invoker<?> mockInvoker = scopeClusterInvoker.getInvoker();
|
||||
Assertions.assertTrue(mockInvoker instanceof MockClusterInvoker);
|
||||
Invoker<?> withCount = ((MockClusterInvoker<?>) mockInvoker).getDirectory().getAllInvokers().get(0);
|
||||
// Assertions.assertTrue(mockInvoker instanceof MockClusterInvoker);
|
||||
// Invoker<?> withCount = ((MockClusterInvoker<?>) mockInvoker).getDirectory().getAllInvokers().get(0);
|
||||
Invoker<?> withCount = scopeClusterInvoker.getDirectory().getAllInvokers().get(0);
|
||||
|
||||
Assertions.assertTrue(withCount instanceof ReferenceCountInvokerWrapper);
|
||||
Invoker<?> withFilter = ((ReferenceCountInvokerWrapper<?>) withCount).getInvoker();
|
||||
|
|
@ -525,7 +525,7 @@ class ReferenceConfigTest {
|
|||
referenceConfig.init();
|
||||
Assertions.assertTrue(referenceConfig.getInvoker() instanceof ScopeClusterInvoker);
|
||||
Invoker scopeClusterInvoker = referenceConfig.getInvoker();
|
||||
Assertions.assertTrue(((ScopeClusterInvoker) scopeClusterInvoker).getInvoker() instanceof MockClusterInvoker);
|
||||
// Assertions.assertTrue(((ScopeClusterInvoker) scopeClusterInvoker).getInvoker() instanceof MockClusterInvoker);
|
||||
Assertions.assertEquals(Boolean.TRUE, ((ScopeClusterInvoker) scopeClusterInvoker).getInvoker().getUrl().getAttribute(PEER_KEY));
|
||||
dubboBootstrap.destroy();
|
||||
|
||||
|
|
@ -1040,6 +1040,7 @@ class ReferenceConfigTest {
|
|||
referenceConfig1.setRegistry(new RegistryConfig(zkUrl1));
|
||||
referenceConfig1.setScopeModel(moduleModel);
|
||||
referenceConfig1.setScope("remote");
|
||||
referenceConfig1.setTimeout(30000);
|
||||
Object object1 = referenceConfig1.get();
|
||||
|
||||
java.lang.reflect.Method callBean1 = object1.getClass().getDeclaredMethod("call", requestClazzOrigin);
|
||||
|
|
|
|||
|
|
@ -186,8 +186,9 @@ class ServiceConfigTest {
|
|||
assertThat(url.getParameters(), hasKey(METHODS_KEY));
|
||||
assertThat(url.getParameters().get(METHODS_KEY), containsString("echo"));
|
||||
assertThat(url.getParameters(), hasEntry(SIDE_KEY, PROVIDER));
|
||||
// export MetadataService and DemoService in "mockprotocol2" protocol.
|
||||
Mockito.verify(protocolDelegate, times(2)).export(Mockito.any(Invoker.class));
|
||||
// export DemoService in "mockprotocol2" protocol.
|
||||
Mockito.verify(protocolDelegate, times(1)).export(Mockito.any(Invoker.class));
|
||||
// MetadataService will be exported on either dubbo or triple (the only two default acceptable protocol)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -351,8 +352,8 @@ class ServiceConfigTest {
|
|||
assertThat(url.getParameters(), hasKey(METHODS_KEY));
|
||||
assertThat(url.getParameters().get(METHODS_KEY), containsString("echo"));
|
||||
assertThat(url.getParameters(), hasEntry(SIDE_KEY, PROVIDER));
|
||||
// export MetadataService and DemoService in "mockprotocol2" protocol.
|
||||
Mockito.verify(protocolDelegate, times(2)).export(Mockito.any(Invoker.class));
|
||||
// export DemoService in "mockprotocol2" protocol (MetadataService will be not exported if no registry specified)
|
||||
Mockito.verify(protocolDelegate, times(1)).export(Mockito.any(Invoker.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
package org.apache.dubbo.config.deploy;
|
||||
|
||||
import org.apache.dubbo.common.utils.Assert;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.metrics.utils.MetricsSupportUtil;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
|
@ -26,7 +26,7 @@ class DefaultApplicationDeployerTest {
|
|||
|
||||
@Test
|
||||
void isSupportPrometheus() {
|
||||
boolean supportPrometheus = new DefaultApplicationDeployer(ApplicationModel.defaultModel()).isSupportPrometheus();
|
||||
Assert.assertTrue(supportPrometheus,"DefaultApplicationDeployer.isSupportPrometheus() should return true");
|
||||
boolean supportPrometheus = MetricsSupportUtil.isSupportPrometheus();
|
||||
Assert.assertTrue(supportPrometheus, "MetricsSupportUtil.isSupportPrometheus() should return true");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.apache.dubbo.rpc.Constants.SCOPE_LOCAL;
|
||||
|
||||
|
|
@ -159,13 +158,9 @@ class MultipleRegistryCenterExportMetadataIntegrationTest implements Integration
|
|||
// 1. Metadata Service exporter with Injvm protocol
|
||||
// 2. MultipleRegistryCenterExportMetadataService exporter with Injvm protocol
|
||||
Assertions.assertEquals(exporterListener.getExportedExporters().size(), 2);
|
||||
List<Exporter<?>> injvmExporters = exporterListener.getExportedExporters()
|
||||
.stream()
|
||||
.filter(
|
||||
exporter -> PROTOCOL_NAME.equalsIgnoreCase(exporter.getInvoker().getUrl().getProtocol())
|
||||
).collect(Collectors.toList());
|
||||
List<Exporter<?>> injvmExporters = exporterListener.getExportedExporters();
|
||||
// Make sure there two injvmExporters
|
||||
Assertions.assertEquals(injvmExporters.size(), 2);
|
||||
Assertions.assertEquals(2, injvmExporters.size());
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
|
|
@ -178,4 +173,4 @@ class MultipleRegistryCenterExportMetadataIntegrationTest implements Integration
|
|||
serviceListener = null;
|
||||
logger.info(getClass().getSimpleName() + " testcase is ending...");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.apache.dubbo.rpc.Constants.SCOPE_LOCAL;
|
||||
|
||||
|
|
@ -155,13 +154,9 @@ class SingleRegistryCenterExportMetadataIntegrationTest implements IntegrationTe
|
|||
// 1. Metadata Service exporter with Injvm protocol
|
||||
// 2. SingleRegistryCenterExportMetadataService exporter with Injvm protocol
|
||||
Assertions.assertEquals(exporterListener.getExportedExporters().size(), 2);
|
||||
List<Exporter<?>> injvmExporters = exporterListener.getExportedExporters()
|
||||
.stream()
|
||||
.filter(
|
||||
exporter -> PROTOCOL_NAME.equalsIgnoreCase(exporter.getInvoker().getUrl().getProtocol())
|
||||
).collect(Collectors.toList());
|
||||
List<Exporter<?>> injvmExporters = exporterListener.getExportedExporters();
|
||||
// Make sure there are 2 injvmExporters
|
||||
Assertions.assertEquals(injvmExporters.size(), 2);
|
||||
Assertions.assertEquals(2, injvmExporters.size());
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
|
|
@ -174,4 +169,4 @@ class SingleRegistryCenterExportMetadataIntegrationTest implements IntegrationTe
|
|||
serviceListener = null;
|
||||
logger.info(getClass().getSimpleName() + " testcase is ending...");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ class MetadataServiceURLParamsMetadataCustomizerTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
void test() {
|
||||
void test() throws InterruptedException {
|
||||
DubboBootstrap providerBootstrap = DubboBootstrap.newInstance();
|
||||
ServiceConfig<DemoService> serviceConfig = new ServiceConfig<>();
|
||||
serviceConfig.setInterface(DemoService.class);
|
||||
|
|
@ -90,8 +90,10 @@ class MetadataServiceURLParamsMetadataCustomizerTest {
|
|||
|
||||
ApplicationModel applicationModel = providerBootstrap.getApplicationModel();
|
||||
MetadataServiceURLParamsMetadataCustomizer customizer = new MetadataServiceURLParamsMetadataCustomizer();
|
||||
customizer.customize(instance, applicationModel);
|
||||
|
||||
Thread.sleep(5000);// wait for service delay export
|
||||
|
||||
customizer.customize(instance, applicationModel);
|
||||
String val = instance.getMetadata().get(METADATA_SERVICE_URL_PARAMS_PROPERTY_NAME);
|
||||
Assertions.assertNotNull(val);
|
||||
|
||||
|
|
|
|||
|
|
@ -20,9 +20,6 @@ import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
|||
import org.apache.dubbo.config.AbstractInterfaceConfig;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.MetadataReportConfig;
|
||||
import org.apache.dubbo.config.api.Greeting;
|
||||
import org.apache.dubbo.config.mock.GreetingMock1;
|
||||
import org.apache.dubbo.config.mock.GreetingMock2;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
|
@ -33,9 +30,8 @@ import java.lang.reflect.Field;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_CLASS_NOT_FOUND;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
|
@ -43,35 +39,6 @@ import static org.mockito.Mockito.verify;
|
|||
|
||||
class ConfigValidationUtilsTest {
|
||||
|
||||
|
||||
@Test
|
||||
void checkMock1() {
|
||||
Assertions.assertThrows(IllegalStateException.class, () -> {
|
||||
InterfaceConfig interfaceConfig = new InterfaceConfig();
|
||||
interfaceConfig.setMock("return {a, b}");
|
||||
ConfigValidationUtils.checkMock(Greeting.class, interfaceConfig);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void checkMock2() {
|
||||
Assertions.assertThrows(IllegalStateException.class, () -> {
|
||||
InterfaceConfig interfaceConfig = new InterfaceConfig();
|
||||
interfaceConfig.setMock(GreetingMock1.class.getName());
|
||||
ConfigValidationUtils.checkMock(Greeting.class, interfaceConfig);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void checkMock3() {
|
||||
Assertions.assertThrows(IllegalStateException.class, () -> {
|
||||
InterfaceConfig interfaceConfig = new InterfaceConfig();
|
||||
interfaceConfig.setMock(GreetingMock2.class.getName());
|
||||
ConfigValidationUtils.checkMock(Greeting.class, interfaceConfig);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testValidateMetadataConfig() {
|
||||
MetadataReportConfig config = new MetadataReportConfig();
|
||||
|
|
@ -137,11 +104,11 @@ class ConfigValidationUtilsTest {
|
|||
config.setName("testName");
|
||||
config.setQosEnable(false);
|
||||
mock.validateApplicationConfig(config);
|
||||
verify(loggerMock, never()).warn(any(), any());
|
||||
verify(loggerMock, never()).warn(any(), any(Throwable.class));
|
||||
|
||||
config.setQosEnable(true);
|
||||
mock.validateApplicationConfig(config);
|
||||
verify(loggerMock).warn(eq(COMMON_CLASS_NOT_FOUND), eq(""), eq(""), eq("No QosProtocolWrapper class was found. Please check the dependency of dubbo-qos whether was imported correctly."), any());
|
||||
verify(loggerMock).info(anyString());
|
||||
}
|
||||
|
||||
private void injectField(Field field, Object newValue) throws Exception {
|
||||
|
|
|
|||
|
|
@ -124,6 +124,42 @@
|
|||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-plugin-context</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-plugin-generic-invoke</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-plugin-classloader-filter</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-plugin-access-log</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-monitor-common</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.dubbo</groupId>
|
||||
<artifactId>dubbo-plugin-qos-trace</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</artifactId>
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import org.apache.dubbo.common.utils.Assert;
|
|||
import org.apache.dubbo.common.utils.ClassUtils;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.config.ReferenceConfig;
|
||||
import org.apache.dubbo.config.spring.aot.AotWithSpringDetector;
|
||||
import org.apache.dubbo.config.spring.context.DubboConfigApplicationListener;
|
||||
import org.apache.dubbo.config.spring.context.DubboConfigBeanInitializer;
|
||||
import org.apache.dubbo.config.spring.reference.ReferenceAttributes;
|
||||
|
|
@ -83,14 +84,14 @@ import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROXY_FAILED
|
|||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* Or register ReferenceBean in xml:
|
||||
* <pre class="code">
|
||||
* <dubbo:reference id="helloService" interface="org.apache.dubbo.config.spring.api.HelloService"/>
|
||||
* <!-- As GenericService -->
|
||||
* <dubbo:reference id="genericHelloService" interface="org.apache.dubbo.config.spring.api.HelloService" generic="true"/>
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* Step 2: Inject ReferenceBean by @Autowired
|
||||
* <pre class="code">
|
||||
* public class FooController {
|
||||
|
|
@ -102,12 +103,11 @@ import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROXY_FAILED
|
|||
* }
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* @see org.apache.dubbo.config.annotation.DubboReference
|
||||
* @see org.apache.dubbo.config.spring.reference.ReferenceBeanBuilder
|
||||
*/
|
||||
public class ReferenceBean<T> implements FactoryBean<T>,
|
||||
ApplicationContextAware, BeanClassLoaderAware, BeanNameAware, InitializingBean, DisposableBean {
|
||||
ApplicationContextAware, BeanClassLoaderAware, BeanNameAware, InitializingBean, DisposableBean {
|
||||
private final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(getClass());
|
||||
private transient ApplicationContext applicationContext;
|
||||
|
||||
|
|
@ -149,7 +149,7 @@ public class ReferenceBean<T> implements FactoryBean<T>,
|
|||
private ReferenceBeanManager referenceBeanManager;
|
||||
|
||||
// Registration sources of this reference, may be xml file or annotation location
|
||||
private List<Map<String,Object>> sources = new ArrayList<>();
|
||||
private List<Map<String, Object>> sources = new ArrayList<>();
|
||||
|
||||
public ReferenceBean() {
|
||||
super();
|
||||
|
|
@ -179,24 +179,23 @@ public class ReferenceBean<T> implements FactoryBean<T>,
|
|||
*
|
||||
* <p></p>
|
||||
* Why we need a lazy proxy?
|
||||
*
|
||||
* <p>
|
||||
* <p/>
|
||||
* When Spring searches beans by type, if Spring cannot determine the type of a factory bean, it may try to initialize it.
|
||||
* The ReferenceBean is also a FactoryBean.
|
||||
* <br/>
|
||||
* (This has already been resolved by decorating the BeanDefinition: {@link DubboBeanDefinitionParser#configReferenceBean})
|
||||
*
|
||||
* <p>
|
||||
* <p/>
|
||||
* In addition, if some ReferenceBeans are dependent on beans that are initialized very early,
|
||||
* and dubbo config beans are not ready yet, there will be many unexpected problems if initializing the dubbo reference immediately.
|
||||
*
|
||||
* <p>
|
||||
* <p/>
|
||||
* When it is initialized, only a lazy proxy object will be created,
|
||||
* and dubbo reference-related resources will not be initialized.
|
||||
* <br/>
|
||||
* In this way, the influence of Spring is eliminated, and the dubbo configuration initialization is controllable.
|
||||
*
|
||||
*
|
||||
* @see DubboConfigBeanInitializer
|
||||
* @see ReferenceBeanManager#initReferenceBean(ReferenceBean)
|
||||
* @see DubboBeanDefinitionParser#configReferenceBean
|
||||
|
|
@ -227,8 +226,14 @@ public class ReferenceBean<T> implements FactoryBean<T>,
|
|||
// pre init xml reference bean or @DubboReference annotation
|
||||
Assert.notEmptyString(getId(), "The id of ReferenceBean cannot be empty");
|
||||
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(getId());
|
||||
this.interfaceClass = (Class<?>) beanDefinition.getAttribute(ReferenceAttributes.INTERFACE_CLASS);
|
||||
this.interfaceName = (String) beanDefinition.getAttribute(ReferenceAttributes.INTERFACE_NAME);
|
||||
if (AotWithSpringDetector.useGeneratedArtifacts()) {
|
||||
this.interfaceClass = (Class<?>) beanDefinition.getPropertyValues().get(ReferenceAttributes.INTERFACE_CLASS);
|
||||
this.interfaceName = (String) beanDefinition.getPropertyValues().get(ReferenceAttributes.INTERFACE_NAME);
|
||||
|
||||
} else {
|
||||
this.interfaceClass = (Class<?>) beanDefinition.getAttribute(ReferenceAttributes.INTERFACE_CLASS);
|
||||
this.interfaceName = (String) beanDefinition.getAttribute(ReferenceAttributes.INTERFACE_NAME);
|
||||
}
|
||||
Assert.notNull(this.interfaceClass, "The interface class of ReferenceBean is not initialized");
|
||||
|
||||
if (beanDefinition.hasAttribute(Constants.REFERENCE_PROPS)) {
|
||||
|
|
@ -280,6 +285,7 @@ public class ReferenceBean<T> implements FactoryBean<T>,
|
|||
|
||||
/**
|
||||
* The interface of this ReferenceBean, for injection purpose
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Class<?> getInterfaceClass() {
|
||||
|
|
@ -415,4 +421,11 @@ public class ReferenceBean<T> implements FactoryBean<T>,
|
|||
}
|
||||
}
|
||||
|
||||
public void setInterfaceClass(Class<?> interfaceClass) {
|
||||
this.interfaceClass = interfaceClass;
|
||||
}
|
||||
|
||||
public void setInterfaceName(String interfaceName) {
|
||||
this.interfaceName = interfaceName;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import org.springframework.aop.support.AopUtils;
|
|||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
|
|
@ -52,6 +53,12 @@ public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean
|
|||
|
||||
private ApplicationEventPublisher applicationEventPublisher;
|
||||
|
||||
@Autowired
|
||||
public ServiceBean(ModuleModel moduleModel) {
|
||||
super(moduleModel);
|
||||
this.service = null;
|
||||
}
|
||||
|
||||
public ServiceBean(ApplicationContext applicationContext) {
|
||||
super();
|
||||
this.service = null;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* 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.aot;
|
||||
|
||||
import org.apache.dubbo.common.aot.NativeDetector;
|
||||
import org.springframework.core.SpringProperties;
|
||||
|
||||
public abstract class AotWithSpringDetector {
|
||||
|
||||
/**
|
||||
* System property that indicates the application should run with AOT
|
||||
* generated artifacts. If such optimizations are not available, it is
|
||||
* recommended to throw an exception rather than fall back to the regular
|
||||
* runtime behavior.
|
||||
*/
|
||||
public static final String AOT_ENABLED = "spring.aot.enabled";
|
||||
|
||||
/**
|
||||
* Determine whether AOT optimizations must be considered at runtime. This
|
||||
* is mandatory in a native image but can be triggered on the JVM using
|
||||
* the {@value #AOT_ENABLED} Spring property.
|
||||
*
|
||||
* @return whether AOT optimizations must be considered
|
||||
*/
|
||||
public static boolean useGeneratedArtifacts() {
|
||||
return (NativeDetector.inNativeImage() || SpringProperties.getFlag(AOT_ENABLED));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -369,6 +369,11 @@ public abstract class AbstractAnnotationBeanPostProcessor implements
|
|||
if (targetClass.isAssignableFrom(clazz) && clazz.getName().contains("$$EnhancerBySpringCGLIB$$")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (targetClass.isAssignableFrom(clazz) && clazz.getName().contains("$$SpringCGLIB$$")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -378,11 +383,11 @@ public abstract class AbstractAnnotationBeanPostProcessor implements
|
|||
*/
|
||||
protected class AnnotatedInjectElement extends InjectionMetadata.InjectedElement {
|
||||
|
||||
protected final AnnotationAttributes attributes;
|
||||
public final AnnotationAttributes attributes;
|
||||
|
||||
protected volatile Object injectedObject;
|
||||
public volatile Object injectedObject;
|
||||
|
||||
private Class<?> injectedType;
|
||||
public Class<?> injectedType;
|
||||
|
||||
protected AnnotatedInjectElement(Member member, PropertyDescriptor pd, AnnotationAttributes attributes) {
|
||||
super(member, pd);
|
||||
|
|
@ -439,7 +444,7 @@ public abstract class AbstractAnnotationBeanPostProcessor implements
|
|||
|
||||
protected class AnnotatedMethodElement extends AnnotatedInjectElement {
|
||||
|
||||
protected final Method method;
|
||||
public final Method method;
|
||||
|
||||
protected AnnotatedMethodElement(Method method, PropertyDescriptor pd, AnnotationAttributes attributes) {
|
||||
super(method, pd, attributes);
|
||||
|
|
@ -449,7 +454,7 @@ public abstract class AbstractAnnotationBeanPostProcessor implements
|
|||
|
||||
public class AnnotatedFieldElement extends AnnotatedInjectElement {
|
||||
|
||||
protected final Field field;
|
||||
public final Field field;
|
||||
|
||||
protected AnnotatedFieldElement(Field field, AnnotationAttributes attributes) {
|
||||
super(field, null, attributes);
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ public class ReferenceAnnotationBeanPostProcessor extends AbstractAnnotationBean
|
|||
/**
|
||||
* The bean name of {@link ReferenceAnnotationBeanPostProcessor}
|
||||
*/
|
||||
public static final String BEAN_NAME = "referenceAnnotationBeanPostProcessor";
|
||||
public static final String BEAN_NAME = ReferenceAnnotationBeanPostProcessor.class.getName();
|
||||
|
||||
/**
|
||||
* Cache size
|
||||
|
|
@ -110,10 +110,10 @@ public class ReferenceAnnotationBeanPostProcessor extends AbstractAnnotationBean
|
|||
private final ConcurrentMap<InjectionMetadata.InjectedElement, String> injectedMethodReferenceBeanCache =
|
||||
new ConcurrentHashMap<>(CACHE_SIZE);
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
protected ApplicationContext applicationContext;
|
||||
|
||||
private ReferenceBeanManager referenceBeanManager;
|
||||
private BeanDefinitionRegistry beanDefinitionRegistry;
|
||||
protected ReferenceBeanManager referenceBeanManager;
|
||||
protected BeanDefinitionRegistry beanDefinitionRegistry;
|
||||
|
||||
/**
|
||||
* {@link com.alibaba.dubbo.config.annotation.Reference @com.alibaba.dubbo.config.annotation.Reference} has been supported since 2.7.3
|
||||
|
|
@ -211,7 +211,7 @@ public class ReferenceAnnotationBeanPostProcessor extends AbstractAnnotationBean
|
|||
* @param beanName
|
||||
* @param beanDefinition
|
||||
*/
|
||||
private void processReferenceAnnotatedBeanDefinition(String beanName, AnnotatedBeanDefinition beanDefinition) {
|
||||
protected void processReferenceAnnotatedBeanDefinition(String beanName, AnnotatedBeanDefinition beanDefinition) {
|
||||
|
||||
MethodMetadata factoryMethodMetadata = SpringCompatUtils.getFactoryMethodMetadata(beanDefinition);
|
||||
|
||||
|
|
@ -315,6 +315,7 @@ public class ReferenceAnnotationBeanPostProcessor extends AbstractAnnotationBean
|
|||
* Alternatives to the {@link #postProcessProperties(PropertyValues, Object, String)}, that removed as of Spring
|
||||
* Framework 6.0.0, and in favor of {@link #postProcessProperties(PropertyValues, Object, String)}.
|
||||
* <p>In order to be compatible with the lower version of Spring, it is still retained.
|
||||
*
|
||||
* @see #postProcessProperties
|
||||
*/
|
||||
public PropertyValues postProcessPropertyValues(
|
||||
|
|
@ -324,6 +325,7 @@ public class ReferenceAnnotationBeanPostProcessor extends AbstractAnnotationBean
|
|||
|
||||
/**
|
||||
* Alternatives to the {@link #postProcessPropertyValues(PropertyValues, PropertyDescriptor[], Object, String)}.
|
||||
*
|
||||
* @see #postProcessPropertyValues
|
||||
*/
|
||||
@Override
|
||||
|
|
@ -418,7 +420,7 @@ public class ReferenceAnnotationBeanPostProcessor extends AbstractAnnotationBean
|
|||
boolean isContains;
|
||||
if ((isContains = beanDefinitionRegistry.containsBeanDefinition(referenceBeanName)) || beanDefinitionRegistry.isAlias(referenceBeanName)) {
|
||||
String preReferenceBeanName = referenceBeanName;
|
||||
if (!isContains){
|
||||
if (!isContains) {
|
||||
// Look in the alias for the origin bean name
|
||||
String[] aliases = beanDefinitionRegistry.getAliases(referenceBeanName);
|
||||
if (ArrayUtils.isNotEmpty(aliases)) {
|
||||
|
|
@ -498,6 +500,9 @@ public class ReferenceAnnotationBeanPostProcessor extends AbstractAnnotationBean
|
|||
beanDefinition.setAttribute(ReferenceAttributes.INTERFACE_CLASS, interfaceClass);
|
||||
beanDefinition.setAttribute(ReferenceAttributes.INTERFACE_NAME, interfaceName);
|
||||
|
||||
beanDefinition.getPropertyValues().add(ReferenceAttributes.INTERFACE_CLASS, interfaceClass);
|
||||
beanDefinition.getPropertyValues().add(ReferenceAttributes.INTERFACE_NAME, interfaceName);
|
||||
|
||||
// create decorated definition for reference bean, Avoid being instantiated when getting the beanType of ReferenceBean
|
||||
// see org.springframework.beans.factory.support.AbstractBeanFactory#getTypeForFactoryBean()
|
||||
GenericBeanDefinition targetDefinition = new GenericBeanDefinition();
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue