Compare commits
216 Commits
3.2
...
3.3-dev-xd
| Author | SHA1 | Date |
|---|---|---|
|
|
4b79a5facc | |
|
|
9926a93223 | |
|
|
b338e20190 | |
|
|
944be946ac | |
|
|
0cce4c8afe | |
|
|
d5c484a643 | |
|
|
0f8be9ec93 | |
|
|
9b3a32f8d6 | |
|
|
1145b4015b | |
|
|
cf53c38179 | |
|
|
da2dd6d2a1 | |
|
|
cb92fcc19e | |
|
|
b14e5e3a12 | |
|
|
9b3073c2f4 | |
|
|
76390eed4e | |
|
|
3f2e0e18c9 | |
|
|
22b3c29b08 | |
|
|
1dd289d405 | |
|
|
0fa88a1180 | |
|
|
044a775373 | |
|
|
97d5563990 | |
|
|
70b1ecb662 | |
|
|
e2ea0046d2 | |
|
|
d5b7941c63 | |
|
|
a1bfa7b8f7 | |
|
|
ce570dd932 | |
|
|
2dde7ac09e | |
|
|
e60f24cb7f | |
|
|
9211a91d1c | |
|
|
c38fa0ac8b | |
|
|
46af145730 | |
|
|
bfd748ee5d | |
|
|
74dd87c15b | |
|
|
d018475f73 | |
|
|
2a0755c279 | |
|
|
cb5ff2aace | |
|
|
36e0ee0a96 | |
|
|
3de3ccf457 | |
|
|
5b0b86b11d | |
|
|
6118aa55f2 | |
|
|
2f4a78ee38 | |
|
|
0fccd2ccae | |
|
|
ad803e1c84 | |
|
|
8f7446c81d | |
|
|
c8f7269e41 | |
|
|
0c766ad462 | |
|
|
4737eafcb4 | |
|
|
5cf765889e | |
|
|
c302fcccd8 | |
|
|
40201078b0 | |
|
|
74978ca003 | |
|
|
40f44f91f5 | |
|
|
93ec8e368d | |
|
|
af0f45f7cd | |
|
|
3f48269562 | |
|
|
7e0954b8cf | |
|
|
a53228d545 | |
|
|
650ee3b9d4 | |
|
|
f441e79d8d | |
|
|
633bdbd08f | |
|
|
7a44bb8ba1 | |
|
|
fe4a9f3592 | |
|
|
3aacb6642c | |
|
|
976516cbc1 | |
|
|
39611ea28c | |
|
|
31712083f4 | |
|
|
c877d6e6f9 | |
|
|
a3096054ed | |
|
|
c3b0c2eefa | |
|
|
865f68bdc5 | |
|
|
2b62e88974 | |
|
|
90bc72e641 | |
|
|
d979b211ce | |
|
|
88deb9be3d | |
|
|
d9743aa86e | |
|
|
c7e548d9a2 | |
|
|
70469346b2 | |
|
|
647f58a02b | |
|
|
e155591adb | |
|
|
35b6682393 | |
|
|
26b9f3e48d | |
|
|
48c82c0462 | |
|
|
35b4c0aba9 | |
|
|
a46188082c | |
|
|
d00757e65b | |
|
|
539bb11ae7 | |
|
|
a15ab195c6 | |
|
|
f635de7ba2 | |
|
|
cd35ca829a | |
|
|
7188a3a5cb | |
|
|
9681515f18 | |
|
|
ba94cf0b17 | |
|
|
d0c41f512e | |
|
|
c98c4873ff | |
|
|
0562b64828 | |
|
|
7696e1b42c | |
|
|
027aba599e | |
|
|
3e50bdd16f | |
|
|
8bdcaf6865 | |
|
|
c72c55aa67 | |
|
|
bbee466e44 | |
|
|
acee3e2f03 | |
|
|
a709b2803c | |
|
|
1848e400a0 | |
|
|
0dab17f11d | |
|
|
2bf662ce90 | |
|
|
d050b9c6ec | |
|
|
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 |
39
.artifacts
39
.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,13 +28,12 @@ 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
|
||||
dubbo-container
|
||||
dubbo-container-api
|
||||
dubbo-container-spring
|
||||
dubbo-core-spi
|
||||
dubbo-dependencies
|
||||
dubbo-dependencies-all
|
||||
|
|
@ -42,13 +41,13 @@ dubbo-dependencies-bom
|
|||
dubbo-dependencies-zookeeper
|
||||
dubbo-dependencies-zookeeper-curator5
|
||||
dubbo-distribution
|
||||
dubbo-filter
|
||||
dubbo-filter-cache
|
||||
dubbo-filter-validation
|
||||
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 +60,9 @@ dubbo-metrics-metadata
|
|||
dubbo-metrics-prometheus
|
||||
dubbo-metrics-registry
|
||||
dubbo-metrics-config-center
|
||||
dubbo-monitor
|
||||
dubbo-monitor-api
|
||||
dubbo-monitor-default
|
||||
dubbo-metrics-netty
|
||||
dubbo-metrics-event
|
||||
dubbo-native
|
||||
dubbo-native-plugin
|
||||
dubbo-parent
|
||||
dubbo-plugin
|
||||
dubbo-qos
|
||||
|
|
@ -77,11 +74,14 @@ dubbo-registry-multicast
|
|||
dubbo-registry-multiple
|
||||
dubbo-registry-nacos
|
||||
dubbo-registry-zookeeper
|
||||
dubbo-xds
|
||||
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 +102,25 @@ 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-loom
|
||||
dubbo-rest-jaxrs
|
||||
dubbo-rest-servlet
|
||||
dubbo-rest-spring
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -97,7 +97,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:
|
||||
|
|
@ -238,7 +238,7 @@ jobs:
|
|||
openssl rsautl -decrypt -in ${{ github.workspace }}/.tmp/encrypted-sonarcloud-token -out ${{ github.workspace }}/.tmp/decrypted-sonarcloud-token -inkey ${{ github.workspace }}/.tmp/rsa/rsa_private.pem
|
||||
- name: "Test with Maven with SonarCloud Scan"
|
||||
if: ${{ github.repository == 'apache/dubbo' }}
|
||||
timeout-minutes: 70
|
||||
timeout-minutes: 90
|
||||
env:
|
||||
# Needed to get some information about the pull request, if any
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
|
@ -247,7 +247,7 @@ jobs:
|
|||
./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Pjacoco,jdk15ge-simple,'!jdk15ge',jacoco089 -Dsonar.host.url=https://sonarcloud.io -Dsonar.organization=apache -Dsonar.projectKey=apache_dubbo -DtrimStackTrace=false -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Dmaven.wagon.http.retryHandler.count=5 -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Dcheckstyle_unix.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper -Dsonar.coverage.jacoco.xmlReportPaths=dubbo-test/dubbo-dependencies-all/target/site/jacoco-aggregate/jacoco.xml -Dsonar.login=${SONAR_TOKEN}
|
||||
- name: "Test with Maven without SonarCloud Scan"
|
||||
if: ${{ github.repository != 'apache/dubbo' }}
|
||||
timeout-minutes: 70
|
||||
timeout-minutes: 90
|
||||
run: |
|
||||
./mvnw --batch-mode --no-snapshot-updates -e --no-transfer-progress --fail-fast clean test verify -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -Pjacoco,jdk15ge-simple,'!jdk15ge',jacoco089 -DtrimStackTrace=false -Dmaven.wagon.http.retryHandler.count=5 -DskipTests=false -DskipIntegrationTests=false -Dcheckstyle.skip=false -Dcheckstyle_unix.skip=false -Drat.skip=false -Dmaven.javadoc.skip=true -DembeddedZookeeperPath=${{ github.workspace }}/.tmp/zookeeper
|
||||
- name: "Upload coverage result"
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ jobs:
|
|||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'zulu'
|
||||
java-version: 21
|
||||
java-version: 8
|
||||
- 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, 21 ]
|
||||
jdk: [ 17, 21 ]
|
||||
env:
|
||||
DISABLE_FILE_SYSTEM_TEST: true
|
||||
steps:
|
||||
|
|
@ -175,7 +175,7 @@ jobs:
|
|||
fail-fast: false
|
||||
matrix:
|
||||
os: [ ubuntu-latest, windows-latest ]
|
||||
jdk: [ 8, 11, 17, 21 ]
|
||||
jdk: [ 17, 21 ]
|
||||
env:
|
||||
DISABLE_FILE_SYSTEM_TEST: true
|
||||
DUBBO_DEFAULT_SERIALIZATION: fastjson2
|
||||
|
|
|
|||
|
|
@ -11,8 +11,6 @@ target/
|
|||
.settings/
|
||||
.project
|
||||
.classpath
|
||||
.externalToolBuilders
|
||||
maven-eclipse.xml
|
||||
|
||||
# idea ignore
|
||||
.idea/
|
||||
|
|
@ -52,6 +50,3 @@ dubbo-demo/dubbo-demo-triple/build/*
|
|||
|
||||
.git.exec.error
|
||||
|
||||
# log files generated by testcase.
|
||||
dubbo-rpc/dubbo-rpc-api/custom-access.log*
|
||||
|
||||
|
|
|
|||
|
|
@ -95,11 +95,15 @@ 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'
|
||||
- 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/DubboProtocCompilerMojo.java'
|
||||
- 'dubbo-plugin/dubbo-compiler/src/main/java/org/apache/dubbo/gen/utils/ProtoTypeMap.java'
|
||||
|
||||
comment: on-failure
|
||||
|
||||
|
|
@ -198,10 +202,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
|
||||
|
|
|
|||
20
NOTICE
20
NOTICE
|
|
@ -16,3 +16,23 @@ Copyright 2014 The Netty Project
|
|||
This product contains code form the t-digest Project:
|
||||
The code for the t-digest was originally authored by Ted Dunning
|
||||
Adrien Grand contributed the heart of the AVLTreeDigest (https://github.com/jpountz)
|
||||
|
||||
This product contains the following code copied from Maven Protocol Buffers Plugin:
|
||||
dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/protoc/DubboProtocCompilerMojo.java
|
||||
|
||||
Maven Protocol Buffers Plugin
|
||||
=============================
|
||||
Copyright (c) 2016 Maven Protocol Buffers Plugin Authors. All rights reserved.
|
||||
|
||||
This product contains the following code copied from grpc-java-contrib:
|
||||
dubbo-plugin/dubbo-compiler/src/main/java/org/apache/dubbo/gen/utils/ProtoTypeMap.java
|
||||
Some portions of this file Copyright (c) 2019, Salesforce.com, Inc. and licensed under the BSD 3-Clause License
|
||||
|
||||
grpc-java-contrib
|
||||
====================
|
||||
Copyright (c) 2019, Salesforce.com, Inc.
|
||||
All rights reserved.
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
236
README.md
236
README.md
|
|
@ -1,187 +1,68 @@
|
|||
# Apache Dubbo Project
|
||||
|
||||
[](https://github.com/apache/dubbo/actions/workflows/build-and-test-pr.yml)
|
||||
[](https://codecov.io/gh/apache/dubbo)
|
||||
[](https://codecov.io/gh/apache/dubbo)
|
||||

|
||||

|
||||
[](http://isitmaintained.com/project/apache/dubbo "Average time to resolve an issue")
|
||||
[](http://isitmaintained.com/project/apache/dubbo "Percentage of issues still open")
|
||||
|
||||
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 [Wanted: who's using dubbo](https://github.com/apache/dubbo/discussions/13842), thanks :)
|
||||
|
||||
## 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.13-SNAPSHOT</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
|
||||
| **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 |
|
||||
|
||||
```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.
|
||||
## Contributing
|
||||
See [CONTRIBUTING](https://github.com/apache/dubbo/blob/master/CONTRIBUTING.md) for details on submitting patches and the contribution workflow.
|
||||
|
||||
### How does the Dubbo Community collaborate?
|
||||
|
||||
|
|
@ -242,13 +123,39 @@ Please follow the [template](https://github.com/apache/dubbo/issues/new?template
|
|||
Please report security vulnerabilities to [us](mailto:security@dubbo.apache.org) privately.
|
||||
|
||||
## 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)
|
||||
* 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.
|
||||
|
||||
## Contributing
|
||||
|
||||
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
|
||||
|
||||
|
|
@ -268,5 +175,4 @@ Please report security vulnerabilities to [us](mailto:security@dubbo.apache.org)
|
|||
* [Erlang](https://github.com/apache/dubbo-erlang)
|
||||
|
||||
## 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,6 +29,5 @@ 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
|
||||
|
|
|
|||
|
|
@ -1,89 +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>
|
||||
<spotless-maven-plugin.version>2.43.0</spotless-maven-plugin.version>
|
||||
<spotless.action>check</spotless.action>
|
||||
<dubbo-shared-resources.version>1.0.0</dubbo-shared-resources.version>
|
||||
<palantirJavaFormat.version>2.38.0</palantirJavaFormat.version>
|
||||
</properties>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>java11+</id>
|
||||
<activation>
|
||||
<jdk>[11,)</jdk>
|
||||
</activation>
|
||||
<build>
|
||||
<!--- newer versions of plugins requires JDK 11 -->
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.diffplug.spotless</groupId>
|
||||
<artifactId>spotless-maven-plugin</artifactId>
|
||||
<version>${spotless-maven-plugin.version}</version>
|
||||
<configuration>
|
||||
<java>
|
||||
<palantirJavaFormat>
|
||||
<version>${palantirJavaFormat.version}</version>
|
||||
</palantirJavaFormat>
|
||||
<removeUnusedImports />
|
||||
<importOrder>
|
||||
<file>dubbo-importorder.txt</file>
|
||||
</importOrder>
|
||||
<licenseHeader>
|
||||
<file>checkstyle-header.txt</file>
|
||||
</licenseHeader>
|
||||
</java>
|
||||
<pom>
|
||||
<sortPom>
|
||||
<expandEmptyElements>false</expandEmptyElements>
|
||||
<spaceBeforeCloseEmptyElement>true</spaceBeforeCloseEmptyElement>
|
||||
</sortPom>
|
||||
</pom>
|
||||
<upToDateChecking>
|
||||
<enabled>true</enabled>
|
||||
</upToDateChecking>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>dubbo-shared-resources</artifactId>
|
||||
<version>${dubbo-shared-resources.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>${spotless.action}</goal>
|
||||
</goals>
|
||||
<phase>process-sources</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
</project>
|
||||
|
|
@ -92,6 +92,11 @@
|
|||
<artifactId>micrometer-tracing-integration-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-slf4j-impl</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
|
|
|
|||
|
|
@ -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,9 @@ 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);
|
||||
}
|
||||
public void initializeModuleModel(ModuleModel moduleModel) {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import org.apache.dubbo.common.URL;
|
|||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.Protocol;
|
||||
import org.apache.dubbo.rpc.RpcException;
|
||||
|
||||
import java.util.List;
|
||||
|
|
@ -98,4 +99,8 @@ public interface Directory<T> extends Node {
|
|||
default boolean isNotificationReceived() {
|
||||
return false;
|
||||
}
|
||||
|
||||
default Protocol getProtocol() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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 org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
|
||||
import org.apache.dubbo.rpc.cluster.merger.MergerFactory;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModelInitializer;
|
||||
|
||||
public class MergeableClusterScopeModelInitializer implements ScopeModelInitializer {
|
||||
@Override
|
||||
public void initializeFrameworkModel(FrameworkModel frameworkModel) {}
|
||||
|
||||
@Override
|
||||
public void initializeApplicationModel(ApplicationModel applicationModel) {
|
||||
ScopeBeanFactory beanFactory = applicationModel.getBeanFactory();
|
||||
beanFactory.registerBean(MergerFactory.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeModuleModel(ModuleModel moduleModel) {}
|
||||
}
|
||||
|
|
@ -212,7 +212,7 @@ public class SingleRouterChain<T> {
|
|||
public RouterSnapshotNode<T> buildRouterSnapshot(
|
||||
URL url, BitList<Invoker<T>> availableInvokers, Invocation invocation) {
|
||||
BitList<Invoker<T>> resultInvokers = availableInvokers.clone();
|
||||
RouterSnapshotNode<T> parentNode = new RouterSnapshotNode<>("Parent", resultInvokers.clone());
|
||||
RouterSnapshotNode<T> parentNode = new RouterSnapshotNode<T>("Parent", resultInvokers.clone());
|
||||
parentNode.setNodeOutputInvokers(resultInvokers.clone());
|
||||
|
||||
// 1. route state router
|
||||
|
|
@ -227,7 +227,7 @@ public class SingleRouterChain<T> {
|
|||
return parentNode;
|
||||
}
|
||||
|
||||
RouterSnapshotNode<T> commonRouterNode = new RouterSnapshotNode<>("CommonRouter", resultInvokers.clone());
|
||||
RouterSnapshotNode<T> commonRouterNode = new RouterSnapshotNode<T>("CommonRouter", resultInvokers.clone());
|
||||
parentNode.appendNode(commonRouterNode);
|
||||
List<Invoker<T>> commonRouterResult = resultInvokers;
|
||||
|
||||
|
|
@ -237,7 +237,7 @@ public class SingleRouterChain<T> {
|
|||
List<Invoker<T>> inputInvokers = new ArrayList<>(commonRouterResult);
|
||||
|
||||
RouterSnapshotNode<T> currentNode =
|
||||
new RouterSnapshotNode<>(router.getClass().getSimpleName(), inputInvokers);
|
||||
new RouterSnapshotNode<T>(router.getClass().getSimpleName(), inputInvokers);
|
||||
|
||||
// append to router node chain
|
||||
commonRouterNode.appendNode(currentNode);
|
||||
|
|
|
|||
|
|
@ -223,7 +223,7 @@ public abstract class AbstractConfigurator implements Configurator {
|
|||
}
|
||||
|
||||
private Set<String> genConditionKeys() {
|
||||
Set<String> conditionKeys = new HashSet<>();
|
||||
Set<String> conditionKeys = new HashSet<String>();
|
||||
conditionKeys.add(CATEGORY_KEY);
|
||||
conditionKeys.add(Constants.CHECK_KEY);
|
||||
conditionKeys.add(DYNAMIC_KEY);
|
||||
|
|
|
|||
|
|
@ -14,11 +14,10 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.monitor.support;
|
||||
package org.apache.dubbo.rpc.cluster.filter.support;
|
||||
|
||||
import org.apache.dubbo.common.extension.Activate;
|
||||
import org.apache.dubbo.rpc.Filter;
|
||||
import org.apache.dubbo.rpc.cluster.filter.support.ConsumerContextFilter;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.CALLBACK;
|
||||
|
|
@ -46,7 +46,8 @@ public class ConsistentHashLoadBalance extends AbstractLoadBalance {
|
|||
*/
|
||||
public static final String HASH_ARGUMENTS = "hash.arguments";
|
||||
|
||||
private final ConcurrentMap<String, ConsistentHashSelector<?>> selectors = new ConcurrentHashMap<>();
|
||||
private final ConcurrentMap<String, ConsistentHashSelector<?>> selectors =
|
||||
new ConcurrentHashMap<String, ConsistentHashSelector<?>>();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
|
|
@ -74,7 +75,7 @@ public class ConsistentHashLoadBalance extends AbstractLoadBalance {
|
|||
private final int[] argumentIndex;
|
||||
|
||||
ConsistentHashSelector(List<Invoker<T>> invokers, String methodName, int identityHashCode) {
|
||||
this.virtualInvokers = new TreeMap<>();
|
||||
this.virtualInvokers = new TreeMap<Long, Invoker<T>>();
|
||||
this.identityHashCode = identityHashCode;
|
||||
URL url = invokers.get(0).getUrl();
|
||||
this.replicaNumber = url.getMethodParameter(methodName, HASH_NODES, 160);
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ public class MapMerger implements Merger<Map<?, ?>> {
|
|||
if (ArrayUtils.isEmpty(items)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
Map<Object, Object> result = new HashMap<>();
|
||||
Map<Object, Object> result = new HashMap<Object, Object>();
|
||||
Stream.of(items).filter(Objects::nonNull).forEach(result::putAll);
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ public class MergerFactory implements ScopeModelAware {
|
|||
|
||||
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(MergerFactory.class);
|
||||
|
||||
private ConcurrentMap<Class<?>, Merger<?>> MERGER_CACHE = new ConcurrentHashMap<>();
|
||||
private ConcurrentMap<Class<?>, Merger<?>> MERGER_CACHE = new ConcurrentHashMap<Class<?>, Merger<?>>();
|
||||
private ScopeModel scopeModel;
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ public class SetMerger implements Merger<Set<?>> {
|
|||
if (ArrayUtils.isEmpty(items)) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
Set<Object> result = new HashSet<>();
|
||||
Set<Object> result = new HashSet<Object>();
|
||||
Stream.of(items).filter(Objects::nonNull).forEach(result::addAll);
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,6 @@ public class ConditionStateRouterFactory extends CacheableStateRouterFactory {
|
|||
|
||||
@Override
|
||||
protected <T> StateRouter<T> createRouter(Class<T> interfaceClass, URL url) {
|
||||
return new ConditionStateRouter<>(url);
|
||||
return new ConditionStateRouter<T>(url);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,6 @@ public class ServiceStateRouterFactory extends CacheableStateRouterFactory {
|
|||
|
||||
@Override
|
||||
protected <T> StateRouter<T> createRouter(Class<T> interfaceClass, URL url) {
|
||||
return new ServiceStateRouter<>(url);
|
||||
return new ServiceStateRouter<T>(url);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.rpc.cluster.router.mesh;
|
||||
|
||||
import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
|
||||
import org.apache.dubbo.rpc.cluster.router.mesh.route.MeshRuleManager;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||
import org.apache.dubbo.rpc.model.ScopeModelInitializer;
|
||||
|
||||
public class MeshScopeModelInitializer implements ScopeModelInitializer {
|
||||
@Override
|
||||
public void initializeFrameworkModel(FrameworkModel frameworkModel) {}
|
||||
|
||||
@Override
|
||||
public void initializeApplicationModel(ApplicationModel applicationModel) {}
|
||||
|
||||
public void initializeModuleModel(ModuleModel moduleModel) {
|
||||
ScopeBeanFactory beanFactory = moduleModel.getBeanFactory();
|
||||
beanFactory.registerBean(MeshRuleManager.class);
|
||||
}
|
||||
}
|
||||
|
|
@ -136,7 +136,7 @@ public class MeshRuleCache<T> {
|
|||
Collections.unmodifiableMap(totalSubsetMap),
|
||||
unmatchedInvokers);
|
||||
} else {
|
||||
return new MeshRuleCache<>(
|
||||
return new MeshRuleCache<T>(
|
||||
Collections.emptyList(), Collections.emptyMap(), Collections.emptyMap(), invokers);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,6 @@ public class MockStateRouterFactory implements StateRouterFactory {
|
|||
|
||||
@Override
|
||||
public <T> StateRouter<T> getRouter(Class<T> interfaceClass, URL url) {
|
||||
return new MockInvokersSelector<>(url);
|
||||
return new MockInvokersSelector<T>(url);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,23 +93,23 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
}
|
||||
|
||||
// Provided by BitList only
|
||||
public synchronized List<E> getOriginList() {
|
||||
public List<E> getOriginList() {
|
||||
return originList;
|
||||
}
|
||||
|
||||
public synchronized void addIndex(int index) {
|
||||
public void addIndex(int index) {
|
||||
this.rootSet.set(index);
|
||||
}
|
||||
|
||||
public synchronized int totalSetSize() {
|
||||
public int totalSetSize() {
|
||||
return this.originList.size();
|
||||
}
|
||||
|
||||
public synchronized boolean indexExist(int index) {
|
||||
public boolean indexExist(int index) {
|
||||
return this.rootSet.get(index);
|
||||
}
|
||||
|
||||
public synchronized E getByIndex(int index) {
|
||||
public E getByIndex(int index) {
|
||||
return this.originList.get(index);
|
||||
}
|
||||
|
||||
|
|
@ -120,7 +120,7 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
* @param target target bitList
|
||||
* @return this bitList only contains those elements contain in both two list and source bitList's tailList
|
||||
*/
|
||||
public synchronized BitList<E> and(BitList<E> target) {
|
||||
public BitList<E> and(BitList<E> target) {
|
||||
rootSet.and(target.rootSet);
|
||||
if (target.getTailList() != null) {
|
||||
target.getTailList().forEach(this::addToTailList);
|
||||
|
|
@ -128,28 +128,28 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
return this;
|
||||
}
|
||||
|
||||
public synchronized BitList<E> or(BitList<E> target) {
|
||||
public BitList<E> or(BitList<E> target) {
|
||||
BitSet resultSet = (BitSet) rootSet.clone();
|
||||
resultSet.or(target.rootSet);
|
||||
return new BitList<>(originList, resultSet, tailList);
|
||||
}
|
||||
|
||||
public synchronized boolean hasMoreElementInTailList() {
|
||||
public boolean hasMoreElementInTailList() {
|
||||
return CollectionUtils.isNotEmpty(tailList);
|
||||
}
|
||||
|
||||
public synchronized List<E> getTailList() {
|
||||
public List<E> getTailList() {
|
||||
return tailList;
|
||||
}
|
||||
|
||||
public synchronized void addToTailList(E e) {
|
||||
public void addToTailList(E e) {
|
||||
if (tailList == null) {
|
||||
tailList = new LinkedList<>();
|
||||
}
|
||||
tailList.add(e);
|
||||
}
|
||||
|
||||
public synchronized E randomSelectOne() {
|
||||
public E randomSelectOne() {
|
||||
int originSize = originList.size();
|
||||
int tailSize = tailList != null ? tailList.size() : 0;
|
||||
int totalSize = originSize + tailSize;
|
||||
|
|
@ -181,18 +181,18 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
|
||||
// Provided by JDK List interface
|
||||
@Override
|
||||
public synchronized int size() {
|
||||
public int size() {
|
||||
return rootSet.cardinality() + (CollectionUtils.isNotEmpty(tailList) ? tailList.size() : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean contains(Object o) {
|
||||
public boolean contains(Object o) {
|
||||
int idx = originList.indexOf(o);
|
||||
return (idx >= 0 && rootSet.get(idx)) || (CollectionUtils.isNotEmpty(tailList) && tailList.contains(o));
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Iterator<E> iterator() {
|
||||
public Iterator<E> iterator() {
|
||||
return new BitListIterator<>(this, 0);
|
||||
}
|
||||
|
||||
|
|
@ -205,7 +205,7 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
* Notice: It is not recommended adding duplicated element.
|
||||
*/
|
||||
@Override
|
||||
public synchronized boolean add(E e) {
|
||||
public boolean add(E e) {
|
||||
int index = originList.indexOf(e);
|
||||
if (index > -1) {
|
||||
rootSet.set(index);
|
||||
|
|
@ -225,7 +225,7 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
* If the element is not contained in originList, try to remove from tailList.
|
||||
*/
|
||||
@Override
|
||||
public synchronized boolean remove(Object o) {
|
||||
public boolean remove(Object o) {
|
||||
int idx = originList.indexOf(o);
|
||||
if (idx > -1 && rootSet.get(idx)) {
|
||||
rootSet.set(idx, false);
|
||||
|
|
@ -242,7 +242,7 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
* This may change the default behaviour when adding new element later.
|
||||
*/
|
||||
@Override
|
||||
public synchronized void clear() {
|
||||
public void clear() {
|
||||
rootSet.clear();
|
||||
// to remove references
|
||||
originList = Collections.emptyList();
|
||||
|
|
@ -252,7 +252,7 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public synchronized E get(int index) {
|
||||
public E get(int index) {
|
||||
int bitIndex = -1;
|
||||
if (index < 0) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
|
|
@ -272,7 +272,7 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public synchronized E remove(int index) {
|
||||
public E remove(int index) {
|
||||
int bitIndex = -1;
|
||||
if (index >= rootSet.cardinality()) {
|
||||
if (CollectionUtils.isNotEmpty(tailList)) {
|
||||
|
|
@ -290,7 +290,7 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public synchronized int indexOf(Object o) {
|
||||
public int indexOf(Object o) {
|
||||
int bitIndex = -1;
|
||||
for (int i = 0; i < rootSet.cardinality(); i++) {
|
||||
bitIndex = rootSet.nextSetBit(bitIndex + 1);
|
||||
|
|
@ -311,7 +311,7 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public synchronized boolean addAll(Collection<? extends E> c) {
|
||||
public boolean addAll(Collection<? extends E> c) {
|
||||
if (c instanceof BitList) {
|
||||
rootSet.or(((BitList<? extends E>) c).rootSet);
|
||||
if (((BitList<? extends E>) c).hasMoreElementInTailList()) {
|
||||
|
|
@ -325,7 +325,7 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public synchronized int lastIndexOf(Object o) {
|
||||
public int lastIndexOf(Object o) {
|
||||
int bitIndex = -1;
|
||||
int index = -1;
|
||||
if (CollectionUtils.isNotEmpty(tailList)) {
|
||||
|
|
@ -344,22 +344,22 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isEmpty() {
|
||||
public boolean isEmpty() {
|
||||
return this.rootSet.isEmpty() && CollectionUtils.isEmpty(tailList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized ListIterator<E> listIterator() {
|
||||
public ListIterator<E> listIterator() {
|
||||
return new BitListIterator<>(this, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized ListIterator<E> listIterator(int index) {
|
||||
public ListIterator<E> listIterator(int index) {
|
||||
return new BitListIterator<>(this, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized BitList<E> subList(int fromIndex, int toIndex) {
|
||||
public BitList<E> subList(int fromIndex, int toIndex) {
|
||||
BitSet resultSet = (BitSet) rootSet.clone();
|
||||
List<E> copiedTailList = tailList == null ? null : new LinkedList<>(tailList);
|
||||
if (toIndex < size()) {
|
||||
|
|
@ -414,7 +414,7 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean hasNext() {
|
||||
public boolean hasNext() {
|
||||
if (isInTailList) {
|
||||
return tailListIterator.hasNext();
|
||||
} else {
|
||||
|
|
@ -428,7 +428,7 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public synchronized E next() {
|
||||
public E next() {
|
||||
if (isInTailList) {
|
||||
if (tailListIterator.hasNext()) {
|
||||
index += 1;
|
||||
|
|
@ -457,7 +457,7 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean hasPrevious() {
|
||||
public boolean hasPrevious() {
|
||||
if (isInTailList) {
|
||||
boolean hasPreviousInTailList = tailListIterator.hasPrevious();
|
||||
if (hasPreviousInTailList) {
|
||||
|
|
@ -471,7 +471,7 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public synchronized E previous() {
|
||||
public E previous() {
|
||||
if (isInTailList) {
|
||||
boolean hasPreviousInTailList = tailListIterator.hasPrevious();
|
||||
if (hasPreviousInTailList) {
|
||||
|
|
@ -503,17 +503,17 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public synchronized int nextIndex() {
|
||||
public int nextIndex() {
|
||||
return hasNext() ? index + 1 : index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int previousIndex() {
|
||||
public int previousIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void remove() {
|
||||
public void remove() {
|
||||
if (lastReturnedIndex == -1) {
|
||||
throw new IllegalStateException();
|
||||
} else {
|
||||
|
|
@ -533,17 +533,17 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public synchronized void set(E e) {
|
||||
public void set(E e) {
|
||||
throw new UnsupportedOperationException("Set method is not supported in BitListIterator!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void add(E e) {
|
||||
public void add(E e) {
|
||||
throw new UnsupportedOperationException("Add method is not supported in BitListIterator!");
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized ArrayList<E> cloneToArrayList() {
|
||||
public ArrayList<E> cloneToArrayList() {
|
||||
if (rootSet.cardinality() == originList.size() && (CollectionUtils.isEmpty(tailList))) {
|
||||
return new ArrayList<>(originList);
|
||||
}
|
||||
|
|
@ -553,7 +553,7 @@ public class BitList<E> extends AbstractList<E> implements Cloneable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public synchronized BitList<E> clone() {
|
||||
public BitList<E> clone() {
|
||||
return new BitList<>(
|
||||
originList, (BitSet) rootSet.clone(), tailList == null ? null : new LinkedList<>(tailList));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ import org.apache.dubbo.rpc.cluster.router.state.BitList;
|
|||
import org.apache.dubbo.rpc.cluster.router.tag.model.TagRouterRule;
|
||||
import org.apache.dubbo.rpc.cluster.router.tag.model.TagRuleParser;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
|
|
@ -52,6 +53,7 @@ public class TagStateRouter<T> extends AbstractStateRouter<T> implements Configu
|
|||
public static final String NAME = "TAG_ROUTER";
|
||||
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(TagStateRouter.class);
|
||||
private static final String RULE_SUFFIX = ".tag-router";
|
||||
public static final char TAG_SEPERATOR = '|';
|
||||
|
||||
private volatile TagRouterRule tagRouterRule;
|
||||
private String application;
|
||||
|
|
@ -119,7 +121,8 @@ public class TagStateRouter<T> extends AbstractStateRouter<T> implements Configu
|
|||
|
||||
// if we are requesting for a Provider with a specific tag
|
||||
if (StringUtils.isNotEmpty(tag)) {
|
||||
Set<String> addresses = tagRouterRuleCopy.getTagnameToAddresses().get(tag);
|
||||
Map<String, Set<String>> tagnameToAddresses = tagRouterRuleCopy.getTagnameToAddresses();
|
||||
Set<String> addresses = selectAddressByTagLevel(tagnameToAddresses, tag, isForceUseTag(invocation));
|
||||
// filter by dynamic tag group first
|
||||
if (addresses != null) { // null means tag not set
|
||||
result = filterInvoker(invokers, invoker -> addressMatches(invoker.getUrl(), addresses));
|
||||
|
|
@ -336,4 +339,34 @@ public class TagStateRouter<T> extends AbstractStateRouter<T> implements Configu
|
|||
public void setTagRouterRule(TagRouterRule tagRouterRule) {
|
||||
this.tagRouterRule = tagRouterRule;
|
||||
}
|
||||
|
||||
/**
|
||||
* select addresses by tag with level
|
||||
* <p>
|
||||
* example:
|
||||
* selector=beta|team1|partner1
|
||||
* step1.select tagAddresses with selector=beta|team1|partner1, if result is empty, then run step2
|
||||
* step2.select tagAddresses with selector=beta|team1, if result is empty, then run step3
|
||||
* step3.select tagAddresses with selector=beta, if result is empty, result is null
|
||||
* </p>
|
||||
*
|
||||
* @param tagAddresses
|
||||
* @param tagSelector eg: beta|team1|partner1
|
||||
* @return
|
||||
*/
|
||||
public static Set<String> selectAddressByTagLevel(
|
||||
Map<String, Set<String>> tagAddresses, String tagSelector, boolean isForce) {
|
||||
if (isForce || StringUtils.isNotContains(tagSelector, TAG_SEPERATOR)) {
|
||||
return tagAddresses.get(tagSelector);
|
||||
}
|
||||
String[] selectors = StringUtils.split(tagSelector, TAG_SEPERATOR);
|
||||
for (int i = selectors.length; i > 0; i--) {
|
||||
String selectorTmp = StringUtils.join(selectors, TAG_SEPERATOR, 0, i);
|
||||
Set<String> addresses = tagAddresses.get(selectorTmp);
|
||||
if (CollectionUtils.isNotEmpty(addresses)) {
|
||||
return addresses;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,6 @@ public class TagStateRouterFactory extends CacheableStateRouterFactory {
|
|||
|
||||
@Override
|
||||
protected <T> StateRouter<T> createRouter(Class<T> interfaceClass, URL url) {
|
||||
return new TagStateRouter<>(url);
|
||||
return new TagStateRouter<T>(url);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,8 +63,8 @@ public class FailoverClusterInvoker<T> extends AbstractClusterInvoker<T> {
|
|||
int len = calculateInvokeTimes(methodName);
|
||||
// retry loop.
|
||||
RpcException le = null; // last exception.
|
||||
List<Invoker<T>> invoked = new ArrayList<>(copyInvokers.size()); // invoked invokers.
|
||||
Set<String> providers = new HashSet<>(len);
|
||||
List<Invoker<T>> invoked = new ArrayList<Invoker<T>>(copyInvokers.size()); // invoked invokers.
|
||||
Set<String> providers = new HashSet<String>(len);
|
||||
for (int i = 0; i < len; i++) {
|
||||
// Reselect before retry to avoid a change of candidate `invokers`.
|
||||
// NOTE: if `invokers` changed, then `invoked` also lose accuracy.
|
||||
|
|
|
|||
|
|
@ -26,6 +26,6 @@ public class MergeableCluster extends AbstractCluster {
|
|||
|
||||
@Override
|
||||
public <T> AbstractClusterInvoker<T> doJoin(Directory<T> directory) throws RpcException {
|
||||
return new MergeableClusterInvoker<>(directory);
|
||||
return new MergeableClusterInvoker<T>(directory);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
|||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.utils.ConfigUtils;
|
||||
import org.apache.dubbo.rpc.AsyncRpcResult;
|
||||
import org.apache.dubbo.rpc.Constants;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.Result;
|
||||
|
|
@ -42,8 +43,6 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_FAILED_GROUP_MERGE;
|
||||
import static org.apache.dubbo.rpc.Constants.ASYNC_KEY;
|
||||
import static org.apache.dubbo.rpc.Constants.MERGER_KEY;
|
||||
|
||||
/**
|
||||
|
|
@ -95,7 +94,7 @@ public class MergeableClusterInvoker<T> extends AbstractClusterInvoker<T> {
|
|||
Map<String, Result> results = new HashMap<>();
|
||||
for (final Invoker<T> invoker : invokers) {
|
||||
RpcInvocation subInvocation = new RpcInvocation(invocation, invoker);
|
||||
subInvocation.setAttachment(ASYNC_KEY, "true");
|
||||
subInvocation.setAttachment(Constants.ASYNC_KEY, "true");
|
||||
try {
|
||||
results.put(invoker.getUrl().getServiceKey(), invokeWithContext(invoker, subInvocation));
|
||||
} catch (RpcException e) {
|
||||
|
|
@ -123,7 +122,7 @@ public class MergeableClusterInvoker<T> extends AbstractClusterInvoker<T> {
|
|||
Result r = asyncResult.get(Integer.MAX_VALUE, TimeUnit.MILLISECONDS);
|
||||
if (r.hasException()) {
|
||||
log.error(
|
||||
CLUSTER_FAILED_GROUP_MERGE,
|
||||
LoggerCodeConstants.CLUSTER_FAILED_GROUP_MERGE,
|
||||
"Invoke " + getGroupDescFromServiceKey(entry.getKey()) + " failed: "
|
||||
+ r.getException().getMessage(),
|
||||
"",
|
||||
|
|
|
|||
|
|
@ -27,6 +27,6 @@ public class ZoneAwareCluster extends AbstractCluster {
|
|||
|
||||
@Override
|
||||
protected <T> AbstractClusterInvoker<T> doJoin(Directory<T> directory) throws RpcException {
|
||||
return new ZoneAwareClusterInvoker<>(directory);
|
||||
return new ZoneAwareClusterInvoker<T>(directory);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import org.apache.dubbo.common.logger.LoggerFactory;
|
|||
import org.apache.dubbo.common.utils.CollectionUtils;
|
||||
import org.apache.dubbo.common.utils.ConfigUtils;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.common.utils.SystemPropertyConfigUtils;
|
||||
import org.apache.dubbo.rpc.AsyncRpcResult;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.InvokeMode;
|
||||
|
|
@ -47,8 +48,8 @@ import static org.apache.dubbo.rpc.cluster.Constants.INVOCATION_NEED_MOCK;
|
|||
public class MockClusterInvoker<T> implements ClusterInvoker<T> {
|
||||
|
||||
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(MockClusterInvoker.class);
|
||||
private static final boolean setFutureWhenSync =
|
||||
Boolean.parseBoolean(System.getProperty(CommonConstants.SET_FUTURE_IN_SYNC_MODE, "true"));
|
||||
private static final boolean setFutureWhenSync = Boolean.parseBoolean(SystemPropertyConfigUtils.getSystemProperty(
|
||||
CommonConstants.ThirdPartyProperty.SET_FUTURE_IN_SYNC_MODE, "true"));
|
||||
|
||||
private final Directory<T> directory;
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ public class MockClusterWrapper implements Cluster {
|
|||
|
||||
@Override
|
||||
public <T> Invoker<T> join(Directory<T> directory, boolean buildFilterChain) throws RpcException {
|
||||
return new MockClusterInvoker<>(directory, this.cluster.join(directory, buildFilterChain));
|
||||
return new MockClusterInvoker<T>(directory, this.cluster.join(directory, buildFilterChain));
|
||||
}
|
||||
|
||||
public Cluster getCluster() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
callback-consumer-context=org.apache.dubbo.rpc.cluster.filter.support.CallbackConsumerContextFilter
|
||||
|
|
@ -8,4 +8,4 @@ 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
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,4 +1,3 @@
|
|||
attachment=org.apache.dubbo.rpc.cluster.router.condition.matcher.attachment.AttachmentConditionMatcherFactory
|
||||
argument=org.apache.dubbo.rpc.cluster.router.condition.matcher.argument.ArgumentConditionMatcherFactory
|
||||
param=org.apache.dubbo.rpc.cluster.router.condition.matcher.param.UrlParamConditionMatcherFactory
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
tag=org.apache.dubbo.rpc.cluster.router.tag.TagStateRouterFactory
|
||||
mock=org.apache.dubbo.rpc.cluster.router.mock.MockStateRouterFactory
|
||||
condition=org.apache.dubbo.rpc.cluster.router.condition.ConditionStateRouterFactory
|
||||
service=org.apache.dubbo.rpc.cluster.router.condition.config.ServiceStateRouterFactory
|
||||
app=org.apache.dubbo.rpc.cluster.router.condition.config.AppStateRouterFactory
|
||||
provider-app=org.apache.dubbo.rpc.cluster.router.condition.config.ProviderAppStateRouterFactory
|
||||
script-app=org.apache.dubbo.rpc.cluster.router.script.config.AppScriptRouterFactory
|
||||
mock=org.apache.dubbo.rpc.cluster.router.mock.MockStateRouterFactory
|
||||
standard-mesh-rule=org.apache.dubbo.rpc.cluster.router.mesh.route.StandardMeshRuleRouterFactory
|
||||
script-app=org.apache.dubbo.rpc.cluster.router.script.config.AppScriptRouterFactory
|
||||
tag=org.apache.dubbo.rpc.cluster.router.tag.TagStateRouterFactory
|
||||
|
|
|
|||
|
|
@ -1 +1,3 @@
|
|||
dubbo-cluster=org.apache.dubbo.rpc.cluster.ClusterScopeModelInitializer
|
||||
dubbo-cluster-mergeable=org.apache.dubbo.rpc.cluster.MergeableClusterScopeModelInitializer
|
||||
mesh=org.apache.dubbo.rpc.cluster.router.mesh.MeshScopeModelInitializer
|
||||
|
|
|
|||
|
|
@ -1,264 +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;
|
||||
|
||||
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 java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
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 static final 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 static final 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,83 +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});
|
||||
}
|
||||
}
|
||||
|
|
@ -22,8 +22,6 @@ import java.util.HashSet;
|
|||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
|
@ -578,44 +576,4 @@ class BitListTest {
|
|||
set.add(new LinkedList<>(Arrays.asList("A", "B", "C", "D", "E", "F", "G")));
|
||||
Assertions.assertEquals(2, set.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConcurrent() throws InterruptedException {
|
||||
for (int i = 0; i < 100000; i++) {
|
||||
BitList<String> bitList = new BitList<>(Collections.singletonList("test"));
|
||||
bitList.remove("test");
|
||||
|
||||
CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||
CountDownLatch countDownLatch2 = new CountDownLatch(2);
|
||||
|
||||
Thread thread1 = new Thread(() -> {
|
||||
try {
|
||||
countDownLatch.await();
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
bitList.add("test");
|
||||
countDownLatch2.countDown();
|
||||
});
|
||||
|
||||
AtomicReference<BitList<String>> ref = new AtomicReference<>();
|
||||
Thread thread2 = new Thread(() -> {
|
||||
try {
|
||||
countDownLatch.await();
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
ref.set(bitList.clone());
|
||||
countDownLatch2.countDown();
|
||||
});
|
||||
|
||||
thread1.start();
|
||||
thread2.start();
|
||||
|
||||
countDownLatch.countDown();
|
||||
countDownLatch2.await();
|
||||
|
||||
Assertions.assertDoesNotThrow(() -> ref.get().iterator().hasNext());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,12 +18,10 @@ package org.apache.dubbo.rpc.cluster.router.tag;
|
|||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
|
||||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
import org.apache.dubbo.common.utils.Holder;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.RpcInvocation;
|
||||
import org.apache.dubbo.rpc.cluster.router.MockInvoker;
|
||||
import org.apache.dubbo.rpc.cluster.router.mesh.util.TracingContextProvider;
|
||||
import org.apache.dubbo.rpc.cluster.router.state.BitList;
|
||||
import org.apache.dubbo.rpc.cluster.router.state.StateRouter;
|
||||
import org.apache.dubbo.rpc.cluster.router.tag.model.TagRouterRule;
|
||||
|
|
@ -32,10 +30,12 @@ import org.apache.dubbo.rpc.model.ApplicationModel;
|
|||
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
|
@ -48,7 +48,6 @@ class TagStateRouterTest {
|
|||
private URL url;
|
||||
private ModuleModel originModel;
|
||||
private ModuleModel moduleModel;
|
||||
private Set<TracingContextProvider> tracingContextProviders;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
|
|
@ -59,11 +58,6 @@ class TagStateRouterTest {
|
|||
ScopeBeanFactory beanFactory = Mockito.spy(originBeanFactory);
|
||||
when(moduleModel.getBeanFactory()).thenReturn(beanFactory);
|
||||
|
||||
ExtensionLoader<TracingContextProvider> extensionLoader = Mockito.mock(ExtensionLoader.class);
|
||||
tracingContextProviders = new HashSet<>();
|
||||
when(extensionLoader.getSupportedExtensionInstances()).thenReturn(tracingContextProviders);
|
||||
when(moduleModel.getExtensionLoader(TracingContextProvider.class)).thenReturn(extensionLoader);
|
||||
|
||||
url = URL.valueOf("test://localhost/DemoInterface").setScopeModel(moduleModel);
|
||||
}
|
||||
|
||||
|
|
@ -264,4 +258,44 @@ class TagStateRouterTest {
|
|||
TagRouterRule tagRouterRule = TagRuleParser.parse(tagRouterRuleConfig);
|
||||
return tagRouterRule;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void tagMultiLevelTest() {
|
||||
String tagSelector = "beta|team1|partner1";
|
||||
Set<String> address1 = Sets.newHashSet("192.168.5.1:20880");
|
||||
Map<String, Set<String>> tagAddresses = new HashMap<>();
|
||||
tagAddresses.put("beta", address1);
|
||||
Assertions.assertEquals(address1, TagStateRouter.selectAddressByTagLevel(tagAddresses, tagSelector, false));
|
||||
|
||||
Set<String> address2 = Sets.newHashSet("192.168.5.2:20880");
|
||||
tagAddresses.put("beta|team1", address2);
|
||||
Assertions.assertEquals(address2, TagStateRouter.selectAddressByTagLevel(tagAddresses, tagSelector, false));
|
||||
|
||||
Set<String> address3 = Sets.newHashSet("192.168.5.3:20880");
|
||||
tagAddresses.put("beta|team1|partner1", address3);
|
||||
Assertions.assertEquals(address3, TagStateRouter.selectAddressByTagLevel(tagAddresses, tagSelector, false));
|
||||
|
||||
tagSelector = "beta";
|
||||
Assertions.assertEquals(address1, TagStateRouter.selectAddressByTagLevel(tagAddresses, tagSelector, false));
|
||||
tagSelector = "beta|team1";
|
||||
Assertions.assertEquals(address2, TagStateRouter.selectAddressByTagLevel(tagAddresses, tagSelector, false));
|
||||
tagSelector = "beta|team1|partner1";
|
||||
Assertions.assertEquals(address3, TagStateRouter.selectAddressByTagLevel(tagAddresses, tagSelector, false));
|
||||
|
||||
tagSelector = "beta2";
|
||||
Assertions.assertNull(TagStateRouter.selectAddressByTagLevel(tagAddresses, tagSelector, false));
|
||||
tagSelector = "beta|team2";
|
||||
Assertions.assertEquals(address1, TagStateRouter.selectAddressByTagLevel(tagAddresses, tagSelector, false));
|
||||
tagSelector = "beta|team1|partner2";
|
||||
Assertions.assertEquals(address2, TagStateRouter.selectAddressByTagLevel(tagAddresses, tagSelector, false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void tagLevelForceTest() {
|
||||
Set<String> addresses = Sets.newHashSet("192.168.1.223:20880");
|
||||
Map<String, Set<String>> tagAddresses = new HashMap<>();
|
||||
tagAddresses.put("beta", addresses);
|
||||
Set<String> selectedAddresses = TagStateRouter.selectAddressByTagLevel(tagAddresses, "beta", true);
|
||||
Assertions.assertEquals(addresses, selectedAddresses);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -580,25 +579,5 @@ 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 {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.rpc.support;
|
||||
package org.apache.dubbo.rpc.cluster.support;
|
||||
|
||||
public interface DemoServiceA {
|
||||
String methodA();
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.rpc.support;
|
||||
package org.apache.dubbo.rpc.cluster.support;
|
||||
|
||||
/**
|
||||
* default mock service for DemoServiceA
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.rpc.support;
|
||||
package org.apache.dubbo.rpc.cluster.support;
|
||||
|
||||
public interface DemoServiceB {
|
||||
String methodB();
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.rpc.support;
|
||||
package org.apache.dubbo.rpc.cluster.support;
|
||||
|
||||
/**
|
||||
* default mock service for DemoServiceA
|
||||
|
|
@ -18,6 +18,7 @@ package org.apache.dubbo.rpc.cluster.support;
|
|||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.constants.CommonConstants;
|
||||
import org.apache.dubbo.common.logger.Level;
|
||||
import org.apache.dubbo.common.utils.DubboAppender;
|
||||
import org.apache.dubbo.common.utils.LogUtil;
|
||||
import org.apache.dubbo.rpc.AppResponse;
|
||||
|
|
@ -34,7 +35,6 @@ import java.util.List;
|
|||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.log4j.Level;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
|
|
|||
|
|
@ -14,8 +14,11 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.common.store;
|
||||
package org.apache.dubbo.rpc.cluster.support;
|
||||
|
||||
public interface DataStoreUpdateListener {
|
||||
void onUpdate(String componentName, String key, Object value);
|
||||
import org.apache.dubbo.common.extension.SPI;
|
||||
|
||||
@SPI
|
||||
public interface Greeting {
|
||||
String hello();
|
||||
}
|
||||
|
|
@ -14,6 +14,6 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.config.mock;
|
||||
package org.apache.dubbo.rpc.cluster.support;
|
||||
|
||||
public class GreetingMock1 {}
|
||||
|
|
@ -14,9 +14,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.config.mock;
|
||||
|
||||
import org.apache.dubbo.config.api.Greeting;
|
||||
package org.apache.dubbo.rpc.cluster.support;
|
||||
|
||||
public class GreetingMock2 implements Greeting {
|
||||
private GreetingMock2() {}
|
||||
|
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
* 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.support;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.metrics.event.MetricsDispatcher;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.Result;
|
||||
import org.apache.dubbo.rpc.RpcContext;
|
||||
import org.apache.dubbo.rpc.RpcException;
|
||||
import org.apache.dubbo.rpc.RpcInvocation;
|
||||
import org.apache.dubbo.rpc.cluster.LoadBalance;
|
||||
import org.apache.dubbo.rpc.cluster.directory.StaticDirectory;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.ENABLE_CONNECTIVITY_VALIDATION;
|
||||
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.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* AbstractClusterInvokerTest
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
class MockAbstractClusterInvokerTest {
|
||||
List<Invoker<IHelloService>> invokers = new ArrayList<Invoker<IHelloService>>();
|
||||
List<Invoker<IHelloService>> selectedInvokers = new ArrayList<Invoker<IHelloService>>();
|
||||
AbstractClusterInvoker<IHelloService> cluster;
|
||||
AbstractClusterInvoker<IHelloService> cluster_nocheck;
|
||||
StaticDirectory<IHelloService> dic;
|
||||
RpcInvocation invocation = new RpcInvocation();
|
||||
URL url = URL.valueOf(
|
||||
"registry://localhost:9090/org.apache.dubbo.rpc.cluster.support.AbstractClusterInvokerTest.IHelloService?refer="
|
||||
+ URL.encode("application=abstractClusterInvokerTest"));
|
||||
URL consumerUrl = URL.valueOf(
|
||||
"dubbo://localhost?application=abstractClusterInvokerTest&refer=application%3DabstractClusterInvokerTest");
|
||||
|
||||
Invoker<IHelloService> invoker1;
|
||||
Invoker<IHelloService> invoker2;
|
||||
Invoker<IHelloService> invoker3;
|
||||
Invoker<IHelloService> invoker4;
|
||||
Invoker<IHelloService> invoker5;
|
||||
Invoker<IHelloService> mockedInvoker1;
|
||||
|
||||
@BeforeAll
|
||||
public static void setUpBeforeClass() throws Exception {
|
||||
System.setProperty(ENABLE_CONNECTIVITY_VALIDATION, "false");
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void teardown() throws Exception {
|
||||
RpcContext.removeContext();
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void afterClass() {
|
||||
System.clearProperty(ENABLE_CONNECTIVITY_VALIDATION);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
@BeforeEach
|
||||
public void setUp() throws Exception {
|
||||
ApplicationModel.defaultModel().getBeanFactory().registerBean(MetricsDispatcher.class);
|
||||
Map<String, Object> attributes = new HashMap<>();
|
||||
attributes.put("application", "abstractClusterInvokerTest");
|
||||
url = url.putAttribute(REFER_KEY, attributes);
|
||||
|
||||
invocation.setMethodName("sayHello");
|
||||
|
||||
invoker1 = mock(Invoker.class);
|
||||
invoker2 = mock(Invoker.class);
|
||||
invoker3 = mock(Invoker.class);
|
||||
invoker4 = mock(Invoker.class);
|
||||
invoker5 = mock(Invoker.class);
|
||||
mockedInvoker1 = mock(Invoker.class);
|
||||
|
||||
URL turl = URL.valueOf("test://test:11/test");
|
||||
|
||||
given(invoker1.isAvailable()).willReturn(false);
|
||||
given(invoker1.getInterface()).willReturn(IHelloService.class);
|
||||
given(invoker1.getUrl()).willReturn(turl.setPort(1).addParameter("name", "invoker1"));
|
||||
|
||||
given(invoker2.isAvailable()).willReturn(true);
|
||||
given(invoker2.getInterface()).willReturn(IHelloService.class);
|
||||
given(invoker2.getUrl()).willReturn(turl.setPort(2).addParameter("name", "invoker2"));
|
||||
|
||||
given(invoker3.isAvailable()).willReturn(false);
|
||||
given(invoker3.getInterface()).willReturn(IHelloService.class);
|
||||
given(invoker3.getUrl()).willReturn(turl.setPort(3).addParameter("name", "invoker3"));
|
||||
|
||||
given(invoker4.isAvailable()).willReturn(true);
|
||||
given(invoker4.getInterface()).willReturn(IHelloService.class);
|
||||
given(invoker4.getUrl()).willReturn(turl.setPort(4).addParameter("name", "invoker4"));
|
||||
|
||||
given(invoker5.isAvailable()).willReturn(false);
|
||||
given(invoker5.getInterface()).willReturn(IHelloService.class);
|
||||
given(invoker5.getUrl()).willReturn(turl.setPort(5).addParameter("name", "invoker5"));
|
||||
|
||||
given(mockedInvoker1.isAvailable()).willReturn(false);
|
||||
given(mockedInvoker1.getInterface()).willReturn(IHelloService.class);
|
||||
given(mockedInvoker1.getUrl()).willReturn(turl.setPort(999).setProtocol("mock"));
|
||||
|
||||
invokers.add(invoker1);
|
||||
dic = new StaticDirectory<IHelloService>(url, invokers, null);
|
||||
cluster = new AbstractClusterInvoker(dic) {
|
||||
@Override
|
||||
protected Result doInvoke(Invocation invocation, List invokers, LoadBalance loadbalance)
|
||||
throws RpcException {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
cluster_nocheck =
|
||||
new AbstractClusterInvoker(
|
||||
dic, url.addParameterIfAbsent(CLUSTER_AVAILABLE_CHECK_KEY, Boolean.FALSE.toString())) {
|
||||
@Override
|
||||
protected Result doInvoke(Invocation invocation, List invokers, LoadBalance loadbalance)
|
||||
throws RpcException {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void initlistsize5() {
|
||||
invokers.clear();
|
||||
selectedInvokers
|
||||
.clear(); // Clear first, previous test case will make sure that the right invoker2 will be used.
|
||||
invokers.add(invoker1);
|
||||
invokers.add(invoker2);
|
||||
invokers.add(invoker3);
|
||||
invokers.add(invoker4);
|
||||
invokers.add(invoker5);
|
||||
}
|
||||
|
||||
private void initDic() {
|
||||
dic.notify(invokers);
|
||||
dic.buildRouterChain();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 {}
|
||||
}
|
||||
|
|
@ -14,12 +14,13 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.rpc.support;
|
||||
package org.apache.dubbo.rpc.cluster.support;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.rpc.RpcException;
|
||||
import org.apache.dubbo.rpc.RpcInvocation;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.apache.dubbo.rpc.support.MockInvoker;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Type;
|
||||
|
|
@ -116,7 +117,8 @@ class MockInvokerTest {
|
|||
|
||||
@Test
|
||||
void testGetThrowable() {
|
||||
Assertions.assertThrows(RpcException.class, () -> MockInvoker.getThrowable("Exception.class"));
|
||||
Assertions.assertThrows(
|
||||
RpcException.class, () -> org.apache.dubbo.rpc.support.MockInvoker.getThrowable("Exception.class"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -62,7 +62,7 @@ class MockProviderRpcExceptionTest {
|
|||
.addParameter("invoke_return_error", "true")
|
||||
.addParameter(
|
||||
REFER_KEY,
|
||||
URL.encode(PATH_KEY + "=" + MockProviderRpcExceptionTest.IHelloRpcService.class.getName()
|
||||
URL.encode(PATH_KEY + "=" + IHelloRpcService.class.getName()
|
||||
+ "&" + "mock=true"
|
||||
+ "&" + "proxy=jdk"));
|
||||
Invoker<IHelloRpcService> cluster = getClusterInvoker(url);
|
||||
|
|
|
|||
|
|
@ -1,38 +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.
|
||||
-->
|
||||
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
|
||||
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
|
||||
<appender name="DUBBO" class="org.apache.dubbo.common.utils.DubboAppender">
|
||||
<param name="File" value="../dubbo.log"/>
|
||||
<layout class="org.apache.log4j.PatternLayout">
|
||||
<param name="ConversionPattern" value="[%d{dd/MM/yy HH:mm:ss:SSS z}] %t %5p %c{2}: %m%n"/>
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
|
||||
<layout class="org.apache.log4j.PatternLayout">
|
||||
<param name="ConversionPattern" value="[%d{dd/MM/yy HH:mm:ss:SSS z}] %t %5p %c{2}: %m%n"/>
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<root>
|
||||
<level value="INFO"/>
|
||||
<appender-ref ref="DUBBO"/>
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
</root>
|
||||
</log4j:configuration>
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
<?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.
|
||||
-->
|
||||
<Configuration status="WARN">
|
||||
<Appenders>
|
||||
<Dubbo name="Dubbo" fileName="../dubbo.log">
|
||||
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] %5p %t %c{2}: %m%n%ex" charset="UTF-8"/>
|
||||
</Dubbo>
|
||||
<Console name="Console" target="SYSTEM_OUT" follow="true">
|
||||
<PatternLayout pattern="%d{HH:mm:ss.SSS} |-%highlight{%-5p} [%t] %40.40c:%-3L -| %m%n%rEx{filters(jdk.internal.reflect,java.lang.reflect,sun.reflect,org.junit,org.mockito)}" charset="UTF-8"/>
|
||||
</Console>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
<Root level="info">
|
||||
<AppenderRef ref="Dubbo"/>
|
||||
<AppenderRef ref="Console"/>
|
||||
</Root>
|
||||
</Loggers>
|
||||
</Configuration>
|
||||
|
|
@ -99,6 +99,17 @@
|
|||
<groupId>javax.annotation</groupId>
|
||||
<artifactId>javax.annotation-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cglib</groupId>
|
||||
<artifactId>cglib-nodep</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-slf4j-impl</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.protobuf</groupId>
|
||||
<artifactId>protobuf-java</artifactId>
|
||||
|
|
|
|||
|
|
@ -1295,19 +1295,6 @@ public /*final**/ class URL implements Serializable {
|
|||
return serviceNameBuilder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* The format is "{interface}:[version]"
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getCompatibleColonSeparatedKey() {
|
||||
StringBuilder serviceNameBuilder = new StringBuilder();
|
||||
serviceNameBuilder.append(this.getServiceInterface());
|
||||
compatibleAppend(serviceNameBuilder, VERSION_KEY);
|
||||
compatibleAppend(serviceNameBuilder, GROUP_KEY);
|
||||
return serviceNameBuilder.toString();
|
||||
}
|
||||
|
||||
private void append(StringBuilder target, String parameterName, boolean first) {
|
||||
String parameterValue = this.getParameter(parameterName);
|
||||
if (!isBlank(parameterValue)) {
|
||||
|
|
@ -1320,14 +1307,6 @@ public /*final**/ class URL implements Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
private void compatibleAppend(StringBuilder target, String parameterName) {
|
||||
String parameterValue = this.getParameter(parameterName);
|
||||
if (!isBlank(parameterValue)) {
|
||||
target.append(':');
|
||||
target.append(parameterValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The format of return value is '{group}/{interfaceName}:{version}'
|
||||
*
|
||||
|
|
@ -1397,10 +1376,6 @@ public /*final**/ class URL implements Serializable {
|
|||
return buildString(true, false, true, true);
|
||||
}
|
||||
|
||||
public String toServiceString(String... parameters) {
|
||||
return buildString(true, true, true, true, parameters);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public String getServiceName() {
|
||||
return getServiceInterface();
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
*/
|
||||
package org.apache.dubbo.common;
|
||||
|
||||
import org.apache.dubbo.common.constants.CommonConstants;
|
||||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
|
|
@ -61,7 +60,7 @@ public final class Version {
|
|||
public static final int LOWEST_VERSION_FOR_RESPONSE_ATTACHMENT = 2000200; // 2.0.2
|
||||
|
||||
public static final int HIGHEST_PROTOCOL_VERSION = 2009900; // 2.0.99
|
||||
private static final Map<String, Integer> VERSION2INT = new HashMap<>();
|
||||
private static final Map<String, Integer> VERSION2INT = new HashMap<String, Integer>();
|
||||
|
||||
static {
|
||||
// get dubbo version and last commit id
|
||||
|
|
@ -85,8 +84,7 @@ public final class Version {
|
|||
}
|
||||
|
||||
private static void tryLoadVersionFromResource() throws IOException {
|
||||
Enumeration<URL> configLoader =
|
||||
Version.class.getClassLoader().getResources(CommonConstants.DUBBO_VERSIONS_KEY + "/dubbo-common");
|
||||
Enumeration<URL> configLoader = Version.class.getClassLoader().getResources("META-INF/versions/dubbo-common");
|
||||
if (configLoader.hasMoreElements()) {
|
||||
URL url = configLoader.nextElement();
|
||||
try (BufferedReader reader =
|
||||
|
|
@ -314,7 +312,7 @@ public final class Version {
|
|||
|
||||
private static void checkArtifact(String artifactId) throws IOException {
|
||||
Enumeration<URL> artifactEnumeration =
|
||||
Version.class.getClassLoader().getResources(CommonConstants.DUBBO_VERSIONS_KEY + artifactId);
|
||||
Version.class.getClassLoader().getResources("META-INF/versions/" + artifactId);
|
||||
while (artifactEnumeration.hasMoreElements()) {
|
||||
URL url = artifactEnumeration.nextElement();
|
||||
try (BufferedReader reader =
|
||||
|
|
@ -350,7 +348,7 @@ public final class Version {
|
|||
|
||||
private static Set<String> loadArtifactIds() throws IOException {
|
||||
Enumeration<URL> artifactsEnumeration =
|
||||
Version.class.getClassLoader().getResources(CommonConstants.DUBBO_VERSIONS_KEY + "/.artifacts");
|
||||
Version.class.getClassLoader().getResources("META-INF/versions/.artifacts");
|
||||
Set<String> artifactIds = new HashSet<>();
|
||||
while (artifactsEnumeration.hasMoreElements()) {
|
||||
URL url = artifactsEnumeration.nextElement();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.common.aot;
|
||||
|
||||
import org.apache.dubbo.common.utils.SystemPropertyConfigUtils;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.ThirdPartyProperty.GRAALVM_NATIVEIMAGE_IMAGECODE;
|
||||
|
||||
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 =
|
||||
(SystemPropertyConfigUtils.getSystemProperty(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;
|
||||
}
|
||||
}
|
||||
|
|
@ -35,7 +35,7 @@ import java.util.Map;
|
|||
public final class JavaBeanSerializeUtil {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(JavaBeanSerializeUtil.class);
|
||||
private static final Map<String, Class<?>> TYPES = new HashMap<>();
|
||||
private static final Map<String, Class<?>> TYPES = new HashMap<String, Class<?>>();
|
||||
private static final String ARRAY_PREFIX = "[";
|
||||
private static final String REFERENCE_TYPE_PREFIX = "L";
|
||||
private static final String REFERENCE_TYPE_SUFFIX = ";";
|
||||
|
|
@ -72,7 +72,7 @@ public final class JavaBeanSerializeUtil {
|
|||
if (obj instanceof JavaBeanDescriptor) {
|
||||
return (JavaBeanDescriptor) obj;
|
||||
}
|
||||
IdentityHashMap<Object, JavaBeanDescriptor> cache = new IdentityHashMap<>();
|
||||
IdentityHashMap<Object, JavaBeanDescriptor> cache = new IdentityHashMap<Object, JavaBeanDescriptor>();
|
||||
return createDescriptorIfAbsent(obj, accessor, cache);
|
||||
}
|
||||
|
||||
|
|
@ -209,7 +209,7 @@ public final class JavaBeanSerializeUtil {
|
|||
if (beanDescriptor == null) {
|
||||
return null;
|
||||
}
|
||||
IdentityHashMap<JavaBeanDescriptor, Object> cache = new IdentityHashMap<>();
|
||||
IdentityHashMap<JavaBeanDescriptor, Object> cache = new IdentityHashMap<JavaBeanDescriptor, Object>();
|
||||
Object result = instantiateForDeserialize(beanDescriptor, loader, cache);
|
||||
deserializeInternal(result, beanDescriptor, loader, cache);
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ public abstract class Mixin {
|
|||
|
||||
Class<?> neighbor = null;
|
||||
// impl methods.
|
||||
Set<String> worked = new HashSet<>();
|
||||
Set<String> worked = new HashSet<String>();
|
||||
for (int i = 0; i < ics.length; i++) {
|
||||
if (!Modifier.isPublic(ics[i].getModifiers())) {
|
||||
String npkg = ics[i].getPackage().getName();
|
||||
|
|
|
|||
|
|
@ -42,8 +42,8 @@ import javassist.CtMethod;
|
|||
* Wrapper.
|
||||
*/
|
||||
public abstract class Wrapper {
|
||||
// class wrapper map
|
||||
private static final ConcurrentMap<Class<?>, Wrapper> WRAPPER_MAP = new ConcurrentHashMap<>();
|
||||
private static final ConcurrentMap<Class<?>, Wrapper> WRAPPER_MAP =
|
||||
new ConcurrentHashMap<Class<?>, Wrapper>(); // class wrapper map
|
||||
private static final String[] EMPTY_STRING_ARRAY = new String[0];
|
||||
private static final String[] OBJECT_METHODS = new String[] {"getClass", "hashCode", "toString", "equals"};
|
||||
private static final Wrapper OBJECT_WRAPPER = new Wrapper() {
|
||||
|
|
|
|||
|
|
@ -162,14 +162,6 @@ public class FileCacheStore {
|
|||
FileCacheStoreFactory.removeCache(cacheFilePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* for unit test only
|
||||
*/
|
||||
@Deprecated
|
||||
protected String getCacheFilePath() {
|
||||
return cacheFilePath;
|
||||
}
|
||||
|
||||
public static Builder newBuilder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package org.apache.dubbo.common.cache;
|
|||
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.utils.ConcurrentHashMapUtils;
|
||||
import org.apache.dubbo.common.utils.SystemPropertyConfigUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
|
@ -30,11 +31,11 @@ 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;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.SystemProperty.USER_HOME;
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_CACHE_PATH_INACCESSIBLE;
|
||||
|
||||
/**
|
||||
|
|
@ -82,7 +83,7 @@ public final class FileCacheStoreFactory {
|
|||
public static FileCacheStore getInstance(String basePath, String cacheName, boolean enableFileCache) {
|
||||
if (basePath == null) {
|
||||
// default case: ~/.dubbo
|
||||
basePath = System.getProperty("user.home") + File.separator + ".dubbo";
|
||||
basePath = SystemPropertyConfigUtils.getSystemProperty(USER_HOME) + File.separator + ".dubbo";
|
||||
}
|
||||
if (basePath.endsWith(File.separator)) {
|
||||
basePath = basePath.substring(0, basePath.length() - 1);
|
||||
|
|
@ -207,14 +208,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);
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package org.apache.dubbo.common.compact;
|
|||
|
||||
import org.apache.dubbo.common.constants.CommonConstants;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.common.utils.SystemPropertyConfigUtils;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
|
|
@ -38,17 +39,18 @@ public class Dubbo2CompactUtils {
|
|||
|
||||
private static void initEnabled() {
|
||||
try {
|
||||
String fromProp = System.getProperty(CommonConstants.DUBBO2_COMPACT_ENABLE);
|
||||
String fromProp =
|
||||
SystemPropertyConfigUtils.getSystemProperty(CommonConstants.DubboProperty.DUBBO2_COMPACT_ENABLE);
|
||||
if (StringUtils.isNotEmpty(fromProp)) {
|
||||
enabled = Boolean.parseBoolean(fromProp);
|
||||
return;
|
||||
}
|
||||
String fromEnv = System.getenv(CommonConstants.DUBBO2_COMPACT_ENABLE);
|
||||
String fromEnv = System.getenv(CommonConstants.DubboProperty.DUBBO2_COMPACT_ENABLE);
|
||||
if (StringUtils.isNotEmpty(fromEnv)) {
|
||||
enabled = Boolean.parseBoolean(fromEnv);
|
||||
return;
|
||||
}
|
||||
fromEnv = System.getenv(StringUtils.toOSStyleKey(CommonConstants.DUBBO2_COMPACT_ENABLE));
|
||||
fromEnv = System.getenv(StringUtils.toOSStyleKey(CommonConstants.DubboProperty.DUBBO2_COMPACT_ENABLE));
|
||||
enabled = !StringUtils.isNotEmpty(fromEnv) || Boolean.parseBoolean(fromEnv);
|
||||
} catch (Throwable t) {
|
||||
enabled = true;
|
||||
|
|
|
|||
|
|
@ -392,7 +392,7 @@ public class ClassUtils {
|
|||
}
|
||||
|
||||
public static <K, V> Map<K, V> toMap(Map.Entry<K, V>[] entries) {
|
||||
Map<K, V> map = new HashMap<>();
|
||||
Map<K, V> map = new HashMap<K, V>();
|
||||
if (entries != null && entries.length > 0) {
|
||||
for (Map.Entry<K, V> entry : entries) {
|
||||
map.put(entry.getKey(), entry.getValue());
|
||||
|
|
|
|||
|
|
@ -31,9 +31,10 @@ import java.io.StringReader;
|
|||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Properties;
|
||||
|
|
@ -42,7 +43,6 @@ import java.util.Set;
|
|||
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_SERVER_SHUTDOWN_TIMEOUT;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.SHUTDOWN_WAIT_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.SHUTDOWN_WAIT_SECONDS_KEY;
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_PROPERTY_TYPE_MISMATCH;
|
||||
|
||||
/**
|
||||
* Utilities for manipulating configurations from different sources
|
||||
|
|
@ -57,18 +57,18 @@ public final class ConfigurationUtils {
|
|||
}
|
||||
|
||||
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(ConfigurationUtils.class);
|
||||
private static final Set<String> securityKey;
|
||||
private static final List<String> securityKey;
|
||||
|
||||
private static volatile long expectedShutdownTime = Long.MAX_VALUE;
|
||||
|
||||
static {
|
||||
Set<String> keys = new HashSet<>();
|
||||
List<String> keys = new LinkedList<>();
|
||||
keys.add("accesslog");
|
||||
keys.add("router");
|
||||
keys.add("rule");
|
||||
keys.add("runtime");
|
||||
keys.add("type");
|
||||
securityKey = Collections.unmodifiableSet(keys);
|
||||
securityKey = Collections.unmodifiableList(keys);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -213,15 +213,11 @@ public final class ConfigurationUtils {
|
|||
properties.load(new StringReader(content));
|
||||
properties.stringPropertyNames().forEach(k -> {
|
||||
boolean deny = false;
|
||||
// check whether property name is safe or not based on the last fragment kebab-case comparison.
|
||||
String[] fragments = k.split("\\.");
|
||||
if (securityKey.contains(StringUtils.convertToSplitName(fragments[fragments.length - 1], "-"))) {
|
||||
deny = true;
|
||||
logger.warn(
|
||||
COMMON_PROPERTY_TYPE_MISMATCH,
|
||||
"security properties are not allowed to be set",
|
||||
"",
|
||||
String.format("'%s' is not allowed to be set as it is on the security key list.", k));
|
||||
for (String key : securityKey) {
|
||||
if (k.contains(key)) {
|
||||
deny = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!deny) {
|
||||
map.put(k, properties.getProperty(k));
|
||||
|
|
@ -286,7 +282,8 @@ 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)) {
|
||||
|
||||
|
|
@ -326,7 +323,8 @@ 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;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
|
|||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
import org.apache.dubbo.common.utils.ConfigUtils;
|
||||
import org.apache.dubbo.common.utils.StringUtils;
|
||||
import org.apache.dubbo.common.utils.SystemPropertyConfigUtils;
|
||||
import org.apache.dubbo.config.AbstractConfig;
|
||||
import org.apache.dubbo.config.context.ConfigConfigurationAdapter;
|
||||
import org.apache.dubbo.rpc.model.ScopeModel;
|
||||
|
|
@ -96,10 +97,12 @@ public class Environment extends LifecycleAdapter implements ApplicationExt {
|
|||
*/
|
||||
@Deprecated
|
||||
private void loadMigrationRule() {
|
||||
if (Boolean.parseBoolean(System.getProperty(CommonConstants.DUBBO_MIGRATION_FILE_ENABLE, "false"))) {
|
||||
String path = System.getProperty(CommonConstants.DUBBO_MIGRATION_KEY);
|
||||
if (Boolean.parseBoolean(SystemPropertyConfigUtils.getSystemProperty(
|
||||
CommonConstants.DubboProperty.DUBBO_MIGRATION_FILE_ENABLE, "false"))) {
|
||||
String path =
|
||||
SystemPropertyConfigUtils.getSystemProperty(CommonConstants.DubboProperty.DUBBO_MIGRATION_KEY);
|
||||
if (StringUtils.isEmpty(path)) {
|
||||
path = System.getenv(CommonConstants.DUBBO_MIGRATION_KEY);
|
||||
path = System.getenv(CommonConstants.DubboProperty.DUBBO_MIGRATION_KEY);
|
||||
if (StringUtils.isEmpty(path)) {
|
||||
path = CommonConstants.DEFAULT_DUBBO_MIGRATION_FILE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
* </ul>
|
||||
*
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ import java.util.concurrent.ExecutorService;
|
|||
import java.util.regex.Pattern;
|
||||
|
||||
public interface CommonConstants {
|
||||
|
||||
String DUBBO = "dubbo";
|
||||
|
||||
String TRIPLE = "tri";
|
||||
|
|
@ -61,14 +60,8 @@ public interface CommonConstants {
|
|||
|
||||
String DISABLED_KEY = "disabled";
|
||||
|
||||
String DUBBO_PROPERTIES_KEY = "dubbo.properties.file";
|
||||
|
||||
String DEFAULT_DUBBO_PROPERTIES = "dubbo.properties";
|
||||
|
||||
String DUBBO_MIGRATION_KEY = "dubbo.migration.file";
|
||||
|
||||
String DUBBO_MIGRATION_FILE_ENABLE = "dubbo.migration-file.enable";
|
||||
|
||||
String DEFAULT_DUBBO_MIGRATION_FILE = "dubbo-migration.yaml";
|
||||
|
||||
String ANY_VALUE = "*";
|
||||
|
|
@ -128,6 +121,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";
|
||||
|
|
@ -268,14 +263,12 @@ public interface CommonConstants {
|
|||
String $INVOKE = "$invoke";
|
||||
|
||||
String $INVOKE_ASYNC = "$invokeAsync";
|
||||
|
||||
String GENERIC_PARAMETER_DESC = "Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/Object;";
|
||||
|
||||
/**
|
||||
* echo call
|
||||
*/
|
||||
String $ECHO = "$echo";
|
||||
|
||||
/**
|
||||
* package version in the manifest
|
||||
*/
|
||||
|
|
@ -286,19 +279,13 @@ public interface CommonConstants {
|
|||
int MAX_PROXY_COUNT = 65535;
|
||||
|
||||
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";
|
||||
|
||||
String PORT_KEY = "port";
|
||||
|
||||
String DUBBO_IP_TO_BIND = "DUBBO_IP_TO_BIND";
|
||||
|
||||
/**
|
||||
|
|
@ -306,41 +293,25 @@ public interface CommonConstants {
|
|||
*/
|
||||
String BROADCAST_CLUSTER = "broadcast";
|
||||
|
||||
/**
|
||||
* The property name for {@link NetworkInterface#getDisplayName() the name of network interface} that
|
||||
* the Dubbo application prefers
|
||||
*
|
||||
* @since 2.7.6
|
||||
*/
|
||||
String DUBBO_PREFERRED_NETWORK_INTERFACE = "dubbo.network.interface.preferred";
|
||||
|
||||
@Deprecated
|
||||
String SHUTDOWN_WAIT_SECONDS_KEY = "dubbo.service.shutdown.wait.seconds";
|
||||
|
||||
String SHUTDOWN_WAIT_KEY = "dubbo.service.shutdown.wait";
|
||||
|
||||
String DUBBO_PROTOCOL = "dubbo";
|
||||
|
||||
String DUBBO_LABELS = "dubbo.labels";
|
||||
|
||||
String DUBBO_ENV_KEYS = "dubbo.env.keys";
|
||||
|
||||
String CONFIG_CONFIGFILE_KEY = "config-file";
|
||||
|
||||
String CONFIG_ENABLE_KEY = "highest-priority";
|
||||
|
||||
String CONFIG_NAMESPACE_KEY = "namespace";
|
||||
|
||||
String CHECK_KEY = "check";
|
||||
|
||||
String BACKLOG_KEY = "backlog";
|
||||
|
||||
String HEARTBEAT_EVENT = null;
|
||||
|
||||
String MOCK_HEARTBEAT_EVENT = "H";
|
||||
|
||||
String READONLY_EVENT = "R";
|
||||
|
||||
String WRITEABLE_EVENT = "W";
|
||||
|
||||
String REFERENCE_FILTER_KEY = "reference.filter";
|
||||
|
|
@ -454,12 +425,6 @@ public interface CommonConstants {
|
|||
*/
|
||||
String DEFAULT_SERVICE_NAME_MAPPING_PROPERTIES_PATH = "META-INF/dubbo/service-name-mapping.properties";
|
||||
|
||||
String CLASS_DESERIALIZE_BLOCK_ALL = "dubbo.security.serialize.blockAllClassExceptAllow";
|
||||
|
||||
String CLASS_DESERIALIZE_ALLOWED_LIST = "dubbo.security.serialize.allowedClassList";
|
||||
|
||||
String CLASS_DESERIALIZE_BLOCKED_LIST = "dubbo.security.serialize.blockedClassList";
|
||||
|
||||
String ENABLE_NATIVE_JAVA_GENERIC_SERIALIZE = "dubbo.security.serialize.generic.native-java-enable";
|
||||
|
||||
String SERIALIZE_BLOCKED_LIST_FILE_PATH = "security/serialize.blockedlist";
|
||||
|
|
@ -477,7 +442,6 @@ public interface CommonConstants {
|
|||
String REGISTRY_DELAY_NOTIFICATION_KEY = "delay-notification";
|
||||
|
||||
String CACHE_CLEAR_TASK_INTERVAL = "dubbo.application.url.cache.task.interval";
|
||||
|
||||
String CACHE_CLEAR_WAITING_THRESHOLD = "dubbo.application.url.cache.clear.waiting";
|
||||
|
||||
String CLUSTER_INTERCEPTOR_COMPATIBLE_KEY = "dubbo.application.cluster.interceptor.compatible";
|
||||
|
|
@ -491,8 +455,6 @@ public interface CommonConstants {
|
|||
|
||||
String DEFAULT_VERSION = "0.0.0";
|
||||
|
||||
String CLASS_DESERIALIZE_OPEN_CHECK = "dubbo.security.serialize.openCheckClass";
|
||||
|
||||
String ROUTER_KEY = "router";
|
||||
|
||||
String EXPORT_ASYNC_KEY = "export-async";
|
||||
|
|
@ -520,11 +482,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";
|
||||
|
|
@ -533,16 +490,6 @@ public interface CommonConstants {
|
|||
|
||||
String SERVICE_MODEL = "serviceModel";
|
||||
|
||||
/**
|
||||
* The property name for {@link NetworkInterface#getDisplayName() the name of network interface} that
|
||||
* the Dubbo application will be ignored
|
||||
*
|
||||
* @since 2.7.6
|
||||
*/
|
||||
String DUBBO_NETWORK_IGNORED_INTERFACE = "dubbo.network.interface.ignored";
|
||||
|
||||
String OS_NAME_KEY = "os.name";
|
||||
|
||||
String OS_LINUX_PREFIX = "linux";
|
||||
|
||||
String OS_WIN_PREFIX = "win";
|
||||
|
|
@ -587,10 +534,6 @@ public interface CommonConstants {
|
|||
|
||||
String INJVM_IGNORE_SAME_MODULE_KEY = "injvm.ignore.same-module";
|
||||
|
||||
String SET_FUTURE_IN_SYNC_MODE = "future.sync.set";
|
||||
|
||||
String CLEAR_FUTURE_AFTER_GET = "future.clear.once";
|
||||
|
||||
String NATIVE_STUB = "nativestub";
|
||||
|
||||
String METADATA = "metadata";
|
||||
|
|
@ -599,8 +542,6 @@ public interface CommonConstants {
|
|||
|
||||
String OPTIMIZER_KEY = "optimizer";
|
||||
|
||||
String PREFER_JSON_FRAMEWORK_NAME = "dubbo.json-framework.prefer";
|
||||
|
||||
/**
|
||||
* @since 3.1.0
|
||||
*/
|
||||
|
|
@ -634,25 +575,12 @@ public interface CommonConstants {
|
|||
String SERVICE_EXECUTOR = "service-executor";
|
||||
|
||||
String EXECUTOR_MANAGEMENT_MODE = "executor-management-mode";
|
||||
|
||||
String EXECUTOR_MANAGEMENT_MODE_DEFAULT = "default";
|
||||
|
||||
String EXECUTOR_MANAGEMENT_MODE_ISOLATION = "isolation";
|
||||
|
||||
/**
|
||||
* used in JVMUtil.java ,Control stack print lines, default is 32 lines
|
||||
*/
|
||||
String DUBBO_JSTACK_MAXLINE = "dubbo.jstack-dump.max-line";
|
||||
|
||||
String ENCODE_IN_IO_THREAD_KEY = "encode.in.io";
|
||||
|
||||
boolean DEFAULT_ENCODE_IN_IO_THREAD = false;
|
||||
|
||||
/**
|
||||
* @since 3.2.0
|
||||
*/
|
||||
String BYTE_ACCESSOR_KEY = "byte.accessor";
|
||||
|
||||
String PAYLOAD = "payload";
|
||||
|
||||
String DUBBO_METRICS_CONFIGCENTER_ENABLE = "dubbo.metrics.configcenter.enable";
|
||||
|
|
@ -663,11 +591,161 @@ public interface CommonConstants {
|
|||
|
||||
String DUBBO_PACKABLE_METHOD_FACTORY = "dubbo.application.parameters." + PACKABLE_METHOD_FACTORY_KEY;
|
||||
|
||||
String DUBBO_MANUAL_REGISTER_KEY = "dubbo.application.manual-register";
|
||||
String DUBBO_TAG_HEADER = "dubbo-tag";
|
||||
|
||||
String DUBBO2_COMPACT_ENABLE = "dubbo.compact.enable";
|
||||
String REST_SERVICE_DEPLOYER_URL_ATTRIBUTE_KEY = "restServiceDeployerAttributeKey";
|
||||
|
||||
String ZOOKEEPER_ENSEMBLE_TRACKER_KEY = "zookeeper.ensemble.tracker";
|
||||
String POD_NAMESPACE = "POD_NAMESPACE";
|
||||
|
||||
String DUBBO_VERSIONS_KEY = "META-INF/dubbo-versions";
|
||||
String CLUSTER_DOMAIN = "CLUSTER_DOMAIN";
|
||||
|
||||
String EXT_PROTOCOL = "ext.protocol";
|
||||
|
||||
String IS_EXTRA = "isExtra";
|
||||
|
||||
/**
|
||||
* System-related VM properties
|
||||
*/
|
||||
interface SystemProperty {
|
||||
|
||||
String USER_HOME = "user.home";
|
||||
|
||||
String SYSTEM_JAVA_VERSION = "java.version";
|
||||
|
||||
String SYSTEM_JAVA_IO_TMPDIR = "java.io.tmpdir";
|
||||
|
||||
String SYSTEM_LINE_SEPARATOR = "line.separator";
|
||||
|
||||
String SERIALIZATION_SECURITY_CHECK_KEY = "serialization.security.check";
|
||||
|
||||
String SYSTEM_BYTE_ACCESSOR_KEY = "byte.accessor";
|
||||
|
||||
String SYSTEM_OS_NAME = "os.name";
|
||||
|
||||
String SYSTEM_OS_VERSION = "os.version";
|
||||
|
||||
String JAVA_RUNTIME_NAME = "java.runtime.name";
|
||||
|
||||
String JAVA_RUNTIME_VERSION = "java.runtime.version";
|
||||
|
||||
String JAVA_VM_NAME = "java.vm.name";
|
||||
|
||||
String JAVA_VM_VERSION = "java.vm.version";
|
||||
|
||||
String JAVA_VM_INFO = "java.vm.info";
|
||||
|
||||
String JAVA_HOME = "java.home";
|
||||
|
||||
String OS_ARCH = "os.arch";
|
||||
|
||||
String SYSTEM_FILE_ENCODING = "file.encoding";
|
||||
|
||||
String SYSTEM_TCP_RESPONSE_TIMEOUT = "sun.rmi.transport.tcp.responseTimeout";
|
||||
}
|
||||
|
||||
/**
|
||||
* Third-party-related VM properties
|
||||
*/
|
||||
interface ThirdPartyProperty {
|
||||
String NETTY_EPOLL_ENABLE_KEY = "netty.epoll.enable";
|
||||
|
||||
String SET_FUTURE_IN_SYNC_MODE = "future.sync.set";
|
||||
|
||||
String CLEAR_FUTURE_AFTER_GET = "future.clear.once";
|
||||
|
||||
String APOLLO_ADDR_KEY = "apollo.meta";
|
||||
|
||||
String APOLLO_CLUSTER_KEY = "apollo.cluster";
|
||||
|
||||
String APOLLO_ENV_KEY = "env";
|
||||
|
||||
String APOLLO_APPID_KEY = "app.id";
|
||||
|
||||
String NACOS_SERVICE_NAME_SEPARATOR = "nacos.service.name.separator";
|
||||
|
||||
String GRAALVM_NATIVEIMAGE_IMAGECODE = "org.graalvm.nativeimage.imagecode";
|
||||
|
||||
/**
|
||||
* The JVM arguments to set if it can use embedded zookeeper, the default value is {@code true}.
|
||||
*/
|
||||
String ZOOKEEPER_CONFIG_ENABLE_EMBEDDED = "enableEmbeddedZookeeper";
|
||||
}
|
||||
|
||||
/**
|
||||
* Dubbo custom VM properties
|
||||
*/
|
||||
interface DubboProperty {
|
||||
String DUBBO_MIGRATION_FILE_ENABLE = "dubbo.migration-file.enable";
|
||||
String DUBBO_MIGRATION_KEY = "dubbo.migration.file";
|
||||
String DUBBO_APPLICATION_LOGGER = "dubbo.application.logger";
|
||||
String DUBBO_PROPERTIES_KEY = "dubbo.properties.file";
|
||||
String DUBBO_PREFER_JSON_FRAMEWORK_NAME = "dubbo.json-framework.prefer";
|
||||
|
||||
/**
|
||||
* used in JVMUtil.java ,Control stack print lines, default is 32 lines
|
||||
*/
|
||||
String DUBBO_JSTACK_MAXLINE = "dubbo.jstack-dump.max-line";
|
||||
|
||||
/**
|
||||
* The property name for {@link NetworkInterface#getDisplayName() the name of network interface} that
|
||||
* the Dubbo application will be ignored
|
||||
*
|
||||
* @since 2.7.6
|
||||
*/
|
||||
String DUBBO_NETWORK_IGNORED_INTERFACE = "dubbo.network.interface.ignored";
|
||||
|
||||
/**
|
||||
* The property name for {@link NetworkInterface#getDisplayName() the name of network interface} that
|
||||
* the Dubbo application prefers
|
||||
*
|
||||
* @since 2.7.6
|
||||
*/
|
||||
String DUBBO_PREFERRED_NETWORK_INTERFACE = "dubbo.network.interface.preferred";
|
||||
|
||||
String DUBBO_CLASS_DESERIALIZE_ALLOWED_LIST = "dubbo.security.serialize.allowedClassList";
|
||||
String DUBBO_CLASS_DESERIALIZE_BLOCKED_LIST = "dubbo.security.serialize.blockedClassList";
|
||||
String DUBBO_CLASS_DESERIALIZE_OPEN_CHECK = "dubbo.security.serialize.openCheckClass";
|
||||
String DUBBO_CLASS_DESERIALIZE_BLOCK_ALL = "dubbo.security.serialize.blockAllClassExceptAllow";
|
||||
String DUBBO_RESOLVE_FILE = "dubbo.resolve.file";
|
||||
String DUBBO_IP_TO_REGISTRY = "DUBBO_IP_TO_REGISTRY";
|
||||
String DUBBO_MONITOR_ADDRESS = "dubbo.monitor.address";
|
||||
String DUBBO_CONTAINER_KEY = "dubbo.container";
|
||||
String DUBBO_SHUTDOWN_HOOK_KEY = "dubbo.shutdown.hook";
|
||||
String DUBBO_SPRING_CONFIG = "dubbo.spring.config";
|
||||
String DUBBO_MAPPING_CACHE_FILEPATH = "dubbo.mapping.cache.filePath";
|
||||
|
||||
String DUBBO_MAPPING_CACHE_FILENAME = "dubbo.mapping.cache.fileName";
|
||||
|
||||
String DUBBO_MAPPING_CACHE_ENTRYSIZE = "dubbo.mapping.cache.entrySize";
|
||||
|
||||
String DUBBO_MAPPING_CACHE_MAXFILESIZE = "dubbo.mapping.cache.maxFileSize";
|
||||
|
||||
String DUBBO_META_CACHE_FILEPATH = "dubbo.meta.cache.filePath";
|
||||
|
||||
String DUBBO_META_CACHE_FILENAME = "dubbo.meta.cache.fileName";
|
||||
|
||||
String DUBBO_META_CACHE_ENTRYSIZE = "dubbo.meta.cache.entrySize";
|
||||
|
||||
String DUBBO_META_CACHE_MAXFILESIZE = "dubbo.meta.cache.maxFileSize";
|
||||
|
||||
String DUBBO_USE_SECURE_RANDOM_ID = "dubbo.application.use-secure-random-request-id";
|
||||
|
||||
String DUBBO_CLOSE_TIMEOUT_CONFIG_KEY = "dubbo.protocol.default-close-timeout";
|
||||
|
||||
String DUBBO_HEARTBEAT_CONFIG_KEY = "dubbo.protocol.default-heartbeat";
|
||||
|
||||
String DUBBO_DEFAULT_REMOTING_SERIALIZATION_PROPERTY = "DUBBO_DEFAULT_SERIALIZATION";
|
||||
|
||||
String DUBBO_HESSIAN_ALLOW_NON_SERIALIZABLE = "dubbo.hessian.allowNonSerializable";
|
||||
|
||||
String DUBBO_HESSIAN_WHITELIST = "dubbo.application.hessian2.whitelist";
|
||||
|
||||
String DUBBO_HESSIAN_ALLOW = "dubbo.application.hessian2.allow";
|
||||
|
||||
String DUBBO_HESSIAN_DENY = "dubbo.application.hessian2.deny";
|
||||
|
||||
String DUBBO_MANUAL_REGISTER_KEY = "dubbo.application.manual-register";
|
||||
|
||||
String DUBBO2_COMPACT_ENABLE = "dubbo.compact.enable";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,6 +91,8 @@ public interface LoggerCodeConstants {
|
|||
|
||||
String VULNERABILITY_WARNING = "0-28";
|
||||
|
||||
String COMMON_NOT_FOUND_TRACER_DEPENDENCY = "0-29";
|
||||
|
||||
// Registry module
|
||||
|
||||
String REGISTRY_ADDRESS_INVALID = "1-1";
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -141,11 +141,5 @@ public interface RegistryConstants {
|
|||
String ENABLE_EMPTY_PROTECTION_KEY = "enable-empty-protection";
|
||||
boolean DEFAULT_ENABLE_EMPTY_PROTECTION = false;
|
||||
String REGISTER_CONSUMER_URL_KEY = "register-consumer-url";
|
||||
|
||||
/**
|
||||
* export noting suffix servicename
|
||||
* by default, dubbo export servicename is "${interface}:${version}:", this servicename with ':' suffix
|
||||
* for compatible, we should export noting suffix servicename, eg: ${interface}:${version}
|
||||
*/
|
||||
String NACOE_REGISTER_COMPATIBLE = "nacos.register-compatible";
|
||||
String REGISTRY_PROTOCOL_TYPE = "registry-protocol-type";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import java.util.List;
|
|||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_MONITOR_EXCEPTION;
|
||||
import static org.apache.dubbo.common.deploy.DeployState.COMPLETION;
|
||||
import static org.apache.dubbo.common.deploy.DeployState.FAILED;
|
||||
import static org.apache.dubbo.common.deploy.DeployState.PENDING;
|
||||
import static org.apache.dubbo.common.deploy.DeployState.STARTED;
|
||||
|
|
@ -56,12 +57,17 @@ public abstract class AbstractDeployer<E extends ScopeModel> implements Deployer
|
|||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return state == STARTING || state == STARTED;
|
||||
return state == STARTING || state == STARTED || state == COMPLETION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStarted() {
|
||||
return state == STARTED;
|
||||
return state == STARTED || state == COMPLETION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompletion() {
|
||||
return state == COMPLETION;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -135,6 +141,22 @@ public abstract class AbstractDeployer<E extends ScopeModel> implements Deployer
|
|||
}
|
||||
}
|
||||
|
||||
protected void setCompletion() {
|
||||
this.state = COMPLETION;
|
||||
for (DeployListener<E> listener : listeners) {
|
||||
try {
|
||||
listener.onCompletion(scopeModel);
|
||||
} catch (Throwable e) {
|
||||
logger.error(
|
||||
COMMON_MONITOR_EXCEPTION,
|
||||
"",
|
||||
"",
|
||||
getIdentifier() + " an exception occurred when handle completion event",
|
||||
e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void setStopping() {
|
||||
this.state = STOPPING;
|
||||
for (DeployListener<E> listener : listeners) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -24,13 +24,35 @@ public interface DeployListener<E extends ScopeModel> {
|
|||
*/
|
||||
void onInitialize(E scopeModel);
|
||||
|
||||
/**
|
||||
* Triggered before starting module.
|
||||
*/
|
||||
void onStarting(E scopeModel);
|
||||
|
||||
/**
|
||||
* Triggered before registering and exposing the service.
|
||||
*/
|
||||
void onStarted(E scopeModel);
|
||||
|
||||
/**
|
||||
* Triggered after deployer startup is complete.
|
||||
*/
|
||||
default void onCompletion(E scopeModel) {}
|
||||
|
||||
/**
|
||||
* Triggered before the app is destroyed,
|
||||
* can do some customized things before offline the service and destroy reference.
|
||||
*/
|
||||
void onStopping(E scopeModel);
|
||||
|
||||
/**
|
||||
* Triggered after the application is destroyed,
|
||||
* can do some customized things after the service is offline and the reference is destroyed.
|
||||
*/
|
||||
void onStopped(E scopeModel);
|
||||
|
||||
/**
|
||||
* Useful to do something when deployer was failed.
|
||||
*/
|
||||
void onFailure(E scopeModel, Throwable cause);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@ public class DeployListenerAdapter<E extends ScopeModel> implements DeployListen
|
|||
@Override
|
||||
public void onStarted(E scopeModel) {}
|
||||
|
||||
@Override
|
||||
public void onCompletion(E scopeModel) {}
|
||||
|
||||
@Override
|
||||
public void onStopping(E scopeModel) {}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,11 @@ public enum DeployState {
|
|||
*/
|
||||
STARTED,
|
||||
|
||||
/**
|
||||
* Completion
|
||||
*/
|
||||
COMPLETION,
|
||||
|
||||
/**
|
||||
* Stopping
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -55,6 +55,8 @@ public interface Deployer<E extends ScopeModel> {
|
|||
*/
|
||||
boolean isStarted();
|
||||
|
||||
boolean isCompletion();
|
||||
|
||||
/**
|
||||
* @return true if the component is starting.
|
||||
* @see #isStarted()
|
||||
|
|
|
|||
|
|
@ -50,4 +50,8 @@ public interface ModuleDeployer extends Deployer<ModuleModel> {
|
|||
* Whether start in background, do not await finish
|
||||
*/
|
||||
boolean isBackground();
|
||||
|
||||
boolean hasRegistryInteraction();
|
||||
|
||||
ApplicationDeployer getApplicationDeployer();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@
|
|||
*/
|
||||
package org.apache.dubbo.common.extension;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Uniform accessor for extension
|
||||
*/
|
||||
|
|
@ -24,7 +27,7 @@ public interface ExtensionAccessor {
|
|||
ExtensionDirector getExtensionDirector();
|
||||
|
||||
default <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) {
|
||||
return this.getExtensionDirector().getExtensionLoader(type);
|
||||
return getExtensionDirector().getExtensionLoader(type);
|
||||
}
|
||||
|
||||
default <T> T getExtension(Class<T> type, String name) {
|
||||
|
|
@ -41,4 +44,21 @@ public interface ExtensionAccessor {
|
|||
ExtensionLoader<T> extensionLoader = getExtensionLoader(type);
|
||||
return extensionLoader != null ? extensionLoader.getDefaultExtension() : null;
|
||||
}
|
||||
|
||||
default <T> List<T> getActivateExtensions(Class<T> type) {
|
||||
ExtensionLoader<T> extensionLoader = getExtensionLoader(type);
|
||||
return extensionLoader != null ? extensionLoader.getActivateExtensions() : Collections.emptyList();
|
||||
}
|
||||
|
||||
default <T> T getFirstActivateExtension(Class<T> type) {
|
||||
ExtensionLoader<T> extensionLoader = getExtensionLoader(type);
|
||||
if (extensionLoader == null) {
|
||||
throw new IllegalArgumentException("ExtensionLoader for [" + type + "] is not found");
|
||||
}
|
||||
List<T> extensions = extensionLoader.getActivateExtensions();
|
||||
if (extensions.isEmpty()) {
|
||||
throw new IllegalArgumentException("No activate extensions for [" + type + "] found");
|
||||
}
|
||||
return extensions.get(0);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.compact.Dubbo2ActivateUtils;
|
||||
import org.apache.dubbo.common.compact.Dubbo2CompactUtils;
|
||||
|
|
@ -35,7 +36,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;
|
||||
|
|
@ -1451,7 +1451,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) {
|
||||
|
|
|
|||
|
|
@ -16,8 +16,13 @@
|
|||
*/
|
||||
package org.apache.dubbo.common.io;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* Stream utils.
|
||||
|
|
@ -229,4 +234,51 @@ public class StreamUtils {
|
|||
is.skip(is.available());
|
||||
}
|
||||
}
|
||||
|
||||
public static void copy(InputStream in, OutputStream out) throws IOException {
|
||||
if (in.getClass() == ByteArrayInputStream.class) {
|
||||
copy((ByteArrayInputStream) in, out);
|
||||
return;
|
||||
}
|
||||
byte[] buffer = new byte[4096];
|
||||
int bytesRead;
|
||||
while ((bytesRead = in.read(buffer)) != -1) {
|
||||
out.write(buffer, 0, bytesRead);
|
||||
}
|
||||
}
|
||||
|
||||
public static void copy(ByteArrayInputStream in, OutputStream out) throws IOException {
|
||||
int len = in.available();
|
||||
byte[] buffer = new byte[len];
|
||||
in.read(buffer, 0, len);
|
||||
out.write(buffer, 0, len);
|
||||
}
|
||||
|
||||
public static byte[] readBytes(InputStream in) throws IOException {
|
||||
if (in.getClass() == ByteArrayInputStream.class) {
|
||||
return readBytes((ByteArrayInputStream) in);
|
||||
}
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[4096];
|
||||
int bytesRead;
|
||||
while ((bytesRead = in.read(buffer)) != -1) {
|
||||
out.write(buffer, 0, bytesRead);
|
||||
}
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
public static byte[] readBytes(ByteArrayInputStream in) throws IOException {
|
||||
int len = in.available();
|
||||
byte[] bytes = new byte[len];
|
||||
in.read(bytes, 0, len);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static String toString(InputStream in) throws IOException {
|
||||
return new String(readBytes(in), StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
public static String toString(InputStream in, Charset charset) throws IOException {
|
||||
return new String(readBytes(in), charset);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,6 +62,19 @@ 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,15 +16,16 @@
|
|||
*/
|
||||
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();
|
||||
|
||||
boolean isJson(String json);
|
||||
|
||||
<T> T toJavaObject(String json, Type type);
|
||||
|
||||
<T> List<T> toJavaList(String json, Class<T> clazz);
|
||||
|
|
@ -39,6 +40,10 @@ public interface JSON {
|
|||
|
||||
Map<String, ?> getObject(Map<String, ?> obj, String key);
|
||||
|
||||
Object convertObject(Object obj, Type type);
|
||||
|
||||
Object convertObject(Object obj, Class<?> clazz);
|
||||
|
||||
Double getNumberAsDouble(Map<String, ?> obj, String key);
|
||||
|
||||
Integer getNumberAsInteger(Map<String, ?> obj, String key);
|
||||
|
|
@ -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 {
|
||||
|
|
@ -19,17 +19,9 @@ package org.apache.dubbo.common.json.impl;
|
|||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.fastjson2.JSONValidator;
|
||||
import com.alibaba.fastjson2.JSONWriter;
|
||||
|
||||
public class FastJson2Impl extends AbstractJSONImpl {
|
||||
|
||||
@Override
|
||||
public boolean isJson(String json) {
|
||||
JSONValidator validator = JSONValidator.from(json);
|
||||
return validator.validate();
|
||||
}
|
||||
|
||||
public class FastJson2Impl extends AbstractJsonUtilImpl {
|
||||
@Override
|
||||
public <T> T toJavaObject(String json, Type type) {
|
||||
return com.alibaba.fastjson2.JSON.parseObject(json, type);
|
||||
|
|
@ -44,4 +36,14 @@ public class FastJson2Impl extends AbstractJSONImpl {
|
|||
public String toJson(Object obj) {
|
||||
return com.alibaba.fastjson2.JSON.toJSONString(obj, JSONWriter.Feature.WriteEnumsUsingName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convertObject(Object obj, Type type) {
|
||||
return com.alibaba.fastjson2.util.TypeUtils.cast(obj, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convertObject(Object obj, Class<?> clazz) {
|
||||
return com.alibaba.fastjson2.util.TypeUtils.cast(obj, clazz);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,19 +19,10 @@ package org.apache.dubbo.common.json.impl;
|
|||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.fastjson.parser.ParserConfig;
|
||||
import com.alibaba.fastjson.serializer.SerializerFeature;
|
||||
|
||||
public class FastJsonImpl extends AbstractJSONImpl {
|
||||
|
||||
@Override
|
||||
public boolean isJson(String json) {
|
||||
try {
|
||||
Object obj = com.alibaba.fastjson.JSON.parse(json);
|
||||
return obj instanceof com.alibaba.fastjson.JSONObject || obj instanceof com.alibaba.fastjson.JSONArray;
|
||||
} catch (com.alibaba.fastjson.JSONException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public class FastJsonImpl extends AbstractJsonUtilImpl {
|
||||
|
||||
@Override
|
||||
public <T> T toJavaObject(String json, Type type) {
|
||||
|
|
@ -47,4 +38,14 @@ public class FastJsonImpl extends AbstractJSONImpl {
|
|||
public String toJson(Object obj) {
|
||||
return com.alibaba.fastjson.JSON.toJSONString(obj, SerializerFeature.DisableCircularReferenceDetect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convertObject(Object obj, Type type) {
|
||||
return com.alibaba.fastjson.util.TypeUtils.cast(obj, type, ParserConfig.getGlobalInstance());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convertObject(Object obj, Class<?> clazz) {
|
||||
return com.alibaba.fastjson.util.TypeUtils.cast(obj, clazz, ParserConfig.getGlobalInstance());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,25 +20,12 @@ import java.lang.reflect.Type;
|
|||
import java.util.List;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
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;
|
||||
|
||||
@Override
|
||||
public boolean isJson(String json) {
|
||||
try {
|
||||
JsonElement jsonElement = JsonParser.parseString(json);
|
||||
return jsonElement.isJsonObject() || jsonElement.isJsonArray();
|
||||
} catch (JsonSyntaxException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T toJavaObject(String json, Type type) {
|
||||
return getGson().fromJson(json, type);
|
||||
|
|
@ -55,6 +42,18 @@ public class GsonImpl extends AbstractJSONImpl {
|
|||
return getGson().toJson(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convertObject(Object obj, Type type) {
|
||||
Gson gson = getGson();
|
||||
return gson.fromJson(gson.toJsonTree(obj), type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convertObject(Object obj, Class<?> clazz) {
|
||||
Gson gson = getGson();
|
||||
return gson.fromJson(gson.toJsonTree(obj), clazz);
|
||||
}
|
||||
|
||||
private Gson getGson() {
|
||||
if (gsonCache == null || !(gsonCache instanceof Gson)) {
|
||||
synchronized (this) {
|
||||
|
|
|
|||
|
|
@ -20,29 +20,17 @@ import java.lang.reflect.Type;
|
|||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.MapperFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.json.JsonMapper;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
|
||||
public class JacksonImpl extends AbstractJSONImpl {
|
||||
public class JacksonImpl extends AbstractJsonUtilImpl {
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
private volatile Object jacksonCache = null;
|
||||
|
||||
@Override
|
||||
public boolean isJson(String json) {
|
||||
try {
|
||||
JsonNode node = objectMapper.readTree(json);
|
||||
return node.isObject() || node.isArray();
|
||||
} catch (JsonProcessingException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T toJavaObject(String json, Type type) {
|
||||
try {
|
||||
|
|
@ -71,6 +59,17 @@ public class JacksonImpl extends AbstractJSONImpl {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convertObject(Object obj, Type type) {
|
||||
JsonMapper mapper = getJackson();
|
||||
return mapper.convertValue(obj, mapper.constructType(type));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convertObject(Object obj, Class<?> clazz) {
|
||||
return getJackson().convertValue(obj, clazz);
|
||||
}
|
||||
|
||||
private JsonMapper getJackson() {
|
||||
if (jacksonCache == null || !(jacksonCache instanceof JsonMapper)) {
|
||||
synchronized (this) {
|
||||
|
|
|
|||
|
|
@ -14,15 +14,17 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.rpc.protocol.rest;
|
||||
package org.apache.dubbo.common.logger;
|
||||
|
||||
/**
|
||||
* Only the server that implements servlet container
|
||||
* could support something like @Context injection of servlet objects.
|
||||
* Loggers that can register to listen to log messages.
|
||||
*/
|
||||
public class RestServerFactory {
|
||||
public interface ListenableLogger extends ErrorTypeAwareLogger {
|
||||
|
||||
public RestProtocolServer createServer(String name) {
|
||||
return new NettyHttpRestServer();
|
||||
}
|
||||
/**
|
||||
* Register a listener to this logger,and get notified when a log happens.
|
||||
*
|
||||
* @param listener log listener
|
||||
*/
|
||||
void registerListen(LogListener listener);
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
package org.apache.dubbo.common.logger;
|
||||
|
||||
import org.apache.dubbo.common.constants.CommonConstants;
|
||||
import org.apache.dubbo.common.logger.jcl.JclLoggerAdapter;
|
||||
import org.apache.dubbo.common.logger.jdk.JdkLoggerAdapter;
|
||||
import org.apache.dubbo.common.logger.log4j.Log4jLoggerAdapter;
|
||||
|
|
@ -24,6 +25,7 @@ import org.apache.dubbo.common.logger.slf4j.Slf4jLoggerAdapter;
|
|||
import org.apache.dubbo.common.logger.support.FailsafeErrorTypeAwareLogger;
|
||||
import org.apache.dubbo.common.logger.support.FailsafeLogger;
|
||||
import org.apache.dubbo.common.utils.ConcurrentHashMapUtils;
|
||||
import org.apache.dubbo.common.utils.SystemPropertyConfigUtils;
|
||||
import org.apache.dubbo.rpc.model.FrameworkModel;
|
||||
|
||||
import java.io.File;
|
||||
|
|
@ -47,7 +49,8 @@ public class LoggerFactory {
|
|||
|
||||
// search common-used logging frameworks
|
||||
static {
|
||||
String logger = System.getProperty("dubbo.application.logger", "");
|
||||
String logger =
|
||||
SystemPropertyConfigUtils.getSystemProperty(CommonConstants.DubboProperty.DUBBO_APPLICATION_LOGGER, "");
|
||||
switch (logger) {
|
||||
case Slf4jLoggerAdapter.NAME:
|
||||
setLoggerAdapter(new Slf4jLoggerAdapter());
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue